Fossil SCM

Merged in trunk.

danield 2022-06-17 09:49 timeline-cmd-by-branch merge
Commit 20c1ba2ea932b8d91646f1946b2ae08d1e78107659ee2f7a558be2007e262c56
--- .fossil-settings/binary-glob
+++ .fossil-settings/binary-glob
@@ -8,5 +8,6 @@
88
*.wav
99
compat/zlib/contrib/blast/test.pk
1010
compat/zlib/contrib/dotzlib/DotZLib.chm
1111
compat/zlib/contrib/puff/zeros.raw
1212
compat/zlib/zlib.3.pdf
13
+extsrc/pikchr.wasm
1314
--- .fossil-settings/binary-glob
+++ .fossil-settings/binary-glob
@@ -8,5 +8,6 @@
8 *.wav
9 compat/zlib/contrib/blast/test.pk
10 compat/zlib/contrib/dotzlib/DotZLib.chm
11 compat/zlib/contrib/puff/zeros.raw
12 compat/zlib/zlib.3.pdf
 
13
--- .fossil-settings/binary-glob
+++ .fossil-settings/binary-glob
@@ -8,5 +8,6 @@
8 *.wav
9 compat/zlib/contrib/blast/test.pk
10 compat/zlib/contrib/dotzlib/DotZLib.chm
11 compat/zlib/contrib/puff/zeros.raw
12 compat/zlib/zlib.3.pdf
13 extsrc/pikchr.wasm
14
+11
--- Makefile.in
+++ Makefile.in
@@ -72,10 +72,21 @@
7272
USE_SEE = @USE_SEE@
7373
APPNAME = fossil
7474
#
7575
# APPNAME = fossil-fuzz
7676
# may be more appropriate for fuzzing.
77
+
78
+#### Emscripten stuff for optionally doing in-tree builds
79
+# of any WASM components. We store precompiled WASM in the the SCM, so
80
+# this is only useful for people who actively work on WASM
81
+# components. EMSDK_ENV refers to the "environment" script which comes
82
+# with the Emscripten SDK package:
83
+# https://emscripten.org/docs/getting_started/downloads.html
84
+EMSDK_HOME = @EMSDK_HOME@
85
+EMSDK_ENV = @EMSDK_ENV@
86
+EMCC_OPT = @EMCC_OPT@
87
+EMCC_WRAPPER = $(SRCDIR_tools)/emcc.sh
7788
7889
.PHONY: all tags
7990
8091
include $(SRCDIR)/main.mk
8192
8293
--- Makefile.in
+++ Makefile.in
@@ -72,10 +72,21 @@
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
--- Makefile.in
+++ Makefile.in
@@ -72,10 +72,21 @@
72 USE_SEE = @USE_SEE@
73 APPNAME = fossil
74 #
75 # APPNAME = fossil-fuzz
76 # may be more appropriate for fuzzing.
77
78 #### Emscripten stuff for optionally doing in-tree builds
79 # of any WASM components. We store precompiled WASM in the the SCM, so
80 # this is only useful for people who actively work on WASM
81 # components. EMSDK_ENV refers to the "environment" script which comes
82 # with the Emscripten SDK package:
83 # https://emscripten.org/docs/getting_started/downloads.html
84 EMSDK_HOME = @EMSDK_HOME@
85 EMSDK_ENV = @EMSDK_ENV@
86 EMCC_OPT = @EMCC_OPT@
87 EMCC_WRAPPER = $(SRCDIR_tools)/emcc.sh
88
89 .PHONY: all tags
90
91 include $(SRCDIR)/main.mk
92
93
+36
--- auto.def
+++ auto.def
@@ -28,10 +28,11 @@
2828
static=0 => {Link a static executable}
2929
fusefs=1 => {Disable the Fuse Filesystem}
3030
fossil-debug=0 => {Build with fossil debugging enabled}
3131
no-opt=0 => {Build without optimization}
3232
json=0 => {Build with fossil JSON API enabled}
33
+ with-emsdk:path => {Directory containing the Emscripten SDK}
3334
}
3435
3536
# Update the minimum required SQLite version number here, and also
3637
# in src/main.c near the sqlite3_libversion_number() call. Take care
3738
# that both places agree!
@@ -632,10 +633,37 @@
632633
set tclconfig(TCL_LD_FLAGS) [string map [list -ldl ""] \
633634
$tclconfig(TCL_LD_FLAGS)]
634635
define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
635636
define FOSSIL_ENABLE_TCL
636637
}
638
+
639
+# Emscripten is a purely optional component used only for doing
640
+# in-tree builds of WASM stuff, as opposed to WASM binaries we import
641
+# from other places. This is only set up for Unix-style OSes and is
642
+# untested anywhere but Linux.
643
+set emsdkHome [opt-val with-emsdk]
644
+define EMSDK_HOME ""
645
+define EMSDK_ENV ""
646
+define EMCC_OPT "-Oz"
647
+if {$emsdkHome eq "" && [info exists ::env(EMSDK)]} {
648
+ # Fall back to checking the environment. $EMSDK gets set
649
+ # by sourcing emsdk_env.sh.
650
+ set emsdkHome $::env(EMSDK)
651
+}
652
+if {$emsdkHome ne ""} {
653
+ define EMSDK_HOME $emsdkHome
654
+ set emsdkEnv "$emsdkHome/emsdk_env.sh"
655
+ if {[file exists $emsdkEnv]} {
656
+ puts "Using Emscripten SDK environment from $emsdkEnv."
657
+ define EMSDK_ENV $emsdkEnv
658
+ if {[info exists ::env(EMCC_OPT)]} {
659
+ define EMCC_OPT $::env(EMCC_OPT)
660
+ }
661
+ } else {
662
+ puts "emsdk_env.sh not found. Assuming emcc is in the PATH."
663
+ }
664
+}
637665
638666
# Network functions require libraries on some systems
639667
cc-check-function-in-lib gethostbyname nsl
640668
if {![cc-check-function-in-lib socket {socket network}]} {
641669
# Last resort, may be Windows
@@ -726,8 +754,16 @@
726754
# Linux can only infer the dependency on pthread from OpenSSL when
727755
# doing dynamic linkage.
728756
define-append LIBS -lpthread
729757
}
730758
759
+if {[get-define EMSDK_HOME] ne ""} {
760
+ define EMCC_WRAPPER $::autosetup(dir)/../tools/emcc.sh
761
+ make-template tools/emcc.sh.in
762
+ catch {exec chmod u+x tools/emcc.sh}
763
+} else {
764
+ define EMCC_WRAPPER ""
765
+ catch {exec rm -f tools/emcc.sh}
766
+}
731767
732768
make-template Makefile.in
733769
make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
734770
735771
ADDED extsrc/pikchr-worker.js
--- auto.def
+++ auto.def
@@ -28,10 +28,11 @@
28 static=0 => {Link a static executable}
29 fusefs=1 => {Disable the Fuse Filesystem}
30 fossil-debug=0 => {Build with fossil debugging enabled}
31 no-opt=0 => {Build without optimization}
32 json=0 => {Build with fossil JSON API enabled}
 
33 }
34
35 # Update the minimum required SQLite version number here, and also
36 # in src/main.c near the sqlite3_libversion_number() call. Take care
37 # that both places agree!
@@ -632,10 +633,37 @@
632 set tclconfig(TCL_LD_FLAGS) [string map [list -ldl ""] \
633 $tclconfig(TCL_LD_FLAGS)]
634 define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
635 define FOSSIL_ENABLE_TCL
636 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
638 # Network functions require libraries on some systems
639 cc-check-function-in-lib gethostbyname nsl
640 if {![cc-check-function-in-lib socket {socket network}]} {
641 # Last resort, may be Windows
@@ -726,8 +754,16 @@
726 # Linux can only infer the dependency on pthread from OpenSSL when
727 # doing dynamic linkage.
728 define-append LIBS -lpthread
729 }
730
 
 
 
 
 
 
 
 
731
732 make-template Makefile.in
733 make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
734
735 DDED extsrc/pikchr-worker.js
--- auto.def
+++ auto.def
@@ -28,10 +28,11 @@
28 static=0 => {Link a static executable}
29 fusefs=1 => {Disable the Fuse Filesystem}
30 fossil-debug=0 => {Build with fossil debugging enabled}
31 no-opt=0 => {Build without optimization}
32 json=0 => {Build with fossil JSON API enabled}
33 with-emsdk:path => {Directory containing the Emscripten SDK}
34 }
35
36 # Update the minimum required SQLite version number here, and also
37 # in src/main.c near the sqlite3_libversion_number() call. Take care
38 # that both places agree!
@@ -632,10 +633,37 @@
633 set tclconfig(TCL_LD_FLAGS) [string map [list -ldl ""] \
634 $tclconfig(TCL_LD_FLAGS)]
635 define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
636 define FOSSIL_ENABLE_TCL
637 }
638
639 # Emscripten is a purely optional component used only for doing
640 # in-tree builds of WASM stuff, as opposed to WASM binaries we import
641 # from other places. This is only set up for Unix-style OSes and is
642 # untested anywhere but Linux.
643 set emsdkHome [opt-val with-emsdk]
644 define EMSDK_HOME ""
645 define EMSDK_ENV ""
646 define EMCC_OPT "-Oz"
647 if {$emsdkHome eq "" && [info exists ::env(EMSDK)]} {
648 # Fall back to checking the environment. $EMSDK gets set
649 # by sourcing emsdk_env.sh.
650 set emsdkHome $::env(EMSDK)
651 }
652 if {$emsdkHome ne ""} {
653 define EMSDK_HOME $emsdkHome
654 set emsdkEnv "$emsdkHome/emsdk_env.sh"
655 if {[file exists $emsdkEnv]} {
656 puts "Using Emscripten SDK environment from $emsdkEnv."
657 define EMSDK_ENV $emsdkEnv
658 if {[info exists ::env(EMCC_OPT)]} {
659 define EMCC_OPT $::env(EMCC_OPT)
660 }
661 } else {
662 puts "emsdk_env.sh not found. Assuming emcc is in the PATH."
663 }
664 }
665
666 # Network functions require libraries on some systems
667 cc-check-function-in-lib gethostbyname nsl
668 if {![cc-check-function-in-lib socket {socket network}]} {
669 # Last resort, may be Windows
@@ -726,8 +754,16 @@
754 # Linux can only infer the dependency on pthread from OpenSSL when
755 # doing dynamic linkage.
756 define-append LIBS -lpthread
757 }
758
759 if {[get-define EMSDK_HOME] ne ""} {
760 define EMCC_WRAPPER $::autosetup(dir)/../tools/emcc.sh
761 make-template tools/emcc.sh.in
762 catch {exec chmod u+x tools/emcc.sh}
763 } else {
764 define EMCC_WRAPPER ""
765 catch {exec rm -f tools/emcc.sh}
766 }
767
768 make-template Makefile.in
769 make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
770
771 DDED extsrc/pikchr-worker.js
--- a/extsrc/pikchr-worker.js
+++ b/extsrc/pikchr-worker.js
@@ -0,0 +1,108 @@
1
+/*
2
+ 2022-05-20
3
+
4
+ The author disresult like with DOM elements,
5
+ we have to define a lower-level message API. Messages abstractly
6
+ look like:
7
+
8
+ { type: string, data: type-specific value }
9
+
10
+ Where 'type' is used for dispatching and 'data' is a
11
+ 'type'-dependent value.
12
+
13
+ The 'type' values expected by each side of the main/worker
14
+ connection vary. The types are described below but subject to
15
+ change at any time as this experiment evolves.
16
+
17
+ Main-to-Worker message types:
18
+
19
+ - pikchr: data=pikchr-format text to render or an object:
20
+
21
+ {
22
+ pikchr: source code for the pikchr,
23
+ darkMode: boolean true to adjust colors for a dark color scheme,
24
+ cssClass: CSS class name to add to the typeshe author disclaims copyright to this source code. In place of a
25
+ legal notice, here is a blessing:
26
+
27
+ * May you do good and not evil.
28
+ * May you find forgiveness for yourself and forgive others.
29
+ * May you share freely, never taking more than you give.
30
+
31
+ ***********************************************************************
32
+
33
+ This is a JS Worker file for use with the pikchr wasm build. It
34
+ loads the pikchr wasm module and offers access to it via the Worker
35
+ message-passing interface.
36
+
37
+ Because we can have only a single message handler, as opposed to an
38
+ arbitrary n/* messages come in the form
39
+
40
+ {type:'module', data:{
41
+ type:'status',
42
+ data: {text:string|null, step:1-based-integer}
43
+ }
44
+
45
+ with an incrementing step value for each subsequent message. When
46
+ the module loading is complete, a message with a text value of
47
+ n ull is posted.
48
+
49
+ - pikchr:
50
+
51
+ {type: 'pikchr',
52
+ data:{
53
+ pikchr: input text,
54
+ result: rendered result (SVG on success, HTML on error),
55
+ isError: bool, true if .pikchr holds an error report,
56
+ flags: integer: flags used to configure the pikchr rendering,
57
+ width: if !isError, width (integer pixels) of the SVG,
58
+ height: if !isError, height (integer pixels) of the SVG
59
+ }
60
+ }
61
+
62
+*/
63
+
64
+"use strict";
65
+(function(){
66
+ /**
67
+ Posts a message in the form {type,data} unless passed more than
68
+ 2 args, in which case it posts {type, data:[arg1...argN]}.
69
+ */
70
+ const wMsg = function(type,data){
71
+ postMessage({
72
+ type,
73
+ data: arguments.length<3
74
+ ? data
75
+ : Array.prototype.slice.call(arguments,1)
76
+ });
77
+ };
78
+
79
+ const stderr = function(){wMsg('stderr', Array.prototype.slice.call(arguments));};
80
+
81
+ self.onerror = function(/*message, source, lineno, colno, error*/) {
82
+ const err = arguments[4];
83
+ if(err && 'ExitStatus'==err.name){
84
+ /* This "cannot happen" for this wasm binding, but just in
85
+ case... */
86
+ pikchrModule.isDead = true;
87
+ stderr("FATAL ERROR:", err.message);
88
+ stderr("Restarting the app requires reloading the page.");
89
+ wMsg('error', err);
90
+ }
91
+ pikchrModule.setStatus('Exception thrown, see JavaScript console: '+err);
92
+ };
93
+
94
+ self.onmessage = function f(ev){
95
+ ev = ev.data;
96
+ switch(ev.type){
97
+ /**
98
+ Runs the given text through pikchr and emits a 'pikchr'
99
+ message result (output format documented above).
100
+
101
+ Fires a working/start event before it starts and
102
+ working/end event when it finishes.
103
+ */
104
+ case 'pikchr':
105
+ if(pikchrModule.isDead){
106
+ stderr( show-ready');
107
+ });
108
+})();
--- a/extsrc/pikchr-worker.js
+++ b/extsrc/pikchr-worker.js
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/extsrc/pikchr-worker.js
+++ b/extsrc/pikchr-worker.js
@@ -0,0 +1,108 @@
1 /*
2 2022-05-20
3
4 The author disresult like with DOM elements,
5 we have to define a lower-level message API. Messages abstractly
6 look like:
7
8 { type: string, data: type-specific value }
9
10 Where 'type' is used for dispatching and 'data' is a
11 'type'-dependent value.
12
13 The 'type' values expected by each side of the main/worker
14 connection vary. The types are described below but subject to
15 change at any time as this experiment evolves.
16
17 Main-to-Worker message types:
18
19 - pikchr: data=pikchr-format text to render or an object:
20
21 {
22 pikchr: source code for the pikchr,
23 darkMode: boolean true to adjust colors for a dark color scheme,
24 cssClass: CSS class name to add to the typeshe author disclaims copyright to this source code. In place of a
25 legal notice, here is a blessing:
26
27 * May you do good and not evil.
28 * May you find forgiveness for yourself and forgive others.
29 * May you share freely, never taking more than you give.
30
31 ***********************************************************************
32
33 This is a JS Worker file for use with the pikchr wasm build. It
34 loads the pikchr wasm module and offers access to it via the Worker
35 message-passing interface.
36
37 Because we can have only a single message handler, as opposed to an
38 arbitrary n/* messages come in the form
39
40 {type:'module', data:{
41 type:'status',
42 data: {text:string|null, step:1-based-integer}
43 }
44
45 with an incrementing step value for each subsequent message. When
46 the module loading is complete, a message with a text value of
47 n ull is posted.
48
49 - pikchr:
50
51 {type: 'pikchr',
52 data:{
53 pikchr: input text,
54 result: rendered result (SVG on success, HTML on error),
55 isError: bool, true if .pikchr holds an error report,
56 flags: integer: flags used to configure the pikchr rendering,
57 width: if !isError, width (integer pixels) of the SVG,
58 height: if !isError, height (integer pixels) of the SVG
59 }
60 }
61
62 */
63
64 "use strict";
65 (function(){
66 /**
67 Posts a message in the form {type,data} unless passed more than
68 2 args, in which case it posts {type, data:[arg1...argN]}.
69 */
70 const wMsg = function(type,data){
71 postMessage({
72 type,
73 data: arguments.length<3
74 ? data
75 : Array.prototype.slice.call(arguments,1)
76 });
77 };
78
79 const stderr = function(){wMsg('stderr', Array.prototype.slice.call(arguments));};
80
81 self.onerror = function(/*message, source, lineno, colno, error*/) {
82 const err = arguments[4];
83 if(err && 'ExitStatus'==err.name){
84 /* This "cannot happen" for this wasm binding, but just in
85 case... */
86 pikchrModule.isDead = true;
87 stderr("FATAL ERROR:", err.message);
88 stderr("Restarting the app requires reloading the page.");
89 wMsg('error', err);
90 }
91 pikchrModule.setStatus('Exception thrown, see JavaScript console: '+err);
92 };
93
94 self.onmessage = function f(ev){
95 ev = ev.data;
96 switch(ev.type){
97 /**
98 Runs the given text through pikchr and emits a 'pikchr'
99 message result (output format documented above).
100
101 Fires a working/start event before it starts and
102 working/end event when it finishes.
103 */
104 case 'pikchr':
105 if(pikchrModule.isDead){
106 stderr( show-ready');
107 });
108 })();
+37 -2
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -4532,10 +4532,43 @@
45324532
}
45334533
memcpy(p->zOut+p->nOut, zText, n);
45344534
p->nOut += n;
45354535
p->zOut[p->nOut] = 0;
45364536
}
4537
+
4538
+/*
4539
+** Given a string and its length, returns true if the string begins
4540
+** with a construct which syntactically matches an HTML entity escape
4541
+** sequence (without checking for whether it's a known entity). Always
4542
+** returns false if zText[0] is false or n<4. Entities match the
4543
+** equivalent of the regexes `&#[0-9]{2,};` and
4544
+** `&[a-zA-Z][a-zA-Z0-9]+;`.
4545
+*/
4546
+static int pik_isentity(char const * zText, int n){
4547
+ int i = 0;
4548
+ if( n<4 || '&'!=zText[0] ) return 0;
4549
+ n--;
4550
+ zText++;
4551
+ if( '#'==zText[0] ){
4552
+ zText++;
4553
+ n--;
4554
+ for(i=0; i<n; i++){
4555
+ if( i>1 && ';'==zText[i] ) return 1;
4556
+ else if( zText[i]<'0' || zText[i]>'9' ) return 0;
4557
+ /* Note that &#nn; values nn<32d are not legal entities. */
4558
+ }
4559
+ }else{
4560
+ for(i=0; i<n; i++){
4561
+ if( i>1 && ';'==zText[i] ) return 1;
4562
+ else if( i>0 && zText[i]>='0' && zText[i]<='9' ){
4563
+ continue;
4564
+ }else if( zText[i]<'A' || zText[i]>'z'
4565
+ || (zText[i]>'Z' && zText[i]<'a') ) return 0;
4566
+ }
4567
+ }
4568
+ return 0;
4569
+}
45374570
45384571
/*
45394572
** Append text to zOut with HTML characters escaped.
45404573
**
45414574
** * The space character is changed into non-breaking space (U+00a0)
@@ -4564,12 +4597,14 @@
45644597
if( i ) pik_append(p, zText, i);
45654598
if( i==n ) break;
45664599
switch( c ){
45674600
case '<': { pik_append(p, "&lt;", 4); break; }
45684601
case '>': { pik_append(p, "&gt;", 4); break; }
4569
- case '&': { pik_append(p, "&amp;", 5); break; }
45704602
case ' ': { pik_append(p, "\302\240;", 2); break; }
4603
+ case '&':
4604
+ if( pik_isentity(zText+i, n-i) ){ pik_append(p, "&", 1); }
4605
+ else { pik_append(p, "&amp;", 5); }
45714606
}
45724607
i++;
45734608
n -= i;
45744609
zText += i;
45754610
i = 0;
@@ -8096,6 +8131,6 @@
80968131
80978132
80988133
#endif /* PIKCHR_TCL */
80998134
81008135
8101
-#line 8126 "pikchr.c"
8136
+#line 8161 "pikchr.c"
81028137
81038138
ADDED extsrc/pikchr.js
81048139
ADDED extsrc/pikchr.wasm
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -4532,10 +4532,43 @@
4532 }
4533 memcpy(p->zOut+p->nOut, zText, n);
4534 p->nOut += n;
4535 p->zOut[p->nOut] = 0;
4536 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4537
4538 /*
4539 ** Append text to zOut with HTML characters escaped.
4540 **
4541 ** * The space character is changed into non-breaking space (U+00a0)
@@ -4564,12 +4597,14 @@
4564 if( i ) pik_append(p, zText, i);
4565 if( i==n ) break;
4566 switch( c ){
4567 case '<': { pik_append(p, "&lt;", 4); break; }
4568 case '>': { pik_append(p, "&gt;", 4); break; }
4569 case '&': { pik_append(p, "&amp;", 5); break; }
4570 case ' ': { pik_append(p, "\302\240;", 2); break; }
 
 
 
4571 }
4572 i++;
4573 n -= i;
4574 zText += i;
4575 i = 0;
@@ -8096,6 +8131,6 @@
8096
8097
8098 #endif /* PIKCHR_TCL */
8099
8100
8101 #line 8126 "pikchr.c"
8102
8103 DDED extsrc/pikchr.js
8104 DDED extsrc/pikchr.wasm
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -4532,10 +4532,43 @@
4532 }
4533 memcpy(p->zOut+p->nOut, zText, n);
4534 p->nOut += n;
4535 p->zOut[p->nOut] = 0;
4536 }
4537
4538 /*
4539 ** Given a string and its length, returns true if the string begins
4540 ** with a construct which syntactically matches an HTML entity escape
4541 ** sequence (without checking for whether it's a known entity). Always
4542 ** returns false if zText[0] is false or n<4. Entities match the
4543 ** equivalent of the regexes `&#[0-9]{2,};` and
4544 ** `&[a-zA-Z][a-zA-Z0-9]+;`.
4545 */
4546 static int pik_isentity(char const * zText, int n){
4547 int i = 0;
4548 if( n<4 || '&'!=zText[0] ) return 0;
4549 n--;
4550 zText++;
4551 if( '#'==zText[0] ){
4552 zText++;
4553 n--;
4554 for(i=0; i<n; i++){
4555 if( i>1 && ';'==zText[i] ) return 1;
4556 else if( zText[i]<'0' || zText[i]>'9' ) return 0;
4557 /* Note that &#nn; values nn<32d are not legal entities. */
4558 }
4559 }else{
4560 for(i=0; i<n; i++){
4561 if( i>1 && ';'==zText[i] ) return 1;
4562 else if( i>0 && zText[i]>='0' && zText[i]<='9' ){
4563 continue;
4564 }else if( zText[i]<'A' || zText[i]>'z'
4565 || (zText[i]>'Z' && zText[i]<'a') ) return 0;
4566 }
4567 }
4568 return 0;
4569 }
4570
4571 /*
4572 ** Append text to zOut with HTML characters escaped.
4573 **
4574 ** * The space character is changed into non-breaking space (U+00a0)
@@ -4564,12 +4597,14 @@
4597 if( i ) pik_append(p, zText, i);
4598 if( i==n ) break;
4599 switch( c ){
4600 case '<': { pik_append(p, "&lt;", 4); break; }
4601 case '>': { pik_append(p, "&gt;", 4); break; }
 
4602 case ' ': { pik_append(p, "\302\240;", 2); break; }
4603 case '&':
4604 if( pik_isentity(zText+i, n-i) ){ pik_append(p, "&", 1); }
4605 else { pik_append(p, "&amp;", 5); }
4606 }
4607 i++;
4608 n -= i;
4609 zText += i;
4610 i = 0;
@@ -8096,6 +8131,6 @@
8131
8132
8133 #endif /* PIKCHR_TCL */
8134
8135
8136 #line 8161 "pikchr.c"
8137
8138 DDED extsrc/pikchr.js
8139 DDED extsrc/pikchr.wasm
--- a/extsrc/pikchr.js
+++ b/extsrc/pikchr.js
@@ -0,0 +1,42 @@
1
+) {
2
+ r initPikchrModuDi
3
+var initPikchrMod || {};e["ready"] = new Promise(fhis by
4
+// setting the ENVIRONMENT// setting the ENVIRONMENT settingow) => {
5
+ throw toT(resolve, reject) =>e present at the end iffunction(resolve, reject) end if `scriptDirectory` is lice"";
6
+
7
+function locateFile(path) {
8
+ if (Module["locaeFile"]) {
9
+ retut they can
10
+// refer to Module (if they choose; th// Sometimes an exivartory` is lice"";
11
+
12
+fnse = awaitirectory + path;
13
+}
14
+
15
+
16
+
17
+/aitirectory + path;
18
+}
19
+
20
+
21
+
22
+// Ho);nt runtime environments.}
23
+var initPikchrModule = (() => {
24
+ vchrModule var initPikchrModule =, setWindowTitle;
25
+ed in the code, and you
26
+//d in the code, and yORKER) {
27
+iseResvar readomiseResolve = resolveft());
28
+ }
29
+ }
30
+ // = reject;
31
+});
32
+
33
+// Determine nvironment we are in}
34
+ if (_scriptDir) {
35
+iseResvar readyPromi_scriptDir;
36
+ }
37
+Throw) => {
38
+ throw tindexOf("blob:") !== 0) {
39
+iseResvar readyPromiscriptDirectory.substr(0, ) => {
40
+ thrvar runtimeKeepavar buffer,aliveCounter = 0 || runtimeKeepaliveCounter > 0binaryFilevar initPikchrModuDir = typGlobalBufferAn ENVIRONME.src : undefined;
41
+ nresponse =>b() =>var function(str)function(arr)function(type) {
42
+ r
--- a/extsrc/pikchr.js
+++ b/extsrc/pikchr.js
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/extsrc/pikchr.js
+++ b/extsrc/pikchr.js
@@ -0,0 +1,42 @@
1 ) {
2 r initPikchrModuDi
3 var initPikchrMod || {};e["ready"] = new Promise(fhis by
4 // setting the ENVIRONMENT// setting the ENVIRONMENT settingow) => {
5 throw toT(resolve, reject) =>e present at the end iffunction(resolve, reject) end if `scriptDirectory` is lice"";
6
7 function locateFile(path) {
8 if (Module["locaeFile"]) {
9 retut they can
10 // refer to Module (if they choose; th// Sometimes an exivartory` is lice"";
11
12 fnse = awaitirectory + path;
13 }
14
15
16
17 /aitirectory + path;
18 }
19
20
21
22 // Ho);nt runtime environments.}
23 var initPikchrModule = (() => {
24 vchrModule var initPikchrModule =, setWindowTitle;
25 ed in the code, and you
26 //d in the code, and yORKER) {
27 iseResvar readomiseResolve = resolveft());
28 }
29 }
30 // = reject;
31 });
32
33 // Determine nvironment we are in}
34 if (_scriptDir) {
35 iseResvar readyPromi_scriptDir;
36 }
37 Throw) => {
38 throw tindexOf("blob:") !== 0) {
39 iseResvar readyPromiscriptDirectory.substr(0, ) => {
40 thrvar runtimeKeepavar buffer,aliveCounter = 0 || runtimeKeepaliveCounter > 0binaryFilevar initPikchrModuDir = typGlobalBufferAn ENVIRONME.src : undefined;
41 nresponse =>b() =>var function(str)function(arr)function(type) {
42 r

Binary file

+2642 -2369
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -245,10 +245,20 @@
245245
#else
246246
# define setBinaryMode(X,Y)
247247
# define setTextMode(X,Y)
248248
#endif
249249
250
+/*
251
+** When compiling with emcc (a.k.a. emscripten), we're building a
252
+** WebAssembly (WASM) bundle and need to disable and rewire a few
253
+** things.
254
+*/
255
+#ifdef __EMSCRIPTEN__
256
+#define SQLITE_SHELL_WASM_MODE
257
+#else
258
+#undef SQLITE_SHELL_WASM_MODE
259
+#endif
250260
251261
/* True if the timer is enabled */
252262
static int enableTimer = 0;
253263
254264
/* Return the current wall-clock time */
@@ -707,10 +717,11 @@
707717
**
708718
** The result is stored in space obtained from malloc() and must either
709719
** be freed by the caller or else passed back into this routine via the
710720
** zPrior argument for reuse.
711721
*/
722
+#ifndef SQLITE_SHELL_WASM_MODE
712723
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
713724
char *zPrompt;
714725
char *zResult;
715726
if( in!=0 ){
716727
zResult = local_getline(zPrior, in);
@@ -726,11 +737,11 @@
726737
if( zResult && *zResult ) shell_add_history(zResult);
727738
#endif
728739
}
729740
return zResult;
730741
}
731
-
742
+#endif /* !SQLITE_SHELL_WASM_MODE */
732743
733744
/*
734745
** Return the value of a hexadecimal digit. Return -1 if the input
735746
** is not a hex digit.
736747
*/
@@ -814,11 +825,11 @@
814825
** zIn, if it was not NULL, is freed.
815826
**
816827
** If the third argument, quote, is not '\0', then it is used as a
817828
** quote character for zAppend.
818829
*/
819
-static void appendText(ShellText *p, char const *zAppend, char quote){
830
+static void appendText(ShellText *p, const char *zAppend, char quote){
820831
int len;
821832
int i;
822833
int nAppend = strlen30(zAppend);
823834
824835
len = nAppend+p->n+1;
@@ -1379,10 +1390,121 @@
13791390
#endif /* defined(WIN32) && defined(_MSC_VER) */
13801391
13811392
/************************* End test_windirent.c ********************/
13821393
#define dirent DIRENT
13831394
#endif
1395
+/************************* Begin ../ext/misc/memtrace.c ******************/
1396
+/*
1397
+** 2019-01-21
1398
+**
1399
+** The author disclaims copyright to this source code. In place of
1400
+** a legal notice, here is a blessing:
1401
+**
1402
+** May you do good and not evil.
1403
+** May you find forgiveness for yourself and forgive others.
1404
+** May you share freely, never taking more than you give.
1405
+**
1406
+*************************************************************************
1407
+**
1408
+** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
1409
+** mechanism to add a tracing layer on top of SQLite. If this extension
1410
+** is registered prior to sqlite3_initialize(), it will cause all memory
1411
+** allocation activities to be logged on standard output, or to some other
1412
+** FILE specified by the initializer.
1413
+**
1414
+** This file needs to be compiled into the application that uses it.
1415
+**
1416
+** This extension is used to implement the --memtrace option of the
1417
+** command-line shell.
1418
+*/
1419
+#include <assert.h>
1420
+#include <string.h>
1421
+#include <stdio.h>
1422
+
1423
+/* The original memory allocation routines */
1424
+static sqlite3_mem_methods memtraceBase;
1425
+static FILE *memtraceOut;
1426
+
1427
+/* Methods that trace memory allocations */
1428
+static void *memtraceMalloc(int n){
1429
+ if( memtraceOut ){
1430
+ fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
1431
+ memtraceBase.xRoundup(n));
1432
+ }
1433
+ return memtraceBase.xMalloc(n);
1434
+}
1435
+static void memtraceFree(void *p){
1436
+ if( p==0 ) return;
1437
+ if( memtraceOut ){
1438
+ fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
1439
+ }
1440
+ memtraceBase.xFree(p);
1441
+}
1442
+static void *memtraceRealloc(void *p, int n){
1443
+ if( p==0 ) return memtraceMalloc(n);
1444
+ if( n==0 ){
1445
+ memtraceFree(p);
1446
+ return 0;
1447
+ }
1448
+ if( memtraceOut ){
1449
+ fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
1450
+ memtraceBase.xSize(p), memtraceBase.xRoundup(n));
1451
+ }
1452
+ return memtraceBase.xRealloc(p, n);
1453
+}
1454
+static int memtraceSize(void *p){
1455
+ return memtraceBase.xSize(p);
1456
+}
1457
+static int memtraceRoundup(int n){
1458
+ return memtraceBase.xRoundup(n);
1459
+}
1460
+static int memtraceInit(void *p){
1461
+ return memtraceBase.xInit(p);
1462
+}
1463
+static void memtraceShutdown(void *p){
1464
+ memtraceBase.xShutdown(p);
1465
+}
1466
+
1467
+/* The substitute memory allocator */
1468
+static sqlite3_mem_methods ersaztMethods = {
1469
+ memtraceMalloc,
1470
+ memtraceFree,
1471
+ memtraceRealloc,
1472
+ memtraceSize,
1473
+ memtraceRoundup,
1474
+ memtraceInit,
1475
+ memtraceShutdown,
1476
+ 0
1477
+};
1478
+
1479
+/* Begin tracing memory allocations to out. */
1480
+int sqlite3MemTraceActivate(FILE *out){
1481
+ int rc = SQLITE_OK;
1482
+ if( memtraceBase.xMalloc==0 ){
1483
+ rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
1484
+ if( rc==SQLITE_OK ){
1485
+ rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
1486
+ }
1487
+ }
1488
+ memtraceOut = out;
1489
+ return rc;
1490
+}
1491
+
1492
+/* Deactivate memory tracing */
1493
+int sqlite3MemTraceDeactivate(void){
1494
+ int rc = SQLITE_OK;
1495
+ if( memtraceBase.xMalloc!=0 ){
1496
+ rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
1497
+ if( rc==SQLITE_OK ){
1498
+ memset(&memtraceBase, 0, sizeof(memtraceBase));
1499
+ }
1500
+ }
1501
+ memtraceOut = 0;
1502
+ return rc;
1503
+}
1504
+
1505
+/************************* End ../ext/misc/memtrace.c ********************/
13841506
/************************* Begin ../ext/misc/shathree.c ******************/
13851507
/*
13861508
** 2017-03-08
13871509
**
13881510
** The author disclaims copyright to this source code. In place of
@@ -2106,2333 +2228,10 @@
21062228
}
21072229
return rc;
21082230
}
21092231
21102232
/************************* End ../ext/misc/shathree.c ********************/
2111
-/************************* Begin ../ext/misc/fileio.c ******************/
2112
-/*
2113
-** 2014-06-13
2114
-**
2115
-** The author disclaims copyright to this source code. In place of
2116
-** a legal notice, here is a blessing:
2117
-**
2118
-** May you do good and not evil.
2119
-** May you find forgiveness for yourself and forgive others.
2120
-** May you share freely, never taking more than you give.
2121
-**
2122
-******************************************************************************
2123
-**
2124
-** This SQLite extension implements SQL functions readfile() and
2125
-** writefile(), and eponymous virtual type "fsdir".
2126
-**
2127
-** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
2128
-**
2129
-** If neither of the optional arguments is present, then this UDF
2130
-** function writes blob DATA to file FILE. If successful, the number
2131
-** of bytes written is returned. If an error occurs, NULL is returned.
2132
-**
2133
-** If the first option argument - MODE - is present, then it must
2134
-** be passed an integer value that corresponds to a POSIX mode
2135
-** value (file type + permissions, as returned in the stat.st_mode
2136
-** field by the stat() system call). Three types of files may
2137
-** be written/created:
2138
-**
2139
-** regular files: (mode & 0170000)==0100000
2140
-** symbolic links: (mode & 0170000)==0120000
2141
-** directories: (mode & 0170000)==0040000
2142
-**
2143
-** For a directory, the DATA is ignored. For a symbolic link, it is
2144
-** interpreted as text and used as the target of the link. For a
2145
-** regular file, it is interpreted as a blob and written into the
2146
-** named file. Regardless of the type of file, its permissions are
2147
-** set to (mode & 0777) before returning.
2148
-**
2149
-** If the optional MTIME argument is present, then it is interpreted
2150
-** as an integer - the number of seconds since the unix epoch. The
2151
-** modification-time of the target file is set to this value before
2152
-** returning.
2153
-**
2154
-** If three or more arguments are passed to this function and an
2155
-** error is encountered, an exception is raised.
2156
-**
2157
-** READFILE(FILE):
2158
-**
2159
-** Read and return the contents of file FILE (type blob) from disk.
2160
-**
2161
-** FSDIR:
2162
-**
2163
-** Used as follows:
2164
-**
2165
-** SELECT * FROM fsdir($path [, $dir]);
2166
-**
2167
-** Parameter $path is an absolute or relative pathname. If the file that it
2168
-** refers to does not exist, it is an error. If the path refers to a regular
2169
-** file or symbolic link, it returns a single row. Or, if the path refers
2170
-** to a directory, it returns one row for the directory, and one row for each
2171
-** file within the hierarchy rooted at $path.
2172
-**
2173
-** Each row has the following columns:
2174
-**
2175
-** name: Path to file or directory (text value).
2176
-** mode: Value of stat.st_mode for directory entry (an integer).
2177
-** mtime: Value of stat.st_mtime for directory entry (an integer).
2178
-** data: For a regular file, a blob containing the file data. For a
2179
-** symlink, a text value containing the text of the link. For a
2180
-** directory, NULL.
2181
-**
2182
-** If a non-NULL value is specified for the optional $dir parameter and
2183
-** $path is a relative path, then $path is interpreted relative to $dir.
2184
-** And the paths returned in the "name" column of the table are also
2185
-** relative to directory $dir.
2186
-**
2187
-** Notes on building this extension for Windows:
2188
-** Unless linked statically with the SQLite library, a preprocessor
2189
-** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
2190
-** DLL form of this extension for WIN32. See its use below for details.
2191
-*/
2192
-/* #include "sqlite3ext.h" */
2193
-SQLITE_EXTENSION_INIT1
2194
-#include <stdio.h>
2195
-#include <string.h>
2196
-#include <assert.h>
2197
-
2198
-#include <sys/types.h>
2199
-#include <sys/stat.h>
2200
-#include <fcntl.h>
2201
-#if !defined(_WIN32) && !defined(WIN32)
2202
-# include <unistd.h>
2203
-# include <dirent.h>
2204
-# include <utime.h>
2205
-# include <sys/time.h>
2206
-#else
2207
-# include "windows.h"
2208
-# include <io.h>
2209
-# include <direct.h>
2210
-/* # include "test_windirent.h" */
2211
-# define dirent DIRENT
2212
-# ifndef chmod
2213
-# define chmod _chmod
2214
-# endif
2215
-# ifndef stat
2216
-# define stat _stat
2217
-# endif
2218
-# define mkdir(path,mode) _mkdir(path)
2219
-# define lstat(path,buf) stat(path,buf)
2220
-#endif
2221
-#include <time.h>
2222
-#include <errno.h>
2223
-
2224
-
2225
-/*
2226
-** Structure of the fsdir() table-valued function
2227
-*/
2228
- /* 0 1 2 3 4 5 */
2229
-#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
2230
-#define FSDIR_COLUMN_NAME 0 /* Name of the file */
2231
-#define FSDIR_COLUMN_MODE 1 /* Access mode */
2232
-#define FSDIR_COLUMN_MTIME 2 /* Last modification time */
2233
-#define FSDIR_COLUMN_DATA 3 /* File content */
2234
-#define FSDIR_COLUMN_PATH 4 /* Path to top of search */
2235
-#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
2236
-
2237
-
2238
-/*
2239
-** Set the result stored by context ctx to a blob containing the
2240
-** contents of file zName. Or, leave the result unchanged (NULL)
2241
-** if the file does not exist or is unreadable.
2242
-**
2243
-** If the file exceeds the SQLite blob size limit, through an
2244
-** SQLITE_TOOBIG error.
2245
-**
2246
-** Throw an SQLITE_IOERR if there are difficulties pulling the file
2247
-** off of disk.
2248
-*/
2249
-static void readFileContents(sqlite3_context *ctx, const char *zName){
2250
- FILE *in;
2251
- sqlite3_int64 nIn;
2252
- void *pBuf;
2253
- sqlite3 *db;
2254
- int mxBlob;
2255
-
2256
- in = fopen(zName, "rb");
2257
- if( in==0 ){
2258
- /* File does not exist or is unreadable. Leave the result set to NULL. */
2259
- return;
2260
- }
2261
- fseek(in, 0, SEEK_END);
2262
- nIn = ftell(in);
2263
- rewind(in);
2264
- db = sqlite3_context_db_handle(ctx);
2265
- mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
2266
- if( nIn>mxBlob ){
2267
- sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
2268
- fclose(in);
2269
- return;
2270
- }
2271
- pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
2272
- if( pBuf==0 ){
2273
- sqlite3_result_error_nomem(ctx);
2274
- fclose(in);
2275
- return;
2276
- }
2277
- if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
2278
- sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
2279
- }else{
2280
- sqlite3_result_error_code(ctx, SQLITE_IOERR);
2281
- sqlite3_free(pBuf);
2282
- }
2283
- fclose(in);
2284
-}
2285
-
2286
-/*
2287
-** Implementation of the "readfile(X)" SQL function. The entire content
2288
-** of the file named X is read and returned as a BLOB. NULL is returned
2289
-** if the file does not exist or is unreadable.
2290
-*/
2291
-static void readfileFunc(
2292
- sqlite3_context *context,
2293
- int argc,
2294
- sqlite3_value **argv
2295
-){
2296
- const char *zName;
2297
- (void)(argc); /* Unused parameter */
2298
- zName = (const char*)sqlite3_value_text(argv[0]);
2299
- if( zName==0 ) return;
2300
- readFileContents(context, zName);
2301
-}
2302
-
2303
-/*
2304
-** Set the error message contained in context ctx to the results of
2305
-** vprintf(zFmt, ...).
2306
-*/
2307
-static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
2308
- char *zMsg = 0;
2309
- va_list ap;
2310
- va_start(ap, zFmt);
2311
- zMsg = sqlite3_vmprintf(zFmt, ap);
2312
- sqlite3_result_error(ctx, zMsg, -1);
2313
- sqlite3_free(zMsg);
2314
- va_end(ap);
2315
-}
2316
-
2317
-#if defined(_WIN32)
2318
-/*
2319
-** This function is designed to convert a Win32 FILETIME structure into the
2320
-** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
2321
-*/
2322
-static sqlite3_uint64 fileTimeToUnixTime(
2323
- LPFILETIME pFileTime
2324
-){
2325
- SYSTEMTIME epochSystemTime;
2326
- ULARGE_INTEGER epochIntervals;
2327
- FILETIME epochFileTime;
2328
- ULARGE_INTEGER fileIntervals;
2329
-
2330
- memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
2331
- epochSystemTime.wYear = 1970;
2332
- epochSystemTime.wMonth = 1;
2333
- epochSystemTime.wDay = 1;
2334
- SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
2335
- epochIntervals.LowPart = epochFileTime.dwLowDateTime;
2336
- epochIntervals.HighPart = epochFileTime.dwHighDateTime;
2337
-
2338
- fileIntervals.LowPart = pFileTime->dwLowDateTime;
2339
- fileIntervals.HighPart = pFileTime->dwHighDateTime;
2340
-
2341
- return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
2342
-}
2343
-
2344
-
2345
-#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
2346
-# /* To allow a standalone DLL, use this next replacement function: */
2347
-# undef sqlite3_win32_utf8_to_unicode
2348
-# define sqlite3_win32_utf8_to_unicode utf8_to_utf16
2349
-#
2350
-LPWSTR utf8_to_utf16(const char *z){
2351
- int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
2352
- LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
2353
- if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
2354
- return rv;
2355
- sqlite3_free(rv);
2356
- return 0;
2357
-}
2358
-#endif
2359
-
2360
-/*
2361
-** This function attempts to normalize the time values found in the stat()
2362
-** buffer to UTC. This is necessary on Win32, where the runtime library
2363
-** appears to return these values as local times.
2364
-*/
2365
-static void statTimesToUtc(
2366
- const char *zPath,
2367
- struct stat *pStatBuf
2368
-){
2369
- HANDLE hFindFile;
2370
- WIN32_FIND_DATAW fd;
2371
- LPWSTR zUnicodeName;
2372
- extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
2373
- zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
2374
- if( zUnicodeName ){
2375
- memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
2376
- hFindFile = FindFirstFileW(zUnicodeName, &fd);
2377
- if( hFindFile!=NULL ){
2378
- pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
2379
- pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
2380
- pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
2381
- FindClose(hFindFile);
2382
- }
2383
- sqlite3_free(zUnicodeName);
2384
- }
2385
-}
2386
-#endif
2387
-
2388
-/*
2389
-** This function is used in place of stat(). On Windows, special handling
2390
-** is required in order for the included time to be returned as UTC. On all
2391
-** other systems, this function simply calls stat().
2392
-*/
2393
-static int fileStat(
2394
- const char *zPath,
2395
- struct stat *pStatBuf
2396
-){
2397
-#if defined(_WIN32)
2398
- int rc = stat(zPath, pStatBuf);
2399
- if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
2400
- return rc;
2401
-#else
2402
- return stat(zPath, pStatBuf);
2403
-#endif
2404
-}
2405
-
2406
-/*
2407
-** This function is used in place of lstat(). On Windows, special handling
2408
-** is required in order for the included time to be returned as UTC. On all
2409
-** other systems, this function simply calls lstat().
2410
-*/
2411
-static int fileLinkStat(
2412
- const char *zPath,
2413
- struct stat *pStatBuf
2414
-){
2415
-#if defined(_WIN32)
2416
- int rc = lstat(zPath, pStatBuf);
2417
- if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
2418
- return rc;
2419
-#else
2420
- return lstat(zPath, pStatBuf);
2421
-#endif
2422
-}
2423
-
2424
-/*
2425
-** Argument zFile is the name of a file that will be created and/or written
2426
-** by SQL function writefile(). This function ensures that the directory
2427
-** zFile will be written to exists, creating it if required. The permissions
2428
-** for any path components created by this function are set in accordance
2429
-** with the current umask.
2430
-**
2431
-** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
2432
-** SQLITE_OK is returned if the directory is successfully created, or
2433
-** SQLITE_ERROR otherwise.
2434
-*/
2435
-static int makeDirectory(
2436
- const char *zFile
2437
-){
2438
- char *zCopy = sqlite3_mprintf("%s", zFile);
2439
- int rc = SQLITE_OK;
2440
-
2441
- if( zCopy==0 ){
2442
- rc = SQLITE_NOMEM;
2443
- }else{
2444
- int nCopy = (int)strlen(zCopy);
2445
- int i = 1;
2446
-
2447
- while( rc==SQLITE_OK ){
2448
- struct stat sStat;
2449
- int rc2;
2450
-
2451
- for(; zCopy[i]!='/' && i<nCopy; i++);
2452
- if( i==nCopy ) break;
2453
- zCopy[i] = '\0';
2454
-
2455
- rc2 = fileStat(zCopy, &sStat);
2456
- if( rc2!=0 ){
2457
- if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
2458
- }else{
2459
- if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
2460
- }
2461
- zCopy[i] = '/';
2462
- i++;
2463
- }
2464
-
2465
- sqlite3_free(zCopy);
2466
- }
2467
-
2468
- return rc;
2469
-}
2470
-
2471
-/*
2472
-** This function does the work for the writefile() UDF. Refer to
2473
-** header comments at the top of this file for details.
2474
-*/
2475
-static int writeFile(
2476
- sqlite3_context *pCtx, /* Context to return bytes written in */
2477
- const char *zFile, /* File to write */
2478
- sqlite3_value *pData, /* Data to write */
2479
- mode_t mode, /* MODE parameter passed to writefile() */
2480
- sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */
2481
-){
2482
- if( zFile==0 ) return 1;
2483
-#if !defined(_WIN32) && !defined(WIN32)
2484
- if( S_ISLNK(mode) ){
2485
- const char *zTo = (const char*)sqlite3_value_text(pData);
2486
- if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
2487
- }else
2488
-#endif
2489
- {
2490
- if( S_ISDIR(mode) ){
2491
- if( mkdir(zFile, mode) ){
2492
- /* The mkdir() call to create the directory failed. This might not
2493
- ** be an error though - if there is already a directory at the same
2494
- ** path and either the permissions already match or can be changed
2495
- ** to do so using chmod(), it is not an error. */
2496
- struct stat sStat;
2497
- if( errno!=EEXIST
2498
- || 0!=fileStat(zFile, &sStat)
2499
- || !S_ISDIR(sStat.st_mode)
2500
- || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
2501
- ){
2502
- return 1;
2503
- }
2504
- }
2505
- }else{
2506
- sqlite3_int64 nWrite = 0;
2507
- const char *z;
2508
- int rc = 0;
2509
- FILE *out = fopen(zFile, "wb");
2510
- if( out==0 ) return 1;
2511
- z = (const char*)sqlite3_value_blob(pData);
2512
- if( z ){
2513
- sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
2514
- nWrite = sqlite3_value_bytes(pData);
2515
- if( nWrite!=n ){
2516
- rc = 1;
2517
- }
2518
- }
2519
- fclose(out);
2520
- if( rc==0 && mode && chmod(zFile, mode & 0777) ){
2521
- rc = 1;
2522
- }
2523
- if( rc ) return 2;
2524
- sqlite3_result_int64(pCtx, nWrite);
2525
- }
2526
- }
2527
-
2528
- if( mtime>=0 ){
2529
-#if defined(_WIN32)
2530
-#if !SQLITE_OS_WINRT
2531
- /* Windows */
2532
- FILETIME lastAccess;
2533
- FILETIME lastWrite;
2534
- SYSTEMTIME currentTime;
2535
- LONGLONG intervals;
2536
- HANDLE hFile;
2537
- LPWSTR zUnicodeName;
2538
- extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
2539
-
2540
- GetSystemTime(&currentTime);
2541
- SystemTimeToFileTime(&currentTime, &lastAccess);
2542
- intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
2543
- lastWrite.dwLowDateTime = (DWORD)intervals;
2544
- lastWrite.dwHighDateTime = intervals >> 32;
2545
- zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
2546
- if( zUnicodeName==0 ){
2547
- return 1;
2548
- }
2549
- hFile = CreateFileW(
2550
- zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
2551
- FILE_FLAG_BACKUP_SEMANTICS, NULL
2552
- );
2553
- sqlite3_free(zUnicodeName);
2554
- if( hFile!=INVALID_HANDLE_VALUE ){
2555
- BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
2556
- CloseHandle(hFile);
2557
- return !bResult;
2558
- }else{
2559
- return 1;
2560
- }
2561
-#endif
2562
-#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
2563
- /* Recent unix */
2564
- struct timespec times[2];
2565
- times[0].tv_nsec = times[1].tv_nsec = 0;
2566
- times[0].tv_sec = time(0);
2567
- times[1].tv_sec = mtime;
2568
- if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
2569
- return 1;
2570
- }
2571
-#else
2572
- /* Legacy unix */
2573
- struct timeval times[2];
2574
- times[0].tv_usec = times[1].tv_usec = 0;
2575
- times[0].tv_sec = time(0);
2576
- times[1].tv_sec = mtime;
2577
- if( utimes(zFile, times) ){
2578
- return 1;
2579
- }
2580
-#endif
2581
- }
2582
-
2583
- return 0;
2584
-}
2585
-
2586
-/*
2587
-** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
2588
-** Refer to header comments at the top of this file for details.
2589
-*/
2590
-static void writefileFunc(
2591
- sqlite3_context *context,
2592
- int argc,
2593
- sqlite3_value **argv
2594
-){
2595
- const char *zFile;
2596
- mode_t mode = 0;
2597
- int res;
2598
- sqlite3_int64 mtime = -1;
2599
-
2600
- if( argc<2 || argc>4 ){
2601
- sqlite3_result_error(context,
2602
- "wrong number of arguments to function writefile()", -1
2603
- );
2604
- return;
2605
- }
2606
-
2607
- zFile = (const char*)sqlite3_value_text(argv[0]);
2608
- if( zFile==0 ) return;
2609
- if( argc>=3 ){
2610
- mode = (mode_t)sqlite3_value_int(argv[2]);
2611
- }
2612
- if( argc==4 ){
2613
- mtime = sqlite3_value_int64(argv[3]);
2614
- }
2615
-
2616
- res = writeFile(context, zFile, argv[1], mode, mtime);
2617
- if( res==1 && errno==ENOENT ){
2618
- if( makeDirectory(zFile)==SQLITE_OK ){
2619
- res = writeFile(context, zFile, argv[1], mode, mtime);
2620
- }
2621
- }
2622
-
2623
- if( argc>2 && res!=0 ){
2624
- if( S_ISLNK(mode) ){
2625
- ctxErrorMsg(context, "failed to create symlink: %s", zFile);
2626
- }else if( S_ISDIR(mode) ){
2627
- ctxErrorMsg(context, "failed to create directory: %s", zFile);
2628
- }else{
2629
- ctxErrorMsg(context, "failed to write file: %s", zFile);
2630
- }
2631
- }
2632
-}
2633
-
2634
-/*
2635
-** SQL function: lsmode(MODE)
2636
-**
2637
-** Given a numberic st_mode from stat(), convert it into a human-readable
2638
-** text string in the style of "ls -l".
2639
-*/
2640
-static void lsModeFunc(
2641
- sqlite3_context *context,
2642
- int argc,
2643
- sqlite3_value **argv
2644
-){
2645
- int i;
2646
- int iMode = sqlite3_value_int(argv[0]);
2647
- char z[16];
2648
- (void)argc;
2649
- if( S_ISLNK(iMode) ){
2650
- z[0] = 'l';
2651
- }else if( S_ISREG(iMode) ){
2652
- z[0] = '-';
2653
- }else if( S_ISDIR(iMode) ){
2654
- z[0] = 'd';
2655
- }else{
2656
- z[0] = '?';
2657
- }
2658
- for(i=0; i<3; i++){
2659
- int m = (iMode >> ((2-i)*3));
2660
- char *a = &z[1 + i*3];
2661
- a[0] = (m & 0x4) ? 'r' : '-';
2662
- a[1] = (m & 0x2) ? 'w' : '-';
2663
- a[2] = (m & 0x1) ? 'x' : '-';
2664
- }
2665
- z[10] = '\0';
2666
- sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
2667
-}
2668
-
2669
-#ifndef SQLITE_OMIT_VIRTUALTABLE
2670
-
2671
-/*
2672
-** Cursor type for recursively iterating through a directory structure.
2673
-*/
2674
-typedef struct fsdir_cursor fsdir_cursor;
2675
-typedef struct FsdirLevel FsdirLevel;
2676
-
2677
-struct FsdirLevel {
2678
- DIR *pDir; /* From opendir() */
2679
- char *zDir; /* Name of directory (nul-terminated) */
2680
-};
2681
-
2682
-struct fsdir_cursor {
2683
- sqlite3_vtab_cursor base; /* Base class - must be first */
2684
-
2685
- int nLvl; /* Number of entries in aLvl[] array */
2686
- int iLvl; /* Index of current entry */
2687
- FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
2688
-
2689
- const char *zBase;
2690
- int nBase;
2691
-
2692
- struct stat sStat; /* Current lstat() results */
2693
- char *zPath; /* Path to current entry */
2694
- sqlite3_int64 iRowid; /* Current rowid */
2695
-};
2696
-
2697
-typedef struct fsdir_tab fsdir_tab;
2698
-struct fsdir_tab {
2699
- sqlite3_vtab base; /* Base class - must be first */
2700
-};
2701
-
2702
-/*
2703
-** Construct a new fsdir virtual table object.
2704
-*/
2705
-static int fsdirConnect(
2706
- sqlite3 *db,
2707
- void *pAux,
2708
- int argc, const char *const*argv,
2709
- sqlite3_vtab **ppVtab,
2710
- char **pzErr
2711
-){
2712
- fsdir_tab *pNew = 0;
2713
- int rc;
2714
- (void)pAux;
2715
- (void)argc;
2716
- (void)argv;
2717
- (void)pzErr;
2718
- rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
2719
- if( rc==SQLITE_OK ){
2720
- pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
2721
- if( pNew==0 ) return SQLITE_NOMEM;
2722
- memset(pNew, 0, sizeof(*pNew));
2723
- sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
2724
- }
2725
- *ppVtab = (sqlite3_vtab*)pNew;
2726
- return rc;
2727
-}
2728
-
2729
-/*
2730
-** This method is the destructor for fsdir vtab objects.
2731
-*/
2732
-static int fsdirDisconnect(sqlite3_vtab *pVtab){
2733
- sqlite3_free(pVtab);
2734
- return SQLITE_OK;
2735
-}
2736
-
2737
-/*
2738
-** Constructor for a new fsdir_cursor object.
2739
-*/
2740
-static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
2741
- fsdir_cursor *pCur;
2742
- (void)p;
2743
- pCur = sqlite3_malloc( sizeof(*pCur) );
2744
- if( pCur==0 ) return SQLITE_NOMEM;
2745
- memset(pCur, 0, sizeof(*pCur));
2746
- pCur->iLvl = -1;
2747
- *ppCursor = &pCur->base;
2748
- return SQLITE_OK;
2749
-}
2750
-
2751
-/*
2752
-** Reset a cursor back to the state it was in when first returned
2753
-** by fsdirOpen().
2754
-*/
2755
-static void fsdirResetCursor(fsdir_cursor *pCur){
2756
- int i;
2757
- for(i=0; i<=pCur->iLvl; i++){
2758
- FsdirLevel *pLvl = &pCur->aLvl[i];
2759
- if( pLvl->pDir ) closedir(pLvl->pDir);
2760
- sqlite3_free(pLvl->zDir);
2761
- }
2762
- sqlite3_free(pCur->zPath);
2763
- sqlite3_free(pCur->aLvl);
2764
- pCur->aLvl = 0;
2765
- pCur->zPath = 0;
2766
- pCur->zBase = 0;
2767
- pCur->nBase = 0;
2768
- pCur->nLvl = 0;
2769
- pCur->iLvl = -1;
2770
- pCur->iRowid = 1;
2771
-}
2772
-
2773
-/*
2774
-** Destructor for an fsdir_cursor.
2775
-*/
2776
-static int fsdirClose(sqlite3_vtab_cursor *cur){
2777
- fsdir_cursor *pCur = (fsdir_cursor*)cur;
2778
-
2779
- fsdirResetCursor(pCur);
2780
- sqlite3_free(pCur);
2781
- return SQLITE_OK;
2782
-}
2783
-
2784
-/*
2785
-** Set the error message for the virtual table associated with cursor
2786
-** pCur to the results of vprintf(zFmt, ...).
2787
-*/
2788
-static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
2789
- va_list ap;
2790
- va_start(ap, zFmt);
2791
- pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
2792
- va_end(ap);
2793
-}
2794
-
2795
-
2796
-/*
2797
-** Advance an fsdir_cursor to its next row of output.
2798
-*/
2799
-static int fsdirNext(sqlite3_vtab_cursor *cur){
2800
- fsdir_cursor *pCur = (fsdir_cursor*)cur;
2801
- mode_t m = pCur->sStat.st_mode;
2802
-
2803
- pCur->iRowid++;
2804
- if( S_ISDIR(m) ){
2805
- /* Descend into this directory */
2806
- int iNew = pCur->iLvl + 1;
2807
- FsdirLevel *pLvl;
2808
- if( iNew>=pCur->nLvl ){
2809
- int nNew = iNew+1;
2810
- sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
2811
- FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
2812
- if( aNew==0 ) return SQLITE_NOMEM;
2813
- memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
2814
- pCur->aLvl = aNew;
2815
- pCur->nLvl = nNew;
2816
- }
2817
- pCur->iLvl = iNew;
2818
- pLvl = &pCur->aLvl[iNew];
2819
-
2820
- pLvl->zDir = pCur->zPath;
2821
- pCur->zPath = 0;
2822
- pLvl->pDir = opendir(pLvl->zDir);
2823
- if( pLvl->pDir==0 ){
2824
- fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
2825
- return SQLITE_ERROR;
2826
- }
2827
- }
2828
-
2829
- while( pCur->iLvl>=0 ){
2830
- FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
2831
- struct dirent *pEntry = readdir(pLvl->pDir);
2832
- if( pEntry ){
2833
- if( pEntry->d_name[0]=='.' ){
2834
- if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
2835
- if( pEntry->d_name[1]=='\0' ) continue;
2836
- }
2837
- sqlite3_free(pCur->zPath);
2838
- pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
2839
- if( pCur->zPath==0 ) return SQLITE_NOMEM;
2840
- if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
2841
- fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
2842
- return SQLITE_ERROR;
2843
- }
2844
- return SQLITE_OK;
2845
- }
2846
- closedir(pLvl->pDir);
2847
- sqlite3_free(pLvl->zDir);
2848
- pLvl->pDir = 0;
2849
- pLvl->zDir = 0;
2850
- pCur->iLvl--;
2851
- }
2852
-
2853
- /* EOF */
2854
- sqlite3_free(pCur->zPath);
2855
- pCur->zPath = 0;
2856
- return SQLITE_OK;
2857
-}
2858
-
2859
-/*
2860
-** Return values of columns for the row at which the series_cursor
2861
-** is currently pointing.
2862
-*/
2863
-static int fsdirColumn(
2864
- sqlite3_vtab_cursor *cur, /* The cursor */
2865
- sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
2866
- int i /* Which column to return */
2867
-){
2868
- fsdir_cursor *pCur = (fsdir_cursor*)cur;
2869
- switch( i ){
2870
- case FSDIR_COLUMN_NAME: {
2871
- sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
2872
- break;
2873
- }
2874
-
2875
- case FSDIR_COLUMN_MODE:
2876
- sqlite3_result_int64(ctx, pCur->sStat.st_mode);
2877
- break;
2878
-
2879
- case FSDIR_COLUMN_MTIME:
2880
- sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
2881
- break;
2882
-
2883
- case FSDIR_COLUMN_DATA: {
2884
- mode_t m = pCur->sStat.st_mode;
2885
- if( S_ISDIR(m) ){
2886
- sqlite3_result_null(ctx);
2887
-#if !defined(_WIN32) && !defined(WIN32)
2888
- }else if( S_ISLNK(m) ){
2889
- char aStatic[64];
2890
- char *aBuf = aStatic;
2891
- sqlite3_int64 nBuf = 64;
2892
- int n;
2893
-
2894
- while( 1 ){
2895
- n = readlink(pCur->zPath, aBuf, nBuf);
2896
- if( n<nBuf ) break;
2897
- if( aBuf!=aStatic ) sqlite3_free(aBuf);
2898
- nBuf = nBuf*2;
2899
- aBuf = sqlite3_malloc64(nBuf);
2900
- if( aBuf==0 ){
2901
- sqlite3_result_error_nomem(ctx);
2902
- return SQLITE_NOMEM;
2903
- }
2904
- }
2905
-
2906
- sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
2907
- if( aBuf!=aStatic ) sqlite3_free(aBuf);
2908
-#endif
2909
- }else{
2910
- readFileContents(ctx, pCur->zPath);
2911
- }
2912
- }
2913
- case FSDIR_COLUMN_PATH:
2914
- default: {
2915
- /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
2916
- ** always return their values as NULL */
2917
- break;
2918
- }
2919
- }
2920
- return SQLITE_OK;
2921
-}
2922
-
2923
-/*
2924
-** Return the rowid for the current row. In this implementation, the
2925
-** first row returned is assigned rowid value 1, and each subsequent
2926
-** row a value 1 more than that of the previous.
2927
-*/
2928
-static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
2929
- fsdir_cursor *pCur = (fsdir_cursor*)cur;
2930
- *pRowid = pCur->iRowid;
2931
- return SQLITE_OK;
2932
-}
2933
-
2934
-/*
2935
-** Return TRUE if the cursor has been moved off of the last
2936
-** row of output.
2937
-*/
2938
-static int fsdirEof(sqlite3_vtab_cursor *cur){
2939
- fsdir_cursor *pCur = (fsdir_cursor*)cur;
2940
- return (pCur->zPath==0);
2941
-}
2942
-
2943
-/*
2944
-** xFilter callback.
2945
-**
2946
-** idxNum==1 PATH parameter only
2947
-** idxNum==2 Both PATH and DIR supplied
2948
-*/
2949
-static int fsdirFilter(
2950
- sqlite3_vtab_cursor *cur,
2951
- int idxNum, const char *idxStr,
2952
- int argc, sqlite3_value **argv
2953
-){
2954
- const char *zDir = 0;
2955
- fsdir_cursor *pCur = (fsdir_cursor*)cur;
2956
- (void)idxStr;
2957
- fsdirResetCursor(pCur);
2958
-
2959
- if( idxNum==0 ){
2960
- fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
2961
- return SQLITE_ERROR;
2962
- }
2963
-
2964
- assert( argc==idxNum && (argc==1 || argc==2) );
2965
- zDir = (const char*)sqlite3_value_text(argv[0]);
2966
- if( zDir==0 ){
2967
- fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
2968
- return SQLITE_ERROR;
2969
- }
2970
- if( argc==2 ){
2971
- pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
2972
- }
2973
- if( pCur->zBase ){
2974
- pCur->nBase = (int)strlen(pCur->zBase)+1;
2975
- pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
2976
- }else{
2977
- pCur->zPath = sqlite3_mprintf("%s", zDir);
2978
- }
2979
-
2980
- if( pCur->zPath==0 ){
2981
- return SQLITE_NOMEM;
2982
- }
2983
- if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
2984
- fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
2985
- return SQLITE_ERROR;
2986
- }
2987
-
2988
- return SQLITE_OK;
2989
-}
2990
-
2991
-/*
2992
-** SQLite will invoke this method one or more times while planning a query
2993
-** that uses the generate_series virtual table. This routine needs to create
2994
-** a query plan for each invocation and compute an estimated cost for that
2995
-** plan.
2996
-**
2997
-** In this implementation idxNum is used to represent the
2998
-** query plan. idxStr is unused.
2999
-**
3000
-** The query plan is represented by values of idxNum:
3001
-**
3002
-** (1) The path value is supplied by argv[0]
3003
-** (2) Path is in argv[0] and dir is in argv[1]
3004
-*/
3005
-static int fsdirBestIndex(
3006
- sqlite3_vtab *tab,
3007
- sqlite3_index_info *pIdxInfo
3008
-){
3009
- int i; /* Loop over constraints */
3010
- int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
3011
- int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
3012
- int seenPath = 0; /* True if an unusable PATH= constraint is seen */
3013
- int seenDir = 0; /* True if an unusable DIR= constraint is seen */
3014
- const struct sqlite3_index_constraint *pConstraint;
3015
-
3016
- (void)tab;
3017
- pConstraint = pIdxInfo->aConstraint;
3018
- for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
3019
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
3020
- switch( pConstraint->iColumn ){
3021
- case FSDIR_COLUMN_PATH: {
3022
- if( pConstraint->usable ){
3023
- idxPath = i;
3024
- seenPath = 0;
3025
- }else if( idxPath<0 ){
3026
- seenPath = 1;
3027
- }
3028
- break;
3029
- }
3030
- case FSDIR_COLUMN_DIR: {
3031
- if( pConstraint->usable ){
3032
- idxDir = i;
3033
- seenDir = 0;
3034
- }else if( idxDir<0 ){
3035
- seenDir = 1;
3036
- }
3037
- break;
3038
- }
3039
- }
3040
- }
3041
- if( seenPath || seenDir ){
3042
- /* If input parameters are unusable, disallow this plan */
3043
- return SQLITE_CONSTRAINT;
3044
- }
3045
-
3046
- if( idxPath<0 ){
3047
- pIdxInfo->idxNum = 0;
3048
- /* The pIdxInfo->estimatedCost should have been initialized to a huge
3049
- ** number. Leave it unchanged. */
3050
- pIdxInfo->estimatedRows = 0x7fffffff;
3051
- }else{
3052
- pIdxInfo->aConstraintUsage[idxPath].omit = 1;
3053
- pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
3054
- if( idxDir>=0 ){
3055
- pIdxInfo->aConstraintUsage[idxDir].omit = 1;
3056
- pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
3057
- pIdxInfo->idxNum = 2;
3058
- pIdxInfo->estimatedCost = 10.0;
3059
- }else{
3060
- pIdxInfo->idxNum = 1;
3061
- pIdxInfo->estimatedCost = 100.0;
3062
- }
3063
- }
3064
-
3065
- return SQLITE_OK;
3066
-}
3067
-
3068
-/*
3069
-** Register the "fsdir" virtual table.
3070
-*/
3071
-static int fsdirRegister(sqlite3 *db){
3072
- static sqlite3_module fsdirModule = {
3073
- 0, /* iVersion */
3074
- 0, /* xCreate */
3075
- fsdirConnect, /* xConnect */
3076
- fsdirBestIndex, /* xBestIndex */
3077
- fsdirDisconnect, /* xDisconnect */
3078
- 0, /* xDestroy */
3079
- fsdirOpen, /* xOpen - open a cursor */
3080
- fsdirClose, /* xClose - close a cursor */
3081
- fsdirFilter, /* xFilter - configure scan constraints */
3082
- fsdirNext, /* xNext - advance a cursor */
3083
- fsdirEof, /* xEof - check for end of scan */
3084
- fsdirColumn, /* xColumn - read data */
3085
- fsdirRowid, /* xRowid - read data */
3086
- 0, /* xUpdate */
3087
- 0, /* xBegin */
3088
- 0, /* xSync */
3089
- 0, /* xCommit */
3090
- 0, /* xRollback */
3091
- 0, /* xFindMethod */
3092
- 0, /* xRename */
3093
- 0, /* xSavepoint */
3094
- 0, /* xRelease */
3095
- 0, /* xRollbackTo */
3096
- 0, /* xShadowName */
3097
- };
3098
-
3099
- int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
3100
- return rc;
3101
-}
3102
-#else /* SQLITE_OMIT_VIRTUALTABLE */
3103
-# define fsdirRegister(x) SQLITE_OK
3104
-#endif
3105
-
3106
-#ifdef _WIN32
3107
-
3108
-#endif
3109
-int sqlite3_fileio_init(
3110
- sqlite3 *db,
3111
- char **pzErrMsg,
3112
- const sqlite3_api_routines *pApi
3113
-){
3114
- int rc = SQLITE_OK;
3115
- SQLITE_EXTENSION_INIT2(pApi);
3116
- (void)pzErrMsg; /* Unused parameter */
3117
- rc = sqlite3_create_function(db, "readfile", 1,
3118
- SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
3119
- readfileFunc, 0, 0);
3120
- if( rc==SQLITE_OK ){
3121
- rc = sqlite3_create_function(db, "writefile", -1,
3122
- SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
3123
- writefileFunc, 0, 0);
3124
- }
3125
- if( rc==SQLITE_OK ){
3126
- rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
3127
- lsModeFunc, 0, 0);
3128
- }
3129
- if( rc==SQLITE_OK ){
3130
- rc = fsdirRegister(db);
3131
- }
3132
- return rc;
3133
-}
3134
-
3135
-#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
3136
-/* To allow a standalone DLL, make test_windirent.c use the same
3137
- * redefined SQLite API calls as the above extension code does.
3138
- * Just pull in this .c to accomplish this. As a beneficial side
3139
- * effect, this extension becomes a single translation unit. */
3140
-# include "test_windirent.c"
3141
-#endif
3142
-
3143
-/************************* End ../ext/misc/fileio.c ********************/
3144
-/************************* Begin ../ext/misc/completion.c ******************/
3145
-/*
3146
-** 2017-07-10
3147
-**
3148
-** The author disclaims copyright to this source code. In place of
3149
-** a legal notice, here is a blessing:
3150
-**
3151
-** May you do good and not evil.
3152
-** May you find forgiveness for yourself and forgive others.
3153
-** May you share freely, never taking more than you give.
3154
-**
3155
-*************************************************************************
3156
-**
3157
-** This file implements an eponymous virtual table that returns suggested
3158
-** completions for a partial SQL input.
3159
-**
3160
-** Suggested usage:
3161
-**
3162
-** SELECT DISTINCT candidate COLLATE nocase
3163
-** FROM completion($prefix,$wholeline)
3164
-** ORDER BY 1;
3165
-**
3166
-** The two query parameters are optional. $prefix is the text of the
3167
-** current word being typed and that is to be completed. $wholeline is
3168
-** the complete input line, used for context.
3169
-**
3170
-** The raw completion() table might return the same candidate multiple
3171
-** times, for example if the same column name is used to two or more
3172
-** tables. And the candidates are returned in an arbitrary order. Hence,
3173
-** the DISTINCT and ORDER BY are recommended.
3174
-**
3175
-** This virtual table operates at the speed of human typing, and so there
3176
-** is no attempt to make it fast. Even a slow implementation will be much
3177
-** faster than any human can type.
3178
-**
3179
-*/
3180
-/* #include "sqlite3ext.h" */
3181
-SQLITE_EXTENSION_INIT1
3182
-#include <assert.h>
3183
-#include <string.h>
3184
-#include <ctype.h>
3185
-
3186
-#ifndef SQLITE_OMIT_VIRTUALTABLE
3187
-
3188
-/* completion_vtab is a subclass of sqlite3_vtab which will
3189
-** serve as the underlying representation of a completion virtual table
3190
-*/
3191
-typedef struct completion_vtab completion_vtab;
3192
-struct completion_vtab {
3193
- sqlite3_vtab base; /* Base class - must be first */
3194
- sqlite3 *db; /* Database connection for this completion vtab */
3195
-};
3196
-
3197
-/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
3198
-** serve as the underlying representation of a cursor that scans
3199
-** over rows of the result
3200
-*/
3201
-typedef struct completion_cursor completion_cursor;
3202
-struct completion_cursor {
3203
- sqlite3_vtab_cursor base; /* Base class - must be first */
3204
- sqlite3 *db; /* Database connection for this cursor */
3205
- int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */
3206
- char *zPrefix; /* The prefix for the word we want to complete */
3207
- char *zLine; /* The whole that we want to complete */
3208
- const char *zCurrentRow; /* Current output row */
3209
- int szRow; /* Length of the zCurrentRow string */
3210
- sqlite3_stmt *pStmt; /* Current statement */
3211
- sqlite3_int64 iRowid; /* The rowid */
3212
- int ePhase; /* Current phase */
3213
- int j; /* inter-phase counter */
3214
-};
3215
-
3216
-/* Values for ePhase:
3217
-*/
3218
-#define COMPLETION_FIRST_PHASE 1
3219
-#define COMPLETION_KEYWORDS 1
3220
-#define COMPLETION_PRAGMAS 2
3221
-#define COMPLETION_FUNCTIONS 3
3222
-#define COMPLETION_COLLATIONS 4
3223
-#define COMPLETION_INDEXES 5
3224
-#define COMPLETION_TRIGGERS 6
3225
-#define COMPLETION_DATABASES 7
3226
-#define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */
3227
-#define COMPLETION_COLUMNS 9
3228
-#define COMPLETION_MODULES 10
3229
-#define COMPLETION_EOF 11
3230
-
3231
-/*
3232
-** The completionConnect() method is invoked to create a new
3233
-** completion_vtab that describes the completion virtual table.
3234
-**
3235
-** Think of this routine as the constructor for completion_vtab objects.
3236
-**
3237
-** All this routine needs to do is:
3238
-**
3239
-** (1) Allocate the completion_vtab object and initialize all fields.
3240
-**
3241
-** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
3242
-** result set of queries against completion will look like.
3243
-*/
3244
-static int completionConnect(
3245
- sqlite3 *db,
3246
- void *pAux,
3247
- int argc, const char *const*argv,
3248
- sqlite3_vtab **ppVtab,
3249
- char **pzErr
3250
-){
3251
- completion_vtab *pNew;
3252
- int rc;
3253
-
3254
- (void)(pAux); /* Unused parameter */
3255
- (void)(argc); /* Unused parameter */
3256
- (void)(argv); /* Unused parameter */
3257
- (void)(pzErr); /* Unused parameter */
3258
-
3259
-/* Column numbers */
3260
-#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
3261
-#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
3262
-#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
3263
-#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
3264
-
3265
- sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
3266
- rc = sqlite3_declare_vtab(db,
3267
- "CREATE TABLE x("
3268
- " candidate TEXT,"
3269
- " prefix TEXT HIDDEN,"
3270
- " wholeline TEXT HIDDEN,"
3271
- " phase INT HIDDEN" /* Used for debugging only */
3272
- ")");
3273
- if( rc==SQLITE_OK ){
3274
- pNew = sqlite3_malloc( sizeof(*pNew) );
3275
- *ppVtab = (sqlite3_vtab*)pNew;
3276
- if( pNew==0 ) return SQLITE_NOMEM;
3277
- memset(pNew, 0, sizeof(*pNew));
3278
- pNew->db = db;
3279
- }
3280
- return rc;
3281
-}
3282
-
3283
-/*
3284
-** This method is the destructor for completion_cursor objects.
3285
-*/
3286
-static int completionDisconnect(sqlite3_vtab *pVtab){
3287
- sqlite3_free(pVtab);
3288
- return SQLITE_OK;
3289
-}
3290
-
3291
-/*
3292
-** Constructor for a new completion_cursor object.
3293
-*/
3294
-static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
3295
- completion_cursor *pCur;
3296
- pCur = sqlite3_malloc( sizeof(*pCur) );
3297
- if( pCur==0 ) return SQLITE_NOMEM;
3298
- memset(pCur, 0, sizeof(*pCur));
3299
- pCur->db = ((completion_vtab*)p)->db;
3300
- *ppCursor = &pCur->base;
3301
- return SQLITE_OK;
3302
-}
3303
-
3304
-/*
3305
-** Reset the completion_cursor.
3306
-*/
3307
-static void completionCursorReset(completion_cursor *pCur){
3308
- sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0;
3309
- sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0;
3310
- sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
3311
- pCur->j = 0;
3312
-}
3313
-
3314
-/*
3315
-** Destructor for a completion_cursor.
3316
-*/
3317
-static int completionClose(sqlite3_vtab_cursor *cur){
3318
- completionCursorReset((completion_cursor*)cur);
3319
- sqlite3_free(cur);
3320
- return SQLITE_OK;
3321
-}
3322
-
3323
-/*
3324
-** Advance a completion_cursor to its next row of output.
3325
-**
3326
-** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
3327
-** record the current state of the scan. This routine sets ->zCurrentRow
3328
-** to the current row of output and then returns. If no more rows remain,
3329
-** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
3330
-** table that has reached the end of its scan.
3331
-**
3332
-** The current implementation just lists potential identifiers and
3333
-** keywords and filters them by zPrefix. Future enhancements should
3334
-** take zLine into account to try to restrict the set of identifiers and
3335
-** keywords based on what would be legal at the current point of input.
3336
-*/
3337
-static int completionNext(sqlite3_vtab_cursor *cur){
3338
- completion_cursor *pCur = (completion_cursor*)cur;
3339
- int eNextPhase = 0; /* Next phase to try if current phase reaches end */
3340
- int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
3341
- pCur->iRowid++;
3342
- while( pCur->ePhase!=COMPLETION_EOF ){
3343
- switch( pCur->ePhase ){
3344
- case COMPLETION_KEYWORDS: {
3345
- if( pCur->j >= sqlite3_keyword_count() ){
3346
- pCur->zCurrentRow = 0;
3347
- pCur->ePhase = COMPLETION_DATABASES;
3348
- }else{
3349
- sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
3350
- }
3351
- iCol = -1;
3352
- break;
3353
- }
3354
- case COMPLETION_DATABASES: {
3355
- if( pCur->pStmt==0 ){
3356
- sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
3357
- &pCur->pStmt, 0);
3358
- }
3359
- iCol = 1;
3360
- eNextPhase = COMPLETION_TABLES;
3361
- break;
3362
- }
3363
- case COMPLETION_TABLES: {
3364
- if( pCur->pStmt==0 ){
3365
- sqlite3_stmt *pS2;
3366
- char *zSql = 0;
3367
- const char *zSep = "";
3368
- sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
3369
- while( sqlite3_step(pS2)==SQLITE_ROW ){
3370
- const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
3371
- zSql = sqlite3_mprintf(
3372
- "%z%s"
3373
- "SELECT name FROM \"%w\".sqlite_schema",
3374
- zSql, zSep, zDb
3375
- );
3376
- if( zSql==0 ) return SQLITE_NOMEM;
3377
- zSep = " UNION ";
3378
- }
3379
- sqlite3_finalize(pS2);
3380
- sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
3381
- sqlite3_free(zSql);
3382
- }
3383
- iCol = 0;
3384
- eNextPhase = COMPLETION_COLUMNS;
3385
- break;
3386
- }
3387
- case COMPLETION_COLUMNS: {
3388
- if( pCur->pStmt==0 ){
3389
- sqlite3_stmt *pS2;
3390
- char *zSql = 0;
3391
- const char *zSep = "";
3392
- sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
3393
- while( sqlite3_step(pS2)==SQLITE_ROW ){
3394
- const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
3395
- zSql = sqlite3_mprintf(
3396
- "%z%s"
3397
- "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
3398
- " JOIN pragma_table_info(sm.name,%Q) AS pti"
3399
- " WHERE sm.type='table'",
3400
- zSql, zSep, zDb, zDb
3401
- );
3402
- if( zSql==0 ) return SQLITE_NOMEM;
3403
- zSep = " UNION ";
3404
- }
3405
- sqlite3_finalize(pS2);
3406
- sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
3407
- sqlite3_free(zSql);
3408
- }
3409
- iCol = 0;
3410
- eNextPhase = COMPLETION_EOF;
3411
- break;
3412
- }
3413
- }
3414
- if( iCol<0 ){
3415
- /* This case is when the phase presets zCurrentRow */
3416
- if( pCur->zCurrentRow==0 ) continue;
3417
- }else{
3418
- if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
3419
- /* Extract the next row of content */
3420
- pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
3421
- pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
3422
- }else{
3423
- /* When all rows are finished, advance to the next phase */
3424
- sqlite3_finalize(pCur->pStmt);
3425
- pCur->pStmt = 0;
3426
- pCur->ePhase = eNextPhase;
3427
- continue;
3428
- }
3429
- }
3430
- if( pCur->nPrefix==0 ) break;
3431
- if( pCur->nPrefix<=pCur->szRow
3432
- && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
3433
- ){
3434
- break;
3435
- }
3436
- }
3437
-
3438
- return SQLITE_OK;
3439
-}
3440
-
3441
-/*
3442
-** Return values of columns for the row at which the completion_cursor
3443
-** is currently pointing.
3444
-*/
3445
-static int completionColumn(
3446
- sqlite3_vtab_cursor *cur, /* The cursor */
3447
- sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
3448
- int i /* Which column to return */
3449
-){
3450
- completion_cursor *pCur = (completion_cursor*)cur;
3451
- switch( i ){
3452
- case COMPLETION_COLUMN_CANDIDATE: {
3453
- sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
3454
- break;
3455
- }
3456
- case COMPLETION_COLUMN_PREFIX: {
3457
- sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
3458
- break;
3459
- }
3460
- case COMPLETION_COLUMN_WHOLELINE: {
3461
- sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
3462
- break;
3463
- }
3464
- case COMPLETION_COLUMN_PHASE: {
3465
- sqlite3_result_int(ctx, pCur->ePhase);
3466
- break;
3467
- }
3468
- }
3469
- return SQLITE_OK;
3470
-}
3471
-
3472
-/*
3473
-** Return the rowid for the current row. In this implementation, the
3474
-** rowid is the same as the output value.
3475
-*/
3476
-static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
3477
- completion_cursor *pCur = (completion_cursor*)cur;
3478
- *pRowid = pCur->iRowid;
3479
- return SQLITE_OK;
3480
-}
3481
-
3482
-/*
3483
-** Return TRUE if the cursor has been moved off of the last
3484
-** row of output.
3485
-*/
3486
-static int completionEof(sqlite3_vtab_cursor *cur){
3487
- completion_cursor *pCur = (completion_cursor*)cur;
3488
- return pCur->ePhase >= COMPLETION_EOF;
3489
-}
3490
-
3491
-/*
3492
-** This method is called to "rewind" the completion_cursor object back
3493
-** to the first row of output. This method is always called at least
3494
-** once prior to any call to completionColumn() or completionRowid() or
3495
-** completionEof().
3496
-*/
3497
-static int completionFilter(
3498
- sqlite3_vtab_cursor *pVtabCursor,
3499
- int idxNum, const char *idxStr,
3500
- int argc, sqlite3_value **argv
3501
-){
3502
- completion_cursor *pCur = (completion_cursor *)pVtabCursor;
3503
- int iArg = 0;
3504
- (void)(idxStr); /* Unused parameter */
3505
- (void)(argc); /* Unused parameter */
3506
- completionCursorReset(pCur);
3507
- if( idxNum & 1 ){
3508
- pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
3509
- if( pCur->nPrefix>0 ){
3510
- pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
3511
- if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
3512
- }
3513
- iArg = 1;
3514
- }
3515
- if( idxNum & 2 ){
3516
- pCur->nLine = sqlite3_value_bytes(argv[iArg]);
3517
- if( pCur->nLine>0 ){
3518
- pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
3519
- if( pCur->zLine==0 ) return SQLITE_NOMEM;
3520
- }
3521
- }
3522
- if( pCur->zLine!=0 && pCur->zPrefix==0 ){
3523
- int i = pCur->nLine;
3524
- while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
3525
- i--;
3526
- }
3527
- pCur->nPrefix = pCur->nLine - i;
3528
- if( pCur->nPrefix>0 ){
3529
- pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
3530
- if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
3531
- }
3532
- }
3533
- pCur->iRowid = 0;
3534
- pCur->ePhase = COMPLETION_FIRST_PHASE;
3535
- return completionNext(pVtabCursor);
3536
-}
3537
-
3538
-/*
3539
-** SQLite will invoke this method one or more times while planning a query
3540
-** that uses the completion virtual table. This routine needs to create
3541
-** a query plan for each invocation and compute an estimated cost for that
3542
-** plan.
3543
-**
3544
-** There are two hidden parameters that act as arguments to the table-valued
3545
-** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix"
3546
-** is available and bit 1 is set if "wholeline" is available.
3547
-*/
3548
-static int completionBestIndex(
3549
- sqlite3_vtab *tab,
3550
- sqlite3_index_info *pIdxInfo
3551
-){
3552
- int i; /* Loop over constraints */
3553
- int idxNum = 0; /* The query plan bitmask */
3554
- int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */
3555
- int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
3556
- int nArg = 0; /* Number of arguments that completeFilter() expects */
3557
- const struct sqlite3_index_constraint *pConstraint;
3558
-
3559
- (void)(tab); /* Unused parameter */
3560
- pConstraint = pIdxInfo->aConstraint;
3561
- for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
3562
- if( pConstraint->usable==0 ) continue;
3563
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
3564
- switch( pConstraint->iColumn ){
3565
- case COMPLETION_COLUMN_PREFIX:
3566
- prefixIdx = i;
3567
- idxNum |= 1;
3568
- break;
3569
- case COMPLETION_COLUMN_WHOLELINE:
3570
- wholelineIdx = i;
3571
- idxNum |= 2;
3572
- break;
3573
- }
3574
- }
3575
- if( prefixIdx>=0 ){
3576
- pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
3577
- pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
3578
- }
3579
- if( wholelineIdx>=0 ){
3580
- pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
3581
- pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
3582
- }
3583
- pIdxInfo->idxNum = idxNum;
3584
- pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
3585
- pIdxInfo->estimatedRows = 500 - 100*nArg;
3586
- return SQLITE_OK;
3587
-}
3588
-
3589
-/*
3590
-** This following structure defines all the methods for the
3591
-** completion virtual table.
3592
-*/
3593
-static sqlite3_module completionModule = {
3594
- 0, /* iVersion */
3595
- 0, /* xCreate */
3596
- completionConnect, /* xConnect */
3597
- completionBestIndex, /* xBestIndex */
3598
- completionDisconnect, /* xDisconnect */
3599
- 0, /* xDestroy */
3600
- completionOpen, /* xOpen - open a cursor */
3601
- completionClose, /* xClose - close a cursor */
3602
- completionFilter, /* xFilter - configure scan constraints */
3603
- completionNext, /* xNext - advance a cursor */
3604
- completionEof, /* xEof - check for end of scan */
3605
- completionColumn, /* xColumn - read data */
3606
- completionRowid, /* xRowid - read data */
3607
- 0, /* xUpdate */
3608
- 0, /* xBegin */
3609
- 0, /* xSync */
3610
- 0, /* xCommit */
3611
- 0, /* xRollback */
3612
- 0, /* xFindMethod */
3613
- 0, /* xRename */
3614
- 0, /* xSavepoint */
3615
- 0, /* xRelease */
3616
- 0, /* xRollbackTo */
3617
- 0 /* xShadowName */
3618
-};
3619
-
3620
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
3621
-
3622
-int sqlite3CompletionVtabInit(sqlite3 *db){
3623
- int rc = SQLITE_OK;
3624
-#ifndef SQLITE_OMIT_VIRTUALTABLE
3625
- rc = sqlite3_create_module(db, "completion", &completionModule, 0);
3626
-#endif
3627
- return rc;
3628
-}
3629
-
3630
-#ifdef _WIN32
3631
-
3632
-#endif
3633
-int sqlite3_completion_init(
3634
- sqlite3 *db,
3635
- char **pzErrMsg,
3636
- const sqlite3_api_routines *pApi
3637
-){
3638
- int rc = SQLITE_OK;
3639
- SQLITE_EXTENSION_INIT2(pApi);
3640
- (void)(pzErrMsg); /* Unused parameter */
3641
-#ifndef SQLITE_OMIT_VIRTUALTABLE
3642
- rc = sqlite3CompletionVtabInit(db);
3643
-#endif
3644
- return rc;
3645
-}
3646
-
3647
-/************************* End ../ext/misc/completion.c ********************/
3648
-/************************* Begin ../ext/misc/appendvfs.c ******************/
3649
-/*
3650
-** 2017-10-20
3651
-**
3652
-** The author disclaims copyright to this source code. In place of
3653
-** a legal notice, here is a blessing:
3654
-**
3655
-** May you do good and not evil.
3656
-** May you find forgiveness for yourself and forgive others.
3657
-** May you share freely, never taking more than you give.
3658
-**
3659
-******************************************************************************
3660
-**
3661
-** This file implements a VFS shim that allows an SQLite database to be
3662
-** appended onto the end of some other file, such as an executable.
3663
-**
3664
-** A special record must appear at the end of the file that identifies the
3665
-** file as an appended database and provides the offset to the first page
3666
-** of the exposed content. (Or, it is the length of the content prefix.)
3667
-** For best performance page 1 should be located at a disk page boundary,
3668
-** though that is not required.
3669
-**
3670
-** When opening a database using this VFS, the connection might treat
3671
-** the file as an ordinary SQLite database, or it might treat it as a
3672
-** database appended onto some other file. The decision is made by
3673
-** applying the following rules in order:
3674
-**
3675
-** (1) An empty file is an ordinary database.
3676
-**
3677
-** (2) If the file ends with the appendvfs trailer string
3678
-** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
3679
-**
3680
-** (3) If the file begins with the standard SQLite prefix string
3681
-** "SQLite format 3", that file is an ordinary database.
3682
-**
3683
-** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
3684
-** set, then a new database is appended to the already existing file.
3685
-**
3686
-** (5) Otherwise, SQLITE_CANTOPEN is returned.
3687
-**
3688
-** To avoid unnecessary complications with the PENDING_BYTE, the size of
3689
-** the file containing the database is limited to 1GiB. (1073741824 bytes)
3690
-** This VFS will not read or write past the 1GiB mark. This restriction
3691
-** might be lifted in future versions. For now, if you need a larger
3692
-** database, then keep it in a separate file.
3693
-**
3694
-** If the file being opened is a plain database (not an appended one), then
3695
-** this shim is a pass-through into the default underlying VFS. (rule 3)
3696
-**/
3697
-/* #include "sqlite3ext.h" */
3698
-SQLITE_EXTENSION_INIT1
3699
-#include <string.h>
3700
-#include <assert.h>
3701
-
3702
-/* The append mark at the end of the database is:
3703
-**
3704
-** Start-Of-SQLite3-NNNNNNNN
3705
-** 123456789 123456789 12345
3706
-**
3707
-** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
3708
-** the offset to page 1, and also the length of the prefix content.
3709
-*/
3710
-#define APND_MARK_PREFIX "Start-Of-SQLite3-"
3711
-#define APND_MARK_PREFIX_SZ 17
3712
-#define APND_MARK_FOS_SZ 8
3713
-#define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
3714
-
3715
-/*
3716
-** Maximum size of the combined prefix + database + append-mark. This
3717
-** must be less than 0x40000000 to avoid locking issues on Windows.
3718
-*/
3719
-#define APND_MAX_SIZE (0x40000000)
3720
-
3721
-/*
3722
-** Try to align the database to an even multiple of APND_ROUNDUP bytes.
3723
-*/
3724
-#ifndef APND_ROUNDUP
3725
-#define APND_ROUNDUP 4096
3726
-#endif
3727
-#define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1))
3728
-#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
3729
-
3730
-/*
3731
-** Forward declaration of objects used by this utility
3732
-*/
3733
-typedef struct sqlite3_vfs ApndVfs;
3734
-typedef struct ApndFile ApndFile;
3735
-
3736
-/* Access to a lower-level VFS that (might) implement dynamic loading,
3737
-** access to randomness, etc.
3738
-*/
3739
-#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
3740
-#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
3741
-
3742
-/* An open appendvfs file
3743
-**
3744
-** An instance of this structure describes the appended database file.
3745
-** A separate sqlite3_file object is always appended. The appended
3746
-** sqlite3_file object (which can be accessed using ORIGFILE()) describes
3747
-** the entire file, including the prefix, the database, and the
3748
-** append-mark.
3749
-**
3750
-** The structure of an AppendVFS database is like this:
3751
-**
3752
-** +-------------+---------+----------+-------------+
3753
-** | prefix-file | padding | database | append-mark |
3754
-** +-------------+---------+----------+-------------+
3755
-** ^ ^
3756
-** | |
3757
-** iPgOne iMark
3758
-**
3759
-**
3760
-** "prefix file" - file onto which the database has been appended.
3761
-** "padding" - zero or more bytes inserted so that "database"
3762
-** starts on an APND_ROUNDUP boundary
3763
-** "database" - The SQLite database file
3764
-** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
3765
-** the offset from the start of prefix-file to the start
3766
-** of "database".
3767
-**
3768
-** The size of the database is iMark - iPgOne.
3769
-**
3770
-** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
3771
-** of iPgOne stored as a big-ending 64-bit integer.
3772
-**
3773
-** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
3774
-** Or, iMark is -1 to indicate that it has not yet been written.
3775
-*/
3776
-struct ApndFile {
3777
- sqlite3_file base; /* Subclass. MUST BE FIRST! */
3778
- sqlite3_int64 iPgOne; /* Offset to the start of the database */
3779
- sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */
3780
- /* Always followed by another sqlite3_file that describes the whole file */
3781
-};
3782
-
3783
-/*
3784
-** Methods for ApndFile
3785
-*/
3786
-static int apndClose(sqlite3_file*);
3787
-static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
3788
-static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
3789
-static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
3790
-static int apndSync(sqlite3_file*, int flags);
3791
-static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
3792
-static int apndLock(sqlite3_file*, int);
3793
-static int apndUnlock(sqlite3_file*, int);
3794
-static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
3795
-static int apndFileControl(sqlite3_file*, int op, void *pArg);
3796
-static int apndSectorSize(sqlite3_file*);
3797
-static int apndDeviceCharacteristics(sqlite3_file*);
3798
-static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
3799
-static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
3800
-static void apndShmBarrier(sqlite3_file*);
3801
-static int apndShmUnmap(sqlite3_file*, int deleteFlag);
3802
-static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
3803
-static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
3804
-
3805
-/*
3806
-** Methods for ApndVfs
3807
-*/
3808
-static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
3809
-static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
3810
-static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
3811
-static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
3812
-static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
3813
-static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
3814
-static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
3815
-static void apndDlClose(sqlite3_vfs*, void*);
3816
-static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
3817
-static int apndSleep(sqlite3_vfs*, int microseconds);
3818
-static int apndCurrentTime(sqlite3_vfs*, double*);
3819
-static int apndGetLastError(sqlite3_vfs*, int, char *);
3820
-static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
3821
-static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
3822
-static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
3823
-static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
3824
-
3825
-static sqlite3_vfs apnd_vfs = {
3826
- 3, /* iVersion (set when registered) */
3827
- 0, /* szOsFile (set when registered) */
3828
- 1024, /* mxPathname */
3829
- 0, /* pNext */
3830
- "apndvfs", /* zName */
3831
- 0, /* pAppData (set when registered) */
3832
- apndOpen, /* xOpen */
3833
- apndDelete, /* xDelete */
3834
- apndAccess, /* xAccess */
3835
- apndFullPathname, /* xFullPathname */
3836
- apndDlOpen, /* xDlOpen */
3837
- apndDlError, /* xDlError */
3838
- apndDlSym, /* xDlSym */
3839
- apndDlClose, /* xDlClose */
3840
- apndRandomness, /* xRandomness */
3841
- apndSleep, /* xSleep */
3842
- apndCurrentTime, /* xCurrentTime */
3843
- apndGetLastError, /* xGetLastError */
3844
- apndCurrentTimeInt64, /* xCurrentTimeInt64 */
3845
- apndSetSystemCall, /* xSetSystemCall */
3846
- apndGetSystemCall, /* xGetSystemCall */
3847
- apndNextSystemCall /* xNextSystemCall */
3848
-};
3849
-
3850
-static const sqlite3_io_methods apnd_io_methods = {
3851
- 3, /* iVersion */
3852
- apndClose, /* xClose */
3853
- apndRead, /* xRead */
3854
- apndWrite, /* xWrite */
3855
- apndTruncate, /* xTruncate */
3856
- apndSync, /* xSync */
3857
- apndFileSize, /* xFileSize */
3858
- apndLock, /* xLock */
3859
- apndUnlock, /* xUnlock */
3860
- apndCheckReservedLock, /* xCheckReservedLock */
3861
- apndFileControl, /* xFileControl */
3862
- apndSectorSize, /* xSectorSize */
3863
- apndDeviceCharacteristics, /* xDeviceCharacteristics */
3864
- apndShmMap, /* xShmMap */
3865
- apndShmLock, /* xShmLock */
3866
- apndShmBarrier, /* xShmBarrier */
3867
- apndShmUnmap, /* xShmUnmap */
3868
- apndFetch, /* xFetch */
3869
- apndUnfetch /* xUnfetch */
3870
-};
3871
-
3872
-/*
3873
-** Close an apnd-file.
3874
-*/
3875
-static int apndClose(sqlite3_file *pFile){
3876
- pFile = ORIGFILE(pFile);
3877
- return pFile->pMethods->xClose(pFile);
3878
-}
3879
-
3880
-/*
3881
-** Read data from an apnd-file.
3882
-*/
3883
-static int apndRead(
3884
- sqlite3_file *pFile,
3885
- void *zBuf,
3886
- int iAmt,
3887
- sqlite_int64 iOfst
3888
-){
3889
- ApndFile *paf = (ApndFile *)pFile;
3890
- pFile = ORIGFILE(pFile);
3891
- return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
3892
-}
3893
-
3894
-/*
3895
-** Add the append-mark onto what should become the end of the file.
3896
-* If and only if this succeeds, internal ApndFile.iMark is updated.
3897
-* Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
3898
-*/
3899
-static int apndWriteMark(
3900
- ApndFile *paf,
3901
- sqlite3_file *pFile,
3902
- sqlite_int64 iWriteEnd
3903
-){
3904
- sqlite_int64 iPgOne = paf->iPgOne;
3905
- unsigned char a[APND_MARK_SIZE];
3906
- int i = APND_MARK_FOS_SZ;
3907
- int rc;
3908
- assert(pFile == ORIGFILE(paf));
3909
- memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
3910
- while( --i >= 0 ){
3911
- a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
3912
- iPgOne >>= 8;
3913
- }
3914
- iWriteEnd += paf->iPgOne;
3915
- if( SQLITE_OK==(rc = pFile->pMethods->xWrite
3916
- (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
3917
- paf->iMark = iWriteEnd;
3918
- }
3919
- return rc;
3920
-}
3921
-
3922
-/*
3923
-** Write data to an apnd-file.
3924
-*/
3925
-static int apndWrite(
3926
- sqlite3_file *pFile,
3927
- const void *zBuf,
3928
- int iAmt,
3929
- sqlite_int64 iOfst
3930
-){
3931
- ApndFile *paf = (ApndFile *)pFile;
3932
- sqlite_int64 iWriteEnd = iOfst + iAmt;
3933
- if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
3934
- pFile = ORIGFILE(pFile);
3935
- /* If append-mark is absent or will be overwritten, write it. */
3936
- if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
3937
- int rc = apndWriteMark(paf, pFile, iWriteEnd);
3938
- if( SQLITE_OK!=rc ) return rc;
3939
- }
3940
- return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
3941
-}
3942
-
3943
-/*
3944
-** Truncate an apnd-file.
3945
-*/
3946
-static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
3947
- ApndFile *paf = (ApndFile *)pFile;
3948
- pFile = ORIGFILE(pFile);
3949
- /* The append mark goes out first so truncate failure does not lose it. */
3950
- if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
3951
- /* Truncate underlying file just past append mark */
3952
- return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
3953
-}
3954
-
3955
-/*
3956
-** Sync an apnd-file.
3957
-*/
3958
-static int apndSync(sqlite3_file *pFile, int flags){
3959
- pFile = ORIGFILE(pFile);
3960
- return pFile->pMethods->xSync(pFile, flags);
3961
-}
3962
-
3963
-/*
3964
-** Return the current file-size of an apnd-file.
3965
-** If the append mark is not yet there, the file-size is 0.
3966
-*/
3967
-static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
3968
- ApndFile *paf = (ApndFile *)pFile;
3969
- *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
3970
- return SQLITE_OK;
3971
-}
3972
-
3973
-/*
3974
-** Lock an apnd-file.
3975
-*/
3976
-static int apndLock(sqlite3_file *pFile, int eLock){
3977
- pFile = ORIGFILE(pFile);
3978
- return pFile->pMethods->xLock(pFile, eLock);
3979
-}
3980
-
3981
-/*
3982
-** Unlock an apnd-file.
3983
-*/
3984
-static int apndUnlock(sqlite3_file *pFile, int eLock){
3985
- pFile = ORIGFILE(pFile);
3986
- return pFile->pMethods->xUnlock(pFile, eLock);
3987
-}
3988
-
3989
-/*
3990
-** Check if another file-handle holds a RESERVED lock on an apnd-file.
3991
-*/
3992
-static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
3993
- pFile = ORIGFILE(pFile);
3994
- return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
3995
-}
3996
-
3997
-/*
3998
-** File control method. For custom operations on an apnd-file.
3999
-*/
4000
-static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
4001
- ApndFile *paf = (ApndFile *)pFile;
4002
- int rc;
4003
- pFile = ORIGFILE(pFile);
4004
- if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
4005
- rc = pFile->pMethods->xFileControl(pFile, op, pArg);
4006
- if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
4007
- *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
4008
- }
4009
- return rc;
4010
-}
4011
-
4012
-/*
4013
-** Return the sector-size in bytes for an apnd-file.
4014
-*/
4015
-static int apndSectorSize(sqlite3_file *pFile){
4016
- pFile = ORIGFILE(pFile);
4017
- return pFile->pMethods->xSectorSize(pFile);
4018
-}
4019
-
4020
-/*
4021
-** Return the device characteristic flags supported by an apnd-file.
4022
-*/
4023
-static int apndDeviceCharacteristics(sqlite3_file *pFile){
4024
- pFile = ORIGFILE(pFile);
4025
- return pFile->pMethods->xDeviceCharacteristics(pFile);
4026
-}
4027
-
4028
-/* Create a shared memory file mapping */
4029
-static int apndShmMap(
4030
- sqlite3_file *pFile,
4031
- int iPg,
4032
- int pgsz,
4033
- int bExtend,
4034
- void volatile **pp
4035
-){
4036
- pFile = ORIGFILE(pFile);
4037
- return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
4038
-}
4039
-
4040
-/* Perform locking on a shared-memory segment */
4041
-static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
4042
- pFile = ORIGFILE(pFile);
4043
- return pFile->pMethods->xShmLock(pFile,offset,n,flags);
4044
-}
4045
-
4046
-/* Memory barrier operation on shared memory */
4047
-static void apndShmBarrier(sqlite3_file *pFile){
4048
- pFile = ORIGFILE(pFile);
4049
- pFile->pMethods->xShmBarrier(pFile);
4050
-}
4051
-
4052
-/* Unmap a shared memory segment */
4053
-static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
4054
- pFile = ORIGFILE(pFile);
4055
- return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
4056
-}
4057
-
4058
-/* Fetch a page of a memory-mapped file */
4059
-static int apndFetch(
4060
- sqlite3_file *pFile,
4061
- sqlite3_int64 iOfst,
4062
- int iAmt,
4063
- void **pp
4064
-){
4065
- ApndFile *p = (ApndFile *)pFile;
4066
- if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
4067
- return SQLITE_IOERR; /* Cannot read what is not yet there. */
4068
- }
4069
- pFile = ORIGFILE(pFile);
4070
- return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
4071
-}
4072
-
4073
-/* Release a memory-mapped page */
4074
-static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
4075
- ApndFile *p = (ApndFile *)pFile;
4076
- pFile = ORIGFILE(pFile);
4077
- return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
4078
-}
4079
-
4080
-/*
4081
-** Try to read the append-mark off the end of a file. Return the
4082
-** start of the appended database if the append-mark is present.
4083
-** If there is no valid append-mark, return -1;
4084
-**
4085
-** An append-mark is only valid if the NNNNNNNN start-of-database offset
4086
-** indicates that the appended database contains at least one page. The
4087
-** start-of-database value must be a multiple of 512.
4088
-*/
4089
-static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
4090
- int rc, i;
4091
- sqlite3_int64 iMark;
4092
- int msbs = 8 * (APND_MARK_FOS_SZ-1);
4093
- unsigned char a[APND_MARK_SIZE];
4094
-
4095
- if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
4096
- rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
4097
- if( rc ) return -1;
4098
- if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
4099
- iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
4100
- for(i=1; i<8; i++){
4101
- msbs -= 8;
4102
- iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
4103
- }
4104
- if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
4105
- if( iMark & 0x1ff ) return -1;
4106
- return iMark;
4107
-}
4108
-
4109
-static const char apvfsSqliteHdr[] = "SQLite format 3";
4110
-/*
4111
-** Check to see if the file is an appendvfs SQLite database file.
4112
-** Return true iff it is such. Parameter sz is the file's size.
4113
-*/
4114
-static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
4115
- int rc;
4116
- char zHdr[16];
4117
- sqlite3_int64 iMark = apndReadMark(sz, pFile);
4118
- if( iMark>=0 ){
4119
- /* If file has the correct end-marker, the expected odd size, and the
4120
- ** SQLite DB type marker where the end-marker puts it, then it
4121
- ** is an appendvfs database.
4122
- */
4123
- rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
4124
- if( SQLITE_OK==rc
4125
- && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
4126
- && (sz & 0x1ff) == APND_MARK_SIZE
4127
- && sz>=512+APND_MARK_SIZE
4128
- ){
4129
- return 1; /* It's an appendvfs database */
4130
- }
4131
- }
4132
- return 0;
4133
-}
4134
-
4135
-/*
4136
-** Check to see if the file is an ordinary SQLite database file.
4137
-** Return true iff so. Parameter sz is the file's size.
4138
-*/
4139
-static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
4140
- char zHdr[16];
4141
- if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
4142
- || (sz & 0x1ff) != 0
4143
- || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
4144
- || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
4145
- ){
4146
- return 0;
4147
- }else{
4148
- return 1;
4149
- }
4150
-}
4151
-
4152
-/*
4153
-** Open an apnd file handle.
4154
-*/
4155
-static int apndOpen(
4156
- sqlite3_vfs *pApndVfs,
4157
- const char *zName,
4158
- sqlite3_file *pFile,
4159
- int flags,
4160
- int *pOutFlags
4161
-){
4162
- ApndFile *pApndFile = (ApndFile*)pFile;
4163
- sqlite3_file *pBaseFile = ORIGFILE(pFile);
4164
- sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
4165
- int rc;
4166
- sqlite3_int64 sz = 0;
4167
- if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
4168
- /* The appendvfs is not to be used for transient or temporary databases.
4169
- ** Just use the base VFS open to initialize the given file object and
4170
- ** open the underlying file. (Appendvfs is then unused for this file.)
4171
- */
4172
- return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
4173
- }
4174
- memset(pApndFile, 0, sizeof(ApndFile));
4175
- pFile->pMethods = &apnd_io_methods;
4176
- pApndFile->iMark = -1; /* Append mark not yet written */
4177
-
4178
- rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
4179
- if( rc==SQLITE_OK ){
4180
- rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
4181
- if( rc ){
4182
- pBaseFile->pMethods->xClose(pBaseFile);
4183
- }
4184
- }
4185
- if( rc ){
4186
- pFile->pMethods = 0;
4187
- return rc;
4188
- }
4189
- if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
4190
- /* The file being opened appears to be just an ordinary DB. Copy
4191
- ** the base dispatch-table so this instance mimics the base VFS.
4192
- */
4193
- memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
4194
- return SQLITE_OK;
4195
- }
4196
- pApndFile->iPgOne = apndReadMark(sz, pFile);
4197
- if( pApndFile->iPgOne>=0 ){
4198
- pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
4199
- return SQLITE_OK;
4200
- }
4201
- if( (flags & SQLITE_OPEN_CREATE)==0 ){
4202
- pBaseFile->pMethods->xClose(pBaseFile);
4203
- rc = SQLITE_CANTOPEN;
4204
- pFile->pMethods = 0;
4205
- }else{
4206
- /* Round newly added appendvfs location to #define'd page boundary.
4207
- ** Note that nothing has yet been written to the underlying file.
4208
- ** The append mark will be written along with first content write.
4209
- ** Until then, paf->iMark value indicates it is not yet written.
4210
- */
4211
- pApndFile->iPgOne = APND_START_ROUNDUP(sz);
4212
- }
4213
- return rc;
4214
-}
4215
-
4216
-/*
4217
-** Delete an apnd file.
4218
-** For an appendvfs, this could mean delete the appendvfs portion,
4219
-** leaving the appendee as it was before it gained an appendvfs.
4220
-** For now, this code deletes the underlying file too.
4221
-*/
4222
-static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
4223
- return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
4224
-}
4225
-
4226
-/*
4227
-** All other VFS methods are pass-thrus.
4228
-*/
4229
-static int apndAccess(
4230
- sqlite3_vfs *pVfs,
4231
- const char *zPath,
4232
- int flags,
4233
- int *pResOut
4234
-){
4235
- return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
4236
-}
4237
-static int apndFullPathname(
4238
- sqlite3_vfs *pVfs,
4239
- const char *zPath,
4240
- int nOut,
4241
- char *zOut
4242
-){
4243
- return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
4244
-}
4245
-static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
4246
- return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
4247
-}
4248
-static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
4249
- ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
4250
-}
4251
-static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
4252
- return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
4253
-}
4254
-static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
4255
- ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
4256
-}
4257
-static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
4258
- return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
4259
-}
4260
-static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
4261
- return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
4262
-}
4263
-static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
4264
- return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
4265
-}
4266
-static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
4267
- return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
4268
-}
4269
-static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
4270
- return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
4271
-}
4272
-static int apndSetSystemCall(
4273
- sqlite3_vfs *pVfs,
4274
- const char *zName,
4275
- sqlite3_syscall_ptr pCall
4276
-){
4277
- return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
4278
-}
4279
-static sqlite3_syscall_ptr apndGetSystemCall(
4280
- sqlite3_vfs *pVfs,
4281
- const char *zName
4282
-){
4283
- return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
4284
-}
4285
-static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
4286
- return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
4287
-}
4288
-
4289
-
4290
-#ifdef _WIN32
4291
-
4292
-#endif
4293
-/*
4294
-** This routine is called when the extension is loaded.
4295
-** Register the new VFS.
4296
-*/
4297
-int sqlite3_appendvfs_init(
4298
- sqlite3 *db,
4299
- char **pzErrMsg,
4300
- const sqlite3_api_routines *pApi
4301
-){
4302
- int rc = SQLITE_OK;
4303
- sqlite3_vfs *pOrig;
4304
- SQLITE_EXTENSION_INIT2(pApi);
4305
- (void)pzErrMsg;
4306
- (void)db;
4307
- pOrig = sqlite3_vfs_find(0);
4308
- if( pOrig==0 ) return SQLITE_ERROR;
4309
- apnd_vfs.iVersion = pOrig->iVersion;
4310
- apnd_vfs.pAppData = pOrig;
4311
- apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
4312
- rc = sqlite3_vfs_register(&apnd_vfs, 0);
4313
-#ifdef APPENDVFS_TEST
4314
- if( rc==SQLITE_OK ){
4315
- rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
4316
- }
4317
-#endif
4318
- if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
4319
- return rc;
4320
-}
4321
-
4322
-/************************* End ../ext/misc/appendvfs.c ********************/
4323
-/************************* Begin ../ext/misc/memtrace.c ******************/
4324
-/*
4325
-** 2019-01-21
4326
-**
4327
-** The author disclaims copyright to this source code. In place of
4328
-** a legal notice, here is a blessing:
4329
-**
4330
-** May you do good and not evil.
4331
-** May you find forgiveness for yourself and forgive others.
4332
-** May you share freely, never taking more than you give.
4333
-**
4334
-*************************************************************************
4335
-**
4336
-** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
4337
-** mechanism to add a tracing layer on top of SQLite. If this extension
4338
-** is registered prior to sqlite3_initialize(), it will cause all memory
4339
-** allocation activities to be logged on standard output, or to some other
4340
-** FILE specified by the initializer.
4341
-**
4342
-** This file needs to be compiled into the application that uses it.
4343
-**
4344
-** This extension is used to implement the --memtrace option of the
4345
-** command-line shell.
4346
-*/
4347
-#include <assert.h>
4348
-#include <string.h>
4349
-#include <stdio.h>
4350
-
4351
-/* The original memory allocation routines */
4352
-static sqlite3_mem_methods memtraceBase;
4353
-static FILE *memtraceOut;
4354
-
4355
-/* Methods that trace memory allocations */
4356
-static void *memtraceMalloc(int n){
4357
- if( memtraceOut ){
4358
- fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
4359
- memtraceBase.xRoundup(n));
4360
- }
4361
- return memtraceBase.xMalloc(n);
4362
-}
4363
-static void memtraceFree(void *p){
4364
- if( p==0 ) return;
4365
- if( memtraceOut ){
4366
- fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
4367
- }
4368
- memtraceBase.xFree(p);
4369
-}
4370
-static void *memtraceRealloc(void *p, int n){
4371
- if( p==0 ) return memtraceMalloc(n);
4372
- if( n==0 ){
4373
- memtraceFree(p);
4374
- return 0;
4375
- }
4376
- if( memtraceOut ){
4377
- fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
4378
- memtraceBase.xSize(p), memtraceBase.xRoundup(n));
4379
- }
4380
- return memtraceBase.xRealloc(p, n);
4381
-}
4382
-static int memtraceSize(void *p){
4383
- return memtraceBase.xSize(p);
4384
-}
4385
-static int memtraceRoundup(int n){
4386
- return memtraceBase.xRoundup(n);
4387
-}
4388
-static int memtraceInit(void *p){
4389
- return memtraceBase.xInit(p);
4390
-}
4391
-static void memtraceShutdown(void *p){
4392
- memtraceBase.xShutdown(p);
4393
-}
4394
-
4395
-/* The substitute memory allocator */
4396
-static sqlite3_mem_methods ersaztMethods = {
4397
- memtraceMalloc,
4398
- memtraceFree,
4399
- memtraceRealloc,
4400
- memtraceSize,
4401
- memtraceRoundup,
4402
- memtraceInit,
4403
- memtraceShutdown,
4404
- 0
4405
-};
4406
-
4407
-/* Begin tracing memory allocations to out. */
4408
-int sqlite3MemTraceActivate(FILE *out){
4409
- int rc = SQLITE_OK;
4410
- if( memtraceBase.xMalloc==0 ){
4411
- rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
4412
- if( rc==SQLITE_OK ){
4413
- rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
4414
- }
4415
- }
4416
- memtraceOut = out;
4417
- return rc;
4418
-}
4419
-
4420
-/* Deactivate memory tracing */
4421
-int sqlite3MemTraceDeactivate(void){
4422
- int rc = SQLITE_OK;
4423
- if( memtraceBase.xMalloc!=0 ){
4424
- rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
4425
- if( rc==SQLITE_OK ){
4426
- memset(&memtraceBase, 0, sizeof(memtraceBase));
4427
- }
4428
- }
4429
- memtraceOut = 0;
4430
- return rc;
4431
-}
4432
-
4433
-/************************* End ../ext/misc/memtrace.c ********************/
44342233
/************************* Begin ../ext/misc/uint.c ******************/
44352234
/*
44362235
** 2020-04-14
44372236
**
44382237
** The author disclaims copyright to this source code. In place of
@@ -6696,10 +4495,2224 @@
66964495
}
66974496
return rc;
66984497
}
66994498
67004499
/************************* End ../ext/misc/regexp.c ********************/
4500
+#ifndef SQLITE_SHELL_WASM_MODE
4501
+/************************* Begin ../ext/misc/fileio.c ******************/
4502
+/*
4503
+** 2014-06-13
4504
+**
4505
+** The author disclaims copyright to this source code. In place of
4506
+** a legal notice, here is a blessing:
4507
+**
4508
+** May you do good and not evil.
4509
+** May you find forgiveness for yourself and forgive others.
4510
+** May you share freely, never taking more than you give.
4511
+**
4512
+******************************************************************************
4513
+**
4514
+** This SQLite extension implements SQL functions readfile() and
4515
+** writefile(), and eponymous virtual type "fsdir".
4516
+**
4517
+** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
4518
+**
4519
+** If neither of the optional arguments is present, then this UDF
4520
+** function writes blob DATA to file FILE. If successful, the number
4521
+** of bytes written is returned. If an error occurs, NULL is returned.
4522
+**
4523
+** If the first option argument - MODE - is present, then it must
4524
+** be passed an integer value that corresponds to a POSIX mode
4525
+** value (file type + permissions, as returned in the stat.st_mode
4526
+** field by the stat() system call). Three types of files may
4527
+** be written/created:
4528
+**
4529
+** regular files: (mode & 0170000)==0100000
4530
+** symbolic links: (mode & 0170000)==0120000
4531
+** directories: (mode & 0170000)==0040000
4532
+**
4533
+** For a directory, the DATA is ignored. For a symbolic link, it is
4534
+** interpreted as text and used as the target of the link. For a
4535
+** regular file, it is interpreted as a blob and written into the
4536
+** named file. Regardless of the type of file, its permissions are
4537
+** set to (mode & 0777) before returning.
4538
+**
4539
+** If the optional MTIME argument is present, then it is interpreted
4540
+** as an integer - the number of seconds since the unix epoch. The
4541
+** modification-time of the target file is set to this value before
4542
+** returning.
4543
+**
4544
+** If three or more arguments are passed to this function and an
4545
+** error is encountered, an exception is raised.
4546
+**
4547
+** READFILE(FILE):
4548
+**
4549
+** Read and return the contents of file FILE (type blob) from disk.
4550
+**
4551
+** FSDIR:
4552
+**
4553
+** Used as follows:
4554
+**
4555
+** SELECT * FROM fsdir($path [, $dir]);
4556
+**
4557
+** Parameter $path is an absolute or relative pathname. If the file that it
4558
+** refers to does not exist, it is an error. If the path refers to a regular
4559
+** file or symbolic link, it returns a single row. Or, if the path refers
4560
+** to a directory, it returns one row for the directory, and one row for each
4561
+** file within the hierarchy rooted at $path.
4562
+**
4563
+** Each row has the following columns:
4564
+**
4565
+** name: Path to file or directory (text value).
4566
+** mode: Value of stat.st_mode for directory entry (an integer).
4567
+** mtime: Value of stat.st_mtime for directory entry (an integer).
4568
+** data: For a regular file, a blob containing the file data. For a
4569
+** symlink, a text value containing the text of the link. For a
4570
+** directory, NULL.
4571
+**
4572
+** If a non-NULL value is specified for the optional $dir parameter and
4573
+** $path is a relative path, then $path is interpreted relative to $dir.
4574
+** And the paths returned in the "name" column of the table are also
4575
+** relative to directory $dir.
4576
+**
4577
+** Notes on building this extension for Windows:
4578
+** Unless linked statically with the SQLite library, a preprocessor
4579
+** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
4580
+** DLL form of this extension for WIN32. See its use below for details.
4581
+*/
4582
+/* #include "sqlite3ext.h" */
4583
+SQLITE_EXTENSION_INIT1
4584
+#include <stdio.h>
4585
+#include <string.h>
4586
+#include <assert.h>
4587
+
4588
+#include <sys/types.h>
4589
+#include <sys/stat.h>
4590
+#include <fcntl.h>
4591
+#if !defined(_WIN32) && !defined(WIN32)
4592
+# include <unistd.h>
4593
+# include <dirent.h>
4594
+# include <utime.h>
4595
+# include <sys/time.h>
4596
+#else
4597
+# include "windows.h"
4598
+# include <io.h>
4599
+# include <direct.h>
4600
+/* # include "test_windirent.h" */
4601
+# define dirent DIRENT
4602
+# ifndef chmod
4603
+# define chmod _chmod
4604
+# endif
4605
+# ifndef stat
4606
+# define stat _stat
4607
+# endif
4608
+# define mkdir(path,mode) _mkdir(path)
4609
+# define lstat(path,buf) stat(path,buf)
4610
+#endif
4611
+#include <time.h>
4612
+#include <errno.h>
4613
+
4614
+
4615
+/*
4616
+** Structure of the fsdir() table-valued function
4617
+*/
4618
+ /* 0 1 2 3 4 5 */
4619
+#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
4620
+#define FSDIR_COLUMN_NAME 0 /* Name of the file */
4621
+#define FSDIR_COLUMN_MODE 1 /* Access mode */
4622
+#define FSDIR_COLUMN_MTIME 2 /* Last modification time */
4623
+#define FSDIR_COLUMN_DATA 3 /* File content */
4624
+#define FSDIR_COLUMN_PATH 4 /* Path to top of search */
4625
+#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
4626
+
4627
+
4628
+/*
4629
+** Set the result stored by context ctx to a blob containing the
4630
+** contents of file zName. Or, leave the result unchanged (NULL)
4631
+** if the file does not exist or is unreadable.
4632
+**
4633
+** If the file exceeds the SQLite blob size limit, through an
4634
+** SQLITE_TOOBIG error.
4635
+**
4636
+** Throw an SQLITE_IOERR if there are difficulties pulling the file
4637
+** off of disk.
4638
+*/
4639
+static void readFileContents(sqlite3_context *ctx, const char *zName){
4640
+ FILE *in;
4641
+ sqlite3_int64 nIn;
4642
+ void *pBuf;
4643
+ sqlite3 *db;
4644
+ int mxBlob;
4645
+
4646
+ in = fopen(zName, "rb");
4647
+ if( in==0 ){
4648
+ /* File does not exist or is unreadable. Leave the result set to NULL. */
4649
+ return;
4650
+ }
4651
+ fseek(in, 0, SEEK_END);
4652
+ nIn = ftell(in);
4653
+ rewind(in);
4654
+ db = sqlite3_context_db_handle(ctx);
4655
+ mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
4656
+ if( nIn>mxBlob ){
4657
+ sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
4658
+ fclose(in);
4659
+ return;
4660
+ }
4661
+ pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
4662
+ if( pBuf==0 ){
4663
+ sqlite3_result_error_nomem(ctx);
4664
+ fclose(in);
4665
+ return;
4666
+ }
4667
+ if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
4668
+ sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
4669
+ }else{
4670
+ sqlite3_result_error_code(ctx, SQLITE_IOERR);
4671
+ sqlite3_free(pBuf);
4672
+ }
4673
+ fclose(in);
4674
+}
4675
+
4676
+/*
4677
+** Implementation of the "readfile(X)" SQL function. The entire content
4678
+** of the file named X is read and returned as a BLOB. NULL is returned
4679
+** if the file does not exist or is unreadable.
4680
+*/
4681
+static void readfileFunc(
4682
+ sqlite3_context *context,
4683
+ int argc,
4684
+ sqlite3_value **argv
4685
+){
4686
+ const char *zName;
4687
+ (void)(argc); /* Unused parameter */
4688
+ zName = (const char*)sqlite3_value_text(argv[0]);
4689
+ if( zName==0 ) return;
4690
+ readFileContents(context, zName);
4691
+}
4692
+
4693
+/*
4694
+** Set the error message contained in context ctx to the results of
4695
+** vprintf(zFmt, ...).
4696
+*/
4697
+static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
4698
+ char *zMsg = 0;
4699
+ va_list ap;
4700
+ va_start(ap, zFmt);
4701
+ zMsg = sqlite3_vmprintf(zFmt, ap);
4702
+ sqlite3_result_error(ctx, zMsg, -1);
4703
+ sqlite3_free(zMsg);
4704
+ va_end(ap);
4705
+}
4706
+
4707
+#if defined(_WIN32)
4708
+/*
4709
+** This function is designed to convert a Win32 FILETIME structure into the
4710
+** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
4711
+*/
4712
+static sqlite3_uint64 fileTimeToUnixTime(
4713
+ LPFILETIME pFileTime
4714
+){
4715
+ SYSTEMTIME epochSystemTime;
4716
+ ULARGE_INTEGER epochIntervals;
4717
+ FILETIME epochFileTime;
4718
+ ULARGE_INTEGER fileIntervals;
4719
+
4720
+ memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
4721
+ epochSystemTime.wYear = 1970;
4722
+ epochSystemTime.wMonth = 1;
4723
+ epochSystemTime.wDay = 1;
4724
+ SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
4725
+ epochIntervals.LowPart = epochFileTime.dwLowDateTime;
4726
+ epochIntervals.HighPart = epochFileTime.dwHighDateTime;
4727
+
4728
+ fileIntervals.LowPart = pFileTime->dwLowDateTime;
4729
+ fileIntervals.HighPart = pFileTime->dwHighDateTime;
4730
+
4731
+ return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
4732
+}
4733
+
4734
+
4735
+#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
4736
+# /* To allow a standalone DLL, use this next replacement function: */
4737
+# undef sqlite3_win32_utf8_to_unicode
4738
+# define sqlite3_win32_utf8_to_unicode utf8_to_utf16
4739
+#
4740
+LPWSTR utf8_to_utf16(const char *z){
4741
+ int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
4742
+ LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
4743
+ if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
4744
+ return rv;
4745
+ sqlite3_free(rv);
4746
+ return 0;
4747
+}
4748
+#endif
4749
+
4750
+/*
4751
+** This function attempts to normalize the time values found in the stat()
4752
+** buffer to UTC. This is necessary on Win32, where the runtime library
4753
+** appears to return these values as local times.
4754
+*/
4755
+static void statTimesToUtc(
4756
+ const char *zPath,
4757
+ struct stat *pStatBuf
4758
+){
4759
+ HANDLE hFindFile;
4760
+ WIN32_FIND_DATAW fd;
4761
+ LPWSTR zUnicodeName;
4762
+ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
4763
+ zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
4764
+ if( zUnicodeName ){
4765
+ memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
4766
+ hFindFile = FindFirstFileW(zUnicodeName, &fd);
4767
+ if( hFindFile!=NULL ){
4768
+ pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
4769
+ pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
4770
+ pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
4771
+ FindClose(hFindFile);
4772
+ }
4773
+ sqlite3_free(zUnicodeName);
4774
+ }
4775
+}
4776
+#endif
4777
+
4778
+/*
4779
+** This function is used in place of stat(). On Windows, special handling
4780
+** is required in order for the included time to be returned as UTC. On all
4781
+** other systems, this function simply calls stat().
4782
+*/
4783
+static int fileStat(
4784
+ const char *zPath,
4785
+ struct stat *pStatBuf
4786
+){
4787
+#if defined(_WIN32)
4788
+ int rc = stat(zPath, pStatBuf);
4789
+ if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
4790
+ return rc;
4791
+#else
4792
+ return stat(zPath, pStatBuf);
4793
+#endif
4794
+}
4795
+
4796
+/*
4797
+** This function is used in place of lstat(). On Windows, special handling
4798
+** is required in order for the included time to be returned as UTC. On all
4799
+** other systems, this function simply calls lstat().
4800
+*/
4801
+static int fileLinkStat(
4802
+ const char *zPath,
4803
+ struct stat *pStatBuf
4804
+){
4805
+#if defined(_WIN32)
4806
+ int rc = lstat(zPath, pStatBuf);
4807
+ if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
4808
+ return rc;
4809
+#else
4810
+ return lstat(zPath, pStatBuf);
4811
+#endif
4812
+}
4813
+
4814
+/*
4815
+** Argument zFile is the name of a file that will be created and/or written
4816
+** by SQL function writefile(). This function ensures that the directory
4817
+** zFile will be written to exists, creating it if required. The permissions
4818
+** for any path components created by this function are set in accordance
4819
+** with the current umask.
4820
+**
4821
+** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
4822
+** SQLITE_OK is returned if the directory is successfully created, or
4823
+** SQLITE_ERROR otherwise.
4824
+*/
4825
+static int makeDirectory(
4826
+ const char *zFile
4827
+){
4828
+ char *zCopy = sqlite3_mprintf("%s", zFile);
4829
+ int rc = SQLITE_OK;
4830
+
4831
+ if( zCopy==0 ){
4832
+ rc = SQLITE_NOMEM;
4833
+ }else{
4834
+ int nCopy = (int)strlen(zCopy);
4835
+ int i = 1;
4836
+
4837
+ while( rc==SQLITE_OK ){
4838
+ struct stat sStat;
4839
+ int rc2;
4840
+
4841
+ for(; zCopy[i]!='/' && i<nCopy; i++);
4842
+ if( i==nCopy ) break;
4843
+ zCopy[i] = '\0';
4844
+
4845
+ rc2 = fileStat(zCopy, &sStat);
4846
+ if( rc2!=0 ){
4847
+ if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
4848
+ }else{
4849
+ if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
4850
+ }
4851
+ zCopy[i] = '/';
4852
+ i++;
4853
+ }
4854
+
4855
+ sqlite3_free(zCopy);
4856
+ }
4857
+
4858
+ return rc;
4859
+}
4860
+
4861
+/*
4862
+** This function does the work for the writefile() UDF. Refer to
4863
+** header comments at the top of this file for details.
4864
+*/
4865
+static int writeFile(
4866
+ sqlite3_context *pCtx, /* Context to return bytes written in */
4867
+ const char *zFile, /* File to write */
4868
+ sqlite3_value *pData, /* Data to write */
4869
+ mode_t mode, /* MODE parameter passed to writefile() */
4870
+ sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */
4871
+){
4872
+ if( zFile==0 ) return 1;
4873
+#if !defined(_WIN32) && !defined(WIN32)
4874
+ if( S_ISLNK(mode) ){
4875
+ const char *zTo = (const char*)sqlite3_value_text(pData);
4876
+ if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
4877
+ }else
4878
+#endif
4879
+ {
4880
+ if( S_ISDIR(mode) ){
4881
+ if( mkdir(zFile, mode) ){
4882
+ /* The mkdir() call to create the directory failed. This might not
4883
+ ** be an error though - if there is already a directory at the same
4884
+ ** path and either the permissions already match or can be changed
4885
+ ** to do so using chmod(), it is not an error. */
4886
+ struct stat sStat;
4887
+ if( errno!=EEXIST
4888
+ || 0!=fileStat(zFile, &sStat)
4889
+ || !S_ISDIR(sStat.st_mode)
4890
+ || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
4891
+ ){
4892
+ return 1;
4893
+ }
4894
+ }
4895
+ }else{
4896
+ sqlite3_int64 nWrite = 0;
4897
+ const char *z;
4898
+ int rc = 0;
4899
+ FILE *out = fopen(zFile, "wb");
4900
+ if( out==0 ) return 1;
4901
+ z = (const char*)sqlite3_value_blob(pData);
4902
+ if( z ){
4903
+ sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
4904
+ nWrite = sqlite3_value_bytes(pData);
4905
+ if( nWrite!=n ){
4906
+ rc = 1;
4907
+ }
4908
+ }
4909
+ fclose(out);
4910
+ if( rc==0 && mode && chmod(zFile, mode & 0777) ){
4911
+ rc = 1;
4912
+ }
4913
+ if( rc ) return 2;
4914
+ sqlite3_result_int64(pCtx, nWrite);
4915
+ }
4916
+ }
4917
+
4918
+ if( mtime>=0 ){
4919
+#if defined(_WIN32)
4920
+#if !SQLITE_OS_WINRT
4921
+ /* Windows */
4922
+ FILETIME lastAccess;
4923
+ FILETIME lastWrite;
4924
+ SYSTEMTIME currentTime;
4925
+ LONGLONG intervals;
4926
+ HANDLE hFile;
4927
+ LPWSTR zUnicodeName;
4928
+ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
4929
+
4930
+ GetSystemTime(&currentTime);
4931
+ SystemTimeToFileTime(&currentTime, &lastAccess);
4932
+ intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
4933
+ lastWrite.dwLowDateTime = (DWORD)intervals;
4934
+ lastWrite.dwHighDateTime = intervals >> 32;
4935
+ zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
4936
+ if( zUnicodeName==0 ){
4937
+ return 1;
4938
+ }
4939
+ hFile = CreateFileW(
4940
+ zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
4941
+ FILE_FLAG_BACKUP_SEMANTICS, NULL
4942
+ );
4943
+ sqlite3_free(zUnicodeName);
4944
+ if( hFile!=INVALID_HANDLE_VALUE ){
4945
+ BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
4946
+ CloseHandle(hFile);
4947
+ return !bResult;
4948
+ }else{
4949
+ return 1;
4950
+ }
4951
+#endif
4952
+#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
4953
+ /* Recent unix */
4954
+ struct timespec times[2];
4955
+ times[0].tv_nsec = times[1].tv_nsec = 0;
4956
+ times[0].tv_sec = time(0);
4957
+ times[1].tv_sec = mtime;
4958
+ if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
4959
+ return 1;
4960
+ }
4961
+#else
4962
+ /* Legacy unix */
4963
+ struct timeval times[2];
4964
+ times[0].tv_usec = times[1].tv_usec = 0;
4965
+ times[0].tv_sec = time(0);
4966
+ times[1].tv_sec = mtime;
4967
+ if( utimes(zFile, times) ){
4968
+ return 1;
4969
+ }
4970
+#endif
4971
+ }
4972
+
4973
+ return 0;
4974
+}
4975
+
4976
+/*
4977
+** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
4978
+** Refer to header comments at the top of this file for details.
4979
+*/
4980
+static void writefileFunc(
4981
+ sqlite3_context *context,
4982
+ int argc,
4983
+ sqlite3_value **argv
4984
+){
4985
+ const char *zFile;
4986
+ mode_t mode = 0;
4987
+ int res;
4988
+ sqlite3_int64 mtime = -1;
4989
+
4990
+ if( argc<2 || argc>4 ){
4991
+ sqlite3_result_error(context,
4992
+ "wrong number of arguments to function writefile()", -1
4993
+ );
4994
+ return;
4995
+ }
4996
+
4997
+ zFile = (const char*)sqlite3_value_text(argv[0]);
4998
+ if( zFile==0 ) return;
4999
+ if( argc>=3 ){
5000
+ mode = (mode_t)sqlite3_value_int(argv[2]);
5001
+ }
5002
+ if( argc==4 ){
5003
+ mtime = sqlite3_value_int64(argv[3]);
5004
+ }
5005
+
5006
+ res = writeFile(context, zFile, argv[1], mode, mtime);
5007
+ if( res==1 && errno==ENOENT ){
5008
+ if( makeDirectory(zFile)==SQLITE_OK ){
5009
+ res = writeFile(context, zFile, argv[1], mode, mtime);
5010
+ }
5011
+ }
5012
+
5013
+ if( argc>2 && res!=0 ){
5014
+ if( S_ISLNK(mode) ){
5015
+ ctxErrorMsg(context, "failed to create symlink: %s", zFile);
5016
+ }else if( S_ISDIR(mode) ){
5017
+ ctxErrorMsg(context, "failed to create directory: %s", zFile);
5018
+ }else{
5019
+ ctxErrorMsg(context, "failed to write file: %s", zFile);
5020
+ }
5021
+ }
5022
+}
5023
+
5024
+/*
5025
+** SQL function: lsmode(MODE)
5026
+**
5027
+** Given a numberic st_mode from stat(), convert it into a human-readable
5028
+** text string in the style of "ls -l".
5029
+*/
5030
+static void lsModeFunc(
5031
+ sqlite3_context *context,
5032
+ int argc,
5033
+ sqlite3_value **argv
5034
+){
5035
+ int i;
5036
+ int iMode = sqlite3_value_int(argv[0]);
5037
+ char z[16];
5038
+ (void)argc;
5039
+ if( S_ISLNK(iMode) ){
5040
+ z[0] = 'l';
5041
+ }else if( S_ISREG(iMode) ){
5042
+ z[0] = '-';
5043
+ }else if( S_ISDIR(iMode) ){
5044
+ z[0] = 'd';
5045
+ }else{
5046
+ z[0] = '?';
5047
+ }
5048
+ for(i=0; i<3; i++){
5049
+ int m = (iMode >> ((2-i)*3));
5050
+ char *a = &z[1 + i*3];
5051
+ a[0] = (m & 0x4) ? 'r' : '-';
5052
+ a[1] = (m & 0x2) ? 'w' : '-';
5053
+ a[2] = (m & 0x1) ? 'x' : '-';
5054
+ }
5055
+ z[10] = '\0';
5056
+ sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
5057
+}
5058
+
5059
+#ifndef SQLITE_OMIT_VIRTUALTABLE
5060
+
5061
+/*
5062
+** Cursor type for recursively iterating through a directory structure.
5063
+*/
5064
+typedef struct fsdir_cursor fsdir_cursor;
5065
+typedef struct FsdirLevel FsdirLevel;
5066
+
5067
+struct FsdirLevel {
5068
+ DIR *pDir; /* From opendir() */
5069
+ char *zDir; /* Name of directory (nul-terminated) */
5070
+};
5071
+
5072
+struct fsdir_cursor {
5073
+ sqlite3_vtab_cursor base; /* Base class - must be first */
5074
+
5075
+ int nLvl; /* Number of entries in aLvl[] array */
5076
+ int iLvl; /* Index of current entry */
5077
+ FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
5078
+
5079
+ const char *zBase;
5080
+ int nBase;
5081
+
5082
+ struct stat sStat; /* Current lstat() results */
5083
+ char *zPath; /* Path to current entry */
5084
+ sqlite3_int64 iRowid; /* Current rowid */
5085
+};
5086
+
5087
+typedef struct fsdir_tab fsdir_tab;
5088
+struct fsdir_tab {
5089
+ sqlite3_vtab base; /* Base class - must be first */
5090
+};
5091
+
5092
+/*
5093
+** Construct a new fsdir virtual table object.
5094
+*/
5095
+static int fsdirConnect(
5096
+ sqlite3 *db,
5097
+ void *pAux,
5098
+ int argc, const char *const*argv,
5099
+ sqlite3_vtab **ppVtab,
5100
+ char **pzErr
5101
+){
5102
+ fsdir_tab *pNew = 0;
5103
+ int rc;
5104
+ (void)pAux;
5105
+ (void)argc;
5106
+ (void)argv;
5107
+ (void)pzErr;
5108
+ rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
5109
+ if( rc==SQLITE_OK ){
5110
+ pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
5111
+ if( pNew==0 ) return SQLITE_NOMEM;
5112
+ memset(pNew, 0, sizeof(*pNew));
5113
+ sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
5114
+ }
5115
+ *ppVtab = (sqlite3_vtab*)pNew;
5116
+ return rc;
5117
+}
5118
+
5119
+/*
5120
+** This method is the destructor for fsdir vtab objects.
5121
+*/
5122
+static int fsdirDisconnect(sqlite3_vtab *pVtab){
5123
+ sqlite3_free(pVtab);
5124
+ return SQLITE_OK;
5125
+}
5126
+
5127
+/*
5128
+** Constructor for a new fsdir_cursor object.
5129
+*/
5130
+static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
5131
+ fsdir_cursor *pCur;
5132
+ (void)p;
5133
+ pCur = sqlite3_malloc( sizeof(*pCur) );
5134
+ if( pCur==0 ) return SQLITE_NOMEM;
5135
+ memset(pCur, 0, sizeof(*pCur));
5136
+ pCur->iLvl = -1;
5137
+ *ppCursor = &pCur->base;
5138
+ return SQLITE_OK;
5139
+}
5140
+
5141
+/*
5142
+** Reset a cursor back to the state it was in when first returned
5143
+** by fsdirOpen().
5144
+*/
5145
+static void fsdirResetCursor(fsdir_cursor *pCur){
5146
+ int i;
5147
+ for(i=0; i<=pCur->iLvl; i++){
5148
+ FsdirLevel *pLvl = &pCur->aLvl[i];
5149
+ if( pLvl->pDir ) closedir(pLvl->pDir);
5150
+ sqlite3_free(pLvl->zDir);
5151
+ }
5152
+ sqlite3_free(pCur->zPath);
5153
+ sqlite3_free(pCur->aLvl);
5154
+ pCur->aLvl = 0;
5155
+ pCur->zPath = 0;
5156
+ pCur->zBase = 0;
5157
+ pCur->nBase = 0;
5158
+ pCur->nLvl = 0;
5159
+ pCur->iLvl = -1;
5160
+ pCur->iRowid = 1;
5161
+}
5162
+
5163
+/*
5164
+** Destructor for an fsdir_cursor.
5165
+*/
5166
+static int fsdirClose(sqlite3_vtab_cursor *cur){
5167
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
5168
+
5169
+ fsdirResetCursor(pCur);
5170
+ sqlite3_free(pCur);
5171
+ return SQLITE_OK;
5172
+}
5173
+
5174
+/*
5175
+** Set the error message for the virtual table associated with cursor
5176
+** pCur to the results of vprintf(zFmt, ...).
5177
+*/
5178
+static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
5179
+ va_list ap;
5180
+ va_start(ap, zFmt);
5181
+ pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
5182
+ va_end(ap);
5183
+}
5184
+
5185
+
5186
+/*
5187
+** Advance an fsdir_cursor to its next row of output.
5188
+*/
5189
+static int fsdirNext(sqlite3_vtab_cursor *cur){
5190
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
5191
+ mode_t m = pCur->sStat.st_mode;
5192
+
5193
+ pCur->iRowid++;
5194
+ if( S_ISDIR(m) ){
5195
+ /* Descend into this directory */
5196
+ int iNew = pCur->iLvl + 1;
5197
+ FsdirLevel *pLvl;
5198
+ if( iNew>=pCur->nLvl ){
5199
+ int nNew = iNew+1;
5200
+ sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
5201
+ FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
5202
+ if( aNew==0 ) return SQLITE_NOMEM;
5203
+ memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
5204
+ pCur->aLvl = aNew;
5205
+ pCur->nLvl = nNew;
5206
+ }
5207
+ pCur->iLvl = iNew;
5208
+ pLvl = &pCur->aLvl[iNew];
5209
+
5210
+ pLvl->zDir = pCur->zPath;
5211
+ pCur->zPath = 0;
5212
+ pLvl->pDir = opendir(pLvl->zDir);
5213
+ if( pLvl->pDir==0 ){
5214
+ fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
5215
+ return SQLITE_ERROR;
5216
+ }
5217
+ }
5218
+
5219
+ while( pCur->iLvl>=0 ){
5220
+ FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
5221
+ struct dirent *pEntry = readdir(pLvl->pDir);
5222
+ if( pEntry ){
5223
+ if( pEntry->d_name[0]=='.' ){
5224
+ if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
5225
+ if( pEntry->d_name[1]=='\0' ) continue;
5226
+ }
5227
+ sqlite3_free(pCur->zPath);
5228
+ pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
5229
+ if( pCur->zPath==0 ) return SQLITE_NOMEM;
5230
+ if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
5231
+ fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
5232
+ return SQLITE_ERROR;
5233
+ }
5234
+ return SQLITE_OK;
5235
+ }
5236
+ closedir(pLvl->pDir);
5237
+ sqlite3_free(pLvl->zDir);
5238
+ pLvl->pDir = 0;
5239
+ pLvl->zDir = 0;
5240
+ pCur->iLvl--;
5241
+ }
5242
+
5243
+ /* EOF */
5244
+ sqlite3_free(pCur->zPath);
5245
+ pCur->zPath = 0;
5246
+ return SQLITE_OK;
5247
+}
5248
+
5249
+/*
5250
+** Return values of columns for the row at which the series_cursor
5251
+** is currently pointing.
5252
+*/
5253
+static int fsdirColumn(
5254
+ sqlite3_vtab_cursor *cur, /* The cursor */
5255
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
5256
+ int i /* Which column to return */
5257
+){
5258
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
5259
+ switch( i ){
5260
+ case FSDIR_COLUMN_NAME: {
5261
+ sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
5262
+ break;
5263
+ }
5264
+
5265
+ case FSDIR_COLUMN_MODE:
5266
+ sqlite3_result_int64(ctx, pCur->sStat.st_mode);
5267
+ break;
5268
+
5269
+ case FSDIR_COLUMN_MTIME:
5270
+ sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
5271
+ break;
5272
+
5273
+ case FSDIR_COLUMN_DATA: {
5274
+ mode_t m = pCur->sStat.st_mode;
5275
+ if( S_ISDIR(m) ){
5276
+ sqlite3_result_null(ctx);
5277
+#if !defined(_WIN32) && !defined(WIN32)
5278
+ }else if( S_ISLNK(m) ){
5279
+ char aStatic[64];
5280
+ char *aBuf = aStatic;
5281
+ sqlite3_int64 nBuf = 64;
5282
+ int n;
5283
+
5284
+ while( 1 ){
5285
+ n = readlink(pCur->zPath, aBuf, nBuf);
5286
+ if( n<nBuf ) break;
5287
+ if( aBuf!=aStatic ) sqlite3_free(aBuf);
5288
+ nBuf = nBuf*2;
5289
+ aBuf = sqlite3_malloc64(nBuf);
5290
+ if( aBuf==0 ){
5291
+ sqlite3_result_error_nomem(ctx);
5292
+ return SQLITE_NOMEM;
5293
+ }
5294
+ }
5295
+
5296
+ sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
5297
+ if( aBuf!=aStatic ) sqlite3_free(aBuf);
5298
+#endif
5299
+ }else{
5300
+ readFileContents(ctx, pCur->zPath);
5301
+ }
5302
+ }
5303
+ case FSDIR_COLUMN_PATH:
5304
+ default: {
5305
+ /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
5306
+ ** always return their values as NULL */
5307
+ break;
5308
+ }
5309
+ }
5310
+ return SQLITE_OK;
5311
+}
5312
+
5313
+/*
5314
+** Return the rowid for the current row. In this implementation, the
5315
+** first row returned is assigned rowid value 1, and each subsequent
5316
+** row a value 1 more than that of the previous.
5317
+*/
5318
+static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
5319
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
5320
+ *pRowid = pCur->iRowid;
5321
+ return SQLITE_OK;
5322
+}
5323
+
5324
+/*
5325
+** Return TRUE if the cursor has been moved off of the last
5326
+** row of output.
5327
+*/
5328
+static int fsdirEof(sqlite3_vtab_cursor *cur){
5329
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
5330
+ return (pCur->zPath==0);
5331
+}
5332
+
5333
+/*
5334
+** xFilter callback.
5335
+**
5336
+** idxNum==1 PATH parameter only
5337
+** idxNum==2 Both PATH and DIR supplied
5338
+*/
5339
+static int fsdirFilter(
5340
+ sqlite3_vtab_cursor *cur,
5341
+ int idxNum, const char *idxStr,
5342
+ int argc, sqlite3_value **argv
5343
+){
5344
+ const char *zDir = 0;
5345
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
5346
+ (void)idxStr;
5347
+ fsdirResetCursor(pCur);
5348
+
5349
+ if( idxNum==0 ){
5350
+ fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
5351
+ return SQLITE_ERROR;
5352
+ }
5353
+
5354
+ assert( argc==idxNum && (argc==1 || argc==2) );
5355
+ zDir = (const char*)sqlite3_value_text(argv[0]);
5356
+ if( zDir==0 ){
5357
+ fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
5358
+ return SQLITE_ERROR;
5359
+ }
5360
+ if( argc==2 ){
5361
+ pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
5362
+ }
5363
+ if( pCur->zBase ){
5364
+ pCur->nBase = (int)strlen(pCur->zBase)+1;
5365
+ pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
5366
+ }else{
5367
+ pCur->zPath = sqlite3_mprintf("%s", zDir);
5368
+ }
5369
+
5370
+ if( pCur->zPath==0 ){
5371
+ return SQLITE_NOMEM;
5372
+ }
5373
+ if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
5374
+ fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
5375
+ return SQLITE_ERROR;
5376
+ }
5377
+
5378
+ return SQLITE_OK;
5379
+}
5380
+
5381
+/*
5382
+** SQLite will invoke this method one or more times while planning a query
5383
+** that uses the generate_series virtual table. This routine needs to create
5384
+** a query plan for each invocation and compute an estimated cost for that
5385
+** plan.
5386
+**
5387
+** In this implementation idxNum is used to represent the
5388
+** query plan. idxStr is unused.
5389
+**
5390
+** The query plan is represented by values of idxNum:
5391
+**
5392
+** (1) The path value is supplied by argv[0]
5393
+** (2) Path is in argv[0] and dir is in argv[1]
5394
+*/
5395
+static int fsdirBestIndex(
5396
+ sqlite3_vtab *tab,
5397
+ sqlite3_index_info *pIdxInfo
5398
+){
5399
+ int i; /* Loop over constraints */
5400
+ int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
5401
+ int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
5402
+ int seenPath = 0; /* True if an unusable PATH= constraint is seen */
5403
+ int seenDir = 0; /* True if an unusable DIR= constraint is seen */
5404
+ const struct sqlite3_index_constraint *pConstraint;
5405
+
5406
+ (void)tab;
5407
+ pConstraint = pIdxInfo->aConstraint;
5408
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
5409
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
5410
+ switch( pConstraint->iColumn ){
5411
+ case FSDIR_COLUMN_PATH: {
5412
+ if( pConstraint->usable ){
5413
+ idxPath = i;
5414
+ seenPath = 0;
5415
+ }else if( idxPath<0 ){
5416
+ seenPath = 1;
5417
+ }
5418
+ break;
5419
+ }
5420
+ case FSDIR_COLUMN_DIR: {
5421
+ if( pConstraint->usable ){
5422
+ idxDir = i;
5423
+ seenDir = 0;
5424
+ }else if( idxDir<0 ){
5425
+ seenDir = 1;
5426
+ }
5427
+ break;
5428
+ }
5429
+ }
5430
+ }
5431
+ if( seenPath || seenDir ){
5432
+ /* If input parameters are unusable, disallow this plan */
5433
+ return SQLITE_CONSTRAINT;
5434
+ }
5435
+
5436
+ if( idxPath<0 ){
5437
+ pIdxInfo->idxNum = 0;
5438
+ /* The pIdxInfo->estimatedCost should have been initialized to a huge
5439
+ ** number. Leave it unchanged. */
5440
+ pIdxInfo->estimatedRows = 0x7fffffff;
5441
+ }else{
5442
+ pIdxInfo->aConstraintUsage[idxPath].omit = 1;
5443
+ pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
5444
+ if( idxDir>=0 ){
5445
+ pIdxInfo->aConstraintUsage[idxDir].omit = 1;
5446
+ pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
5447
+ pIdxInfo->idxNum = 2;
5448
+ pIdxInfo->estimatedCost = 10.0;
5449
+ }else{
5450
+ pIdxInfo->idxNum = 1;
5451
+ pIdxInfo->estimatedCost = 100.0;
5452
+ }
5453
+ }
5454
+
5455
+ return SQLITE_OK;
5456
+}
5457
+
5458
+/*
5459
+** Register the "fsdir" virtual table.
5460
+*/
5461
+static int fsdirRegister(sqlite3 *db){
5462
+ static sqlite3_module fsdirModule = {
5463
+ 0, /* iVersion */
5464
+ 0, /* xCreate */
5465
+ fsdirConnect, /* xConnect */
5466
+ fsdirBestIndex, /* xBestIndex */
5467
+ fsdirDisconnect, /* xDisconnect */
5468
+ 0, /* xDestroy */
5469
+ fsdirOpen, /* xOpen - open a cursor */
5470
+ fsdirClose, /* xClose - close a cursor */
5471
+ fsdirFilter, /* xFilter - configure scan constraints */
5472
+ fsdirNext, /* xNext - advance a cursor */
5473
+ fsdirEof, /* xEof - check for end of scan */
5474
+ fsdirColumn, /* xColumn - read data */
5475
+ fsdirRowid, /* xRowid - read data */
5476
+ 0, /* xUpdate */
5477
+ 0, /* xBegin */
5478
+ 0, /* xSync */
5479
+ 0, /* xCommit */
5480
+ 0, /* xRollback */
5481
+ 0, /* xFindMethod */
5482
+ 0, /* xRename */
5483
+ 0, /* xSavepoint */
5484
+ 0, /* xRelease */
5485
+ 0, /* xRollbackTo */
5486
+ 0, /* xShadowName */
5487
+ };
5488
+
5489
+ int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
5490
+ return rc;
5491
+}
5492
+#else /* SQLITE_OMIT_VIRTUALTABLE */
5493
+# define fsdirRegister(x) SQLITE_OK
5494
+#endif
5495
+
5496
+#ifdef _WIN32
5497
+
5498
+#endif
5499
+int sqlite3_fileio_init(
5500
+ sqlite3 *db,
5501
+ char **pzErrMsg,
5502
+ const sqlite3_api_routines *pApi
5503
+){
5504
+ int rc = SQLITE_OK;
5505
+ SQLITE_EXTENSION_INIT2(pApi);
5506
+ (void)pzErrMsg; /* Unused parameter */
5507
+ rc = sqlite3_create_function(db, "readfile", 1,
5508
+ SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
5509
+ readfileFunc, 0, 0);
5510
+ if( rc==SQLITE_OK ){
5511
+ rc = sqlite3_create_function(db, "writefile", -1,
5512
+ SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
5513
+ writefileFunc, 0, 0);
5514
+ }
5515
+ if( rc==SQLITE_OK ){
5516
+ rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
5517
+ lsModeFunc, 0, 0);
5518
+ }
5519
+ if( rc==SQLITE_OK ){
5520
+ rc = fsdirRegister(db);
5521
+ }
5522
+ return rc;
5523
+}
5524
+
5525
+#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
5526
+/* To allow a standalone DLL, make test_windirent.c use the same
5527
+ * redefined SQLite API calls as the above extension code does.
5528
+ * Just pull in this .c to accomplish this. As a beneficial side
5529
+ * effect, this extension becomes a single translation unit. */
5530
+# include "test_windirent.c"
5531
+#endif
5532
+
5533
+/************************* End ../ext/misc/fileio.c ********************/
5534
+/************************* Begin ../ext/misc/completion.c ******************/
5535
+/*
5536
+** 2017-07-10
5537
+**
5538
+** The author disclaims copyright to this source code. In place of
5539
+** a legal notice, here is a blessing:
5540
+**
5541
+** May you do good and not evil.
5542
+** May you find forgiveness for yourself and forgive others.
5543
+** May you share freely, never taking more than you give.
5544
+**
5545
+*************************************************************************
5546
+**
5547
+** This file implements an eponymous virtual table that returns suggested
5548
+** completions for a partial SQL input.
5549
+**
5550
+** Suggested usage:
5551
+**
5552
+** SELECT DISTINCT candidate COLLATE nocase
5553
+** FROM completion($prefix,$wholeline)
5554
+** ORDER BY 1;
5555
+**
5556
+** The two query parameters are optional. $prefix is the text of the
5557
+** current word being typed and that is to be completed. $wholeline is
5558
+** the complete input line, used for context.
5559
+**
5560
+** The raw completion() table might return the same candidate multiple
5561
+** times, for example if the same column name is used to two or more
5562
+** tables. And the candidates are returned in an arbitrary order. Hence,
5563
+** the DISTINCT and ORDER BY are recommended.
5564
+**
5565
+** This virtual table operates at the speed of human typing, and so there
5566
+** is no attempt to make it fast. Even a slow implementation will be much
5567
+** faster than any human can type.
5568
+**
5569
+*/
5570
+/* #include "sqlite3ext.h" */
5571
+SQLITE_EXTENSION_INIT1
5572
+#include <assert.h>
5573
+#include <string.h>
5574
+#include <ctype.h>
5575
+
5576
+#ifndef SQLITE_OMIT_VIRTUALTABLE
5577
+
5578
+/* completion_vtab is a subclass of sqlite3_vtab which will
5579
+** serve as the underlying representation of a completion virtual table
5580
+*/
5581
+typedef struct completion_vtab completion_vtab;
5582
+struct completion_vtab {
5583
+ sqlite3_vtab base; /* Base class - must be first */
5584
+ sqlite3 *db; /* Database connection for this completion vtab */
5585
+};
5586
+
5587
+/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
5588
+** serve as the underlying representation of a cursor that scans
5589
+** over rows of the result
5590
+*/
5591
+typedef struct completion_cursor completion_cursor;
5592
+struct completion_cursor {
5593
+ sqlite3_vtab_cursor base; /* Base class - must be first */
5594
+ sqlite3 *db; /* Database connection for this cursor */
5595
+ int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */
5596
+ char *zPrefix; /* The prefix for the word we want to complete */
5597
+ char *zLine; /* The whole that we want to complete */
5598
+ const char *zCurrentRow; /* Current output row */
5599
+ int szRow; /* Length of the zCurrentRow string */
5600
+ sqlite3_stmt *pStmt; /* Current statement */
5601
+ sqlite3_int64 iRowid; /* The rowid */
5602
+ int ePhase; /* Current phase */
5603
+ int j; /* inter-phase counter */
5604
+};
5605
+
5606
+/* Values for ePhase:
5607
+*/
5608
+#define COMPLETION_FIRST_PHASE 1
5609
+#define COMPLETION_KEYWORDS 1
5610
+#define COMPLETION_PRAGMAS 2
5611
+#define COMPLETION_FUNCTIONS 3
5612
+#define COMPLETION_COLLATIONS 4
5613
+#define COMPLETION_INDEXES 5
5614
+#define COMPLETION_TRIGGERS 6
5615
+#define COMPLETION_DATABASES 7
5616
+#define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */
5617
+#define COMPLETION_COLUMNS 9
5618
+#define COMPLETION_MODULES 10
5619
+#define COMPLETION_EOF 11
5620
+
5621
+/*
5622
+** The completionConnect() method is invoked to create a new
5623
+** completion_vtab that describes the completion virtual table.
5624
+**
5625
+** Think of this routine as the constructor for completion_vtab objects.
5626
+**
5627
+** All this routine needs to do is:
5628
+**
5629
+** (1) Allocate the completion_vtab object and initialize all fields.
5630
+**
5631
+** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
5632
+** result set of queries against completion will look like.
5633
+*/
5634
+static int completionConnect(
5635
+ sqlite3 *db,
5636
+ void *pAux,
5637
+ int argc, const char *const*argv,
5638
+ sqlite3_vtab **ppVtab,
5639
+ char **pzErr
5640
+){
5641
+ completion_vtab *pNew;
5642
+ int rc;
5643
+
5644
+ (void)(pAux); /* Unused parameter */
5645
+ (void)(argc); /* Unused parameter */
5646
+ (void)(argv); /* Unused parameter */
5647
+ (void)(pzErr); /* Unused parameter */
5648
+
5649
+/* Column numbers */
5650
+#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
5651
+#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
5652
+#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
5653
+#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
5654
+
5655
+ sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
5656
+ rc = sqlite3_declare_vtab(db,
5657
+ "CREATE TABLE x("
5658
+ " candidate TEXT,"
5659
+ " prefix TEXT HIDDEN,"
5660
+ " wholeline TEXT HIDDEN,"
5661
+ " phase INT HIDDEN" /* Used for debugging only */
5662
+ ")");
5663
+ if( rc==SQLITE_OK ){
5664
+ pNew = sqlite3_malloc( sizeof(*pNew) );
5665
+ *ppVtab = (sqlite3_vtab*)pNew;
5666
+ if( pNew==0 ) return SQLITE_NOMEM;
5667
+ memset(pNew, 0, sizeof(*pNew));
5668
+ pNew->db = db;
5669
+ }
5670
+ return rc;
5671
+}
5672
+
5673
+/*
5674
+** This method is the destructor for completion_cursor objects.
5675
+*/
5676
+static int completionDisconnect(sqlite3_vtab *pVtab){
5677
+ sqlite3_free(pVtab);
5678
+ return SQLITE_OK;
5679
+}
5680
+
5681
+/*
5682
+** Constructor for a new completion_cursor object.
5683
+*/
5684
+static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
5685
+ completion_cursor *pCur;
5686
+ pCur = sqlite3_malloc( sizeof(*pCur) );
5687
+ if( pCur==0 ) return SQLITE_NOMEM;
5688
+ memset(pCur, 0, sizeof(*pCur));
5689
+ pCur->db = ((completion_vtab*)p)->db;
5690
+ *ppCursor = &pCur->base;
5691
+ return SQLITE_OK;
5692
+}
5693
+
5694
+/*
5695
+** Reset the completion_cursor.
5696
+*/
5697
+static void completionCursorReset(completion_cursor *pCur){
5698
+ sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0;
5699
+ sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0;
5700
+ sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
5701
+ pCur->j = 0;
5702
+}
5703
+
5704
+/*
5705
+** Destructor for a completion_cursor.
5706
+*/
5707
+static int completionClose(sqlite3_vtab_cursor *cur){
5708
+ completionCursorReset((completion_cursor*)cur);
5709
+ sqlite3_free(cur);
5710
+ return SQLITE_OK;
5711
+}
5712
+
5713
+/*
5714
+** Advance a completion_cursor to its next row of output.
5715
+**
5716
+** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
5717
+** record the current state of the scan. This routine sets ->zCurrentRow
5718
+** to the current row of output and then returns. If no more rows remain,
5719
+** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
5720
+** table that has reached the end of its scan.
5721
+**
5722
+** The current implementation just lists potential identifiers and
5723
+** keywords and filters them by zPrefix. Future enhancements should
5724
+** take zLine into account to try to restrict the set of identifiers and
5725
+** keywords based on what would be legal at the current point of input.
5726
+*/
5727
+static int completionNext(sqlite3_vtab_cursor *cur){
5728
+ completion_cursor *pCur = (completion_cursor*)cur;
5729
+ int eNextPhase = 0; /* Next phase to try if current phase reaches end */
5730
+ int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
5731
+ pCur->iRowid++;
5732
+ while( pCur->ePhase!=COMPLETION_EOF ){
5733
+ switch( pCur->ePhase ){
5734
+ case COMPLETION_KEYWORDS: {
5735
+ if( pCur->j >= sqlite3_keyword_count() ){
5736
+ pCur->zCurrentRow = 0;
5737
+ pCur->ePhase = COMPLETION_DATABASES;
5738
+ }else{
5739
+ sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
5740
+ }
5741
+ iCol = -1;
5742
+ break;
5743
+ }
5744
+ case COMPLETION_DATABASES: {
5745
+ if( pCur->pStmt==0 ){
5746
+ sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
5747
+ &pCur->pStmt, 0);
5748
+ }
5749
+ iCol = 1;
5750
+ eNextPhase = COMPLETION_TABLES;
5751
+ break;
5752
+ }
5753
+ case COMPLETION_TABLES: {
5754
+ if( pCur->pStmt==0 ){
5755
+ sqlite3_stmt *pS2;
5756
+ char *zSql = 0;
5757
+ const char *zSep = "";
5758
+ sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
5759
+ while( sqlite3_step(pS2)==SQLITE_ROW ){
5760
+ const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
5761
+ zSql = sqlite3_mprintf(
5762
+ "%z%s"
5763
+ "SELECT name FROM \"%w\".sqlite_schema",
5764
+ zSql, zSep, zDb
5765
+ );
5766
+ if( zSql==0 ) return SQLITE_NOMEM;
5767
+ zSep = " UNION ";
5768
+ }
5769
+ sqlite3_finalize(pS2);
5770
+ sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
5771
+ sqlite3_free(zSql);
5772
+ }
5773
+ iCol = 0;
5774
+ eNextPhase = COMPLETION_COLUMNS;
5775
+ break;
5776
+ }
5777
+ case COMPLETION_COLUMNS: {
5778
+ if( pCur->pStmt==0 ){
5779
+ sqlite3_stmt *pS2;
5780
+ char *zSql = 0;
5781
+ const char *zSep = "";
5782
+ sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
5783
+ while( sqlite3_step(pS2)==SQLITE_ROW ){
5784
+ const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
5785
+ zSql = sqlite3_mprintf(
5786
+ "%z%s"
5787
+ "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
5788
+ " JOIN pragma_table_info(sm.name,%Q) AS pti"
5789
+ " WHERE sm.type='table'",
5790
+ zSql, zSep, zDb, zDb
5791
+ );
5792
+ if( zSql==0 ) return SQLITE_NOMEM;
5793
+ zSep = " UNION ";
5794
+ }
5795
+ sqlite3_finalize(pS2);
5796
+ sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
5797
+ sqlite3_free(zSql);
5798
+ }
5799
+ iCol = 0;
5800
+ eNextPhase = COMPLETION_EOF;
5801
+ break;
5802
+ }
5803
+ }
5804
+ if( iCol<0 ){
5805
+ /* This case is when the phase presets zCurrentRow */
5806
+ if( pCur->zCurrentRow==0 ) continue;
5807
+ }else{
5808
+ if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
5809
+ /* Extract the next row of content */
5810
+ pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
5811
+ pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
5812
+ }else{
5813
+ /* When all rows are finished, advance to the next phase */
5814
+ sqlite3_finalize(pCur->pStmt);
5815
+ pCur->pStmt = 0;
5816
+ pCur->ePhase = eNextPhase;
5817
+ continue;
5818
+ }
5819
+ }
5820
+ if( pCur->nPrefix==0 ) break;
5821
+ if( pCur->nPrefix<=pCur->szRow
5822
+ && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
5823
+ ){
5824
+ break;
5825
+ }
5826
+ }
5827
+
5828
+ return SQLITE_OK;
5829
+}
5830
+
5831
+/*
5832
+** Return values of columns for the row at which the completion_cursor
5833
+** is currently pointing.
5834
+*/
5835
+static int completionColumn(
5836
+ sqlite3_vtab_cursor *cur, /* The cursor */
5837
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
5838
+ int i /* Which column to return */
5839
+){
5840
+ completion_cursor *pCur = (completion_cursor*)cur;
5841
+ switch( i ){
5842
+ case COMPLETION_COLUMN_CANDIDATE: {
5843
+ sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
5844
+ break;
5845
+ }
5846
+ case COMPLETION_COLUMN_PREFIX: {
5847
+ sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
5848
+ break;
5849
+ }
5850
+ case COMPLETION_COLUMN_WHOLELINE: {
5851
+ sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
5852
+ break;
5853
+ }
5854
+ case COMPLETION_COLUMN_PHASE: {
5855
+ sqlite3_result_int(ctx, pCur->ePhase);
5856
+ break;
5857
+ }
5858
+ }
5859
+ return SQLITE_OK;
5860
+}
5861
+
5862
+/*
5863
+** Return the rowid for the current row. In this implementation, the
5864
+** rowid is the same as the output value.
5865
+*/
5866
+static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
5867
+ completion_cursor *pCur = (completion_cursor*)cur;
5868
+ *pRowid = pCur->iRowid;
5869
+ return SQLITE_OK;
5870
+}
5871
+
5872
+/*
5873
+** Return TRUE if the cursor has been moved off of the last
5874
+** row of output.
5875
+*/
5876
+static int completionEof(sqlite3_vtab_cursor *cur){
5877
+ completion_cursor *pCur = (completion_cursor*)cur;
5878
+ return pCur->ePhase >= COMPLETION_EOF;
5879
+}
5880
+
5881
+/*
5882
+** This method is called to "rewind" the completion_cursor object back
5883
+** to the first row of output. This method is always called at least
5884
+** once prior to any call to completionColumn() or completionRowid() or
5885
+** completionEof().
5886
+*/
5887
+static int completionFilter(
5888
+ sqlite3_vtab_cursor *pVtabCursor,
5889
+ int idxNum, const char *idxStr,
5890
+ int argc, sqlite3_value **argv
5891
+){
5892
+ completion_cursor *pCur = (completion_cursor *)pVtabCursor;
5893
+ int iArg = 0;
5894
+ (void)(idxStr); /* Unused parameter */
5895
+ (void)(argc); /* Unused parameter */
5896
+ completionCursorReset(pCur);
5897
+ if( idxNum & 1 ){
5898
+ pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
5899
+ if( pCur->nPrefix>0 ){
5900
+ pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
5901
+ if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
5902
+ }
5903
+ iArg = 1;
5904
+ }
5905
+ if( idxNum & 2 ){
5906
+ pCur->nLine = sqlite3_value_bytes(argv[iArg]);
5907
+ if( pCur->nLine>0 ){
5908
+ pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
5909
+ if( pCur->zLine==0 ) return SQLITE_NOMEM;
5910
+ }
5911
+ }
5912
+ if( pCur->zLine!=0 && pCur->zPrefix==0 ){
5913
+ int i = pCur->nLine;
5914
+ while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
5915
+ i--;
5916
+ }
5917
+ pCur->nPrefix = pCur->nLine - i;
5918
+ if( pCur->nPrefix>0 ){
5919
+ pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
5920
+ if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
5921
+ }
5922
+ }
5923
+ pCur->iRowid = 0;
5924
+ pCur->ePhase = COMPLETION_FIRST_PHASE;
5925
+ return completionNext(pVtabCursor);
5926
+}
5927
+
5928
+/*
5929
+** SQLite will invoke this method one or more times while planning a query
5930
+** that uses the completion virtual table. This routine needs to create
5931
+** a query plan for each invocation and compute an estimated cost for that
5932
+** plan.
5933
+**
5934
+** There are two hidden parameters that act as arguments to the table-valued
5935
+** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix"
5936
+** is available and bit 1 is set if "wholeline" is available.
5937
+*/
5938
+static int completionBestIndex(
5939
+ sqlite3_vtab *tab,
5940
+ sqlite3_index_info *pIdxInfo
5941
+){
5942
+ int i; /* Loop over constraints */
5943
+ int idxNum = 0; /* The query plan bitmask */
5944
+ int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */
5945
+ int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
5946
+ int nArg = 0; /* Number of arguments that completeFilter() expects */
5947
+ const struct sqlite3_index_constraint *pConstraint;
5948
+
5949
+ (void)(tab); /* Unused parameter */
5950
+ pConstraint = pIdxInfo->aConstraint;
5951
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
5952
+ if( pConstraint->usable==0 ) continue;
5953
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
5954
+ switch( pConstraint->iColumn ){
5955
+ case COMPLETION_COLUMN_PREFIX:
5956
+ prefixIdx = i;
5957
+ idxNum |= 1;
5958
+ break;
5959
+ case COMPLETION_COLUMN_WHOLELINE:
5960
+ wholelineIdx = i;
5961
+ idxNum |= 2;
5962
+ break;
5963
+ }
5964
+ }
5965
+ if( prefixIdx>=0 ){
5966
+ pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
5967
+ pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
5968
+ }
5969
+ if( wholelineIdx>=0 ){
5970
+ pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
5971
+ pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
5972
+ }
5973
+ pIdxInfo->idxNum = idxNum;
5974
+ pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
5975
+ pIdxInfo->estimatedRows = 500 - 100*nArg;
5976
+ return SQLITE_OK;
5977
+}
5978
+
5979
+/*
5980
+** This following structure defines all the methods for the
5981
+** completion virtual table.
5982
+*/
5983
+static sqlite3_module completionModule = {
5984
+ 0, /* iVersion */
5985
+ 0, /* xCreate */
5986
+ completionConnect, /* xConnect */
5987
+ completionBestIndex, /* xBestIndex */
5988
+ completionDisconnect, /* xDisconnect */
5989
+ 0, /* xDestroy */
5990
+ completionOpen, /* xOpen - open a cursor */
5991
+ completionClose, /* xClose - close a cursor */
5992
+ completionFilter, /* xFilter - configure scan constraints */
5993
+ completionNext, /* xNext - advance a cursor */
5994
+ completionEof, /* xEof - check for end of scan */
5995
+ completionColumn, /* xColumn - read data */
5996
+ completionRowid, /* xRowid - read data */
5997
+ 0, /* xUpdate */
5998
+ 0, /* xBegin */
5999
+ 0, /* xSync */
6000
+ 0, /* xCommit */
6001
+ 0, /* xRollback */
6002
+ 0, /* xFindMethod */
6003
+ 0, /* xRename */
6004
+ 0, /* xSavepoint */
6005
+ 0, /* xRelease */
6006
+ 0, /* xRollbackTo */
6007
+ 0 /* xShadowName */
6008
+};
6009
+
6010
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
6011
+
6012
+int sqlite3CompletionVtabInit(sqlite3 *db){
6013
+ int rc = SQLITE_OK;
6014
+#ifndef SQLITE_OMIT_VIRTUALTABLE
6015
+ rc = sqlite3_create_module(db, "completion", &completionModule, 0);
6016
+#endif
6017
+ return rc;
6018
+}
6019
+
6020
+#ifdef _WIN32
6021
+
6022
+#endif
6023
+int sqlite3_completion_init(
6024
+ sqlite3 *db,
6025
+ char **pzErrMsg,
6026
+ const sqlite3_api_routines *pApi
6027
+){
6028
+ int rc = SQLITE_OK;
6029
+ SQLITE_EXTENSION_INIT2(pApi);
6030
+ (void)(pzErrMsg); /* Unused parameter */
6031
+#ifndef SQLITE_OMIT_VIRTUALTABLE
6032
+ rc = sqlite3CompletionVtabInit(db);
6033
+#endif
6034
+ return rc;
6035
+}
6036
+
6037
+/************************* End ../ext/misc/completion.c ********************/
6038
+/************************* Begin ../ext/misc/appendvfs.c ******************/
6039
+/*
6040
+** 2017-10-20
6041
+**
6042
+** The author disclaims copyright to this source code. In place of
6043
+** a legal notice, here is a blessing:
6044
+**
6045
+** May you do good and not evil.
6046
+** May you find forgiveness for yourself and forgive others.
6047
+** May you share freely, never taking more than you give.
6048
+**
6049
+******************************************************************************
6050
+**
6051
+** This file implements a VFS shim that allows an SQLite database to be
6052
+** appended onto the end of some other file, such as an executable.
6053
+**
6054
+** A special record must appear at the end of the file that identifies the
6055
+** file as an appended database and provides the offset to the first page
6056
+** of the exposed content. (Or, it is the length of the content prefix.)
6057
+** For best performance page 1 should be located at a disk page boundary,
6058
+** though that is not required.
6059
+**
6060
+** When opening a database using this VFS, the connection might treat
6061
+** the file as an ordinary SQLite database, or it might treat it as a
6062
+** database appended onto some other file. The decision is made by
6063
+** applying the following rules in order:
6064
+**
6065
+** (1) An empty file is an ordinary database.
6066
+**
6067
+** (2) If the file ends with the appendvfs trailer string
6068
+** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
6069
+**
6070
+** (3) If the file begins with the standard SQLite prefix string
6071
+** "SQLite format 3", that file is an ordinary database.
6072
+**
6073
+** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
6074
+** set, then a new database is appended to the already existing file.
6075
+**
6076
+** (5) Otherwise, SQLITE_CANTOPEN is returned.
6077
+**
6078
+** To avoid unnecessary complications with the PENDING_BYTE, the size of
6079
+** the file containing the database is limited to 1GiB. (1073741824 bytes)
6080
+** This VFS will not read or write past the 1GiB mark. This restriction
6081
+** might be lifted in future versions. For now, if you need a larger
6082
+** database, then keep it in a separate file.
6083
+**
6084
+** If the file being opened is a plain database (not an appended one), then
6085
+** this shim is a pass-through into the default underlying VFS. (rule 3)
6086
+**/
6087
+/* #include "sqlite3ext.h" */
6088
+SQLITE_EXTENSION_INIT1
6089
+#include <string.h>
6090
+#include <assert.h>
6091
+
6092
+/* The append mark at the end of the database is:
6093
+**
6094
+** Start-Of-SQLite3-NNNNNNNN
6095
+** 123456789 123456789 12345
6096
+**
6097
+** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
6098
+** the offset to page 1, and also the length of the prefix content.
6099
+*/
6100
+#define APND_MARK_PREFIX "Start-Of-SQLite3-"
6101
+#define APND_MARK_PREFIX_SZ 17
6102
+#define APND_MARK_FOS_SZ 8
6103
+#define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
6104
+
6105
+/*
6106
+** Maximum size of the combined prefix + database + append-mark. This
6107
+** must be less than 0x40000000 to avoid locking issues on Windows.
6108
+*/
6109
+#define APND_MAX_SIZE (0x40000000)
6110
+
6111
+/*
6112
+** Try to align the database to an even multiple of APND_ROUNDUP bytes.
6113
+*/
6114
+#ifndef APND_ROUNDUP
6115
+#define APND_ROUNDUP 4096
6116
+#endif
6117
+#define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1))
6118
+#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
6119
+
6120
+/*
6121
+** Forward declaration of objects used by this utility
6122
+*/
6123
+typedef struct sqlite3_vfs ApndVfs;
6124
+typedef struct ApndFile ApndFile;
6125
+
6126
+/* Access to a lower-level VFS that (might) implement dynamic loading,
6127
+** access to randomness, etc.
6128
+*/
6129
+#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
6130
+#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
6131
+
6132
+/* An open appendvfs file
6133
+**
6134
+** An instance of this structure describes the appended database file.
6135
+** A separate sqlite3_file object is always appended. The appended
6136
+** sqlite3_file object (which can be accessed using ORIGFILE()) describes
6137
+** the entire file, including the prefix, the database, and the
6138
+** append-mark.
6139
+**
6140
+** The structure of an AppendVFS database is like this:
6141
+**
6142
+** +-------------+---------+----------+-------------+
6143
+** | prefix-file | padding | database | append-mark |
6144
+** +-------------+---------+----------+-------------+
6145
+** ^ ^
6146
+** | |
6147
+** iPgOne iMark
6148
+**
6149
+**
6150
+** "prefix file" - file onto which the database has been appended.
6151
+** "padding" - zero or more bytes inserted so that "database"
6152
+** starts on an APND_ROUNDUP boundary
6153
+** "database" - The SQLite database file
6154
+** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
6155
+** the offset from the start of prefix-file to the start
6156
+** of "database".
6157
+**
6158
+** The size of the database is iMark - iPgOne.
6159
+**
6160
+** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
6161
+** of iPgOne stored as a big-ending 64-bit integer.
6162
+**
6163
+** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
6164
+** Or, iMark is -1 to indicate that it has not yet been written.
6165
+*/
6166
+struct ApndFile {
6167
+ sqlite3_file base; /* Subclass. MUST BE FIRST! */
6168
+ sqlite3_int64 iPgOne; /* Offset to the start of the database */
6169
+ sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */
6170
+ /* Always followed by another sqlite3_file that describes the whole file */
6171
+};
6172
+
6173
+/*
6174
+** Methods for ApndFile
6175
+*/
6176
+static int apndClose(sqlite3_file*);
6177
+static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
6178
+static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
6179
+static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
6180
+static int apndSync(sqlite3_file*, int flags);
6181
+static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
6182
+static int apndLock(sqlite3_file*, int);
6183
+static int apndUnlock(sqlite3_file*, int);
6184
+static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
6185
+static int apndFileControl(sqlite3_file*, int op, void *pArg);
6186
+static int apndSectorSize(sqlite3_file*);
6187
+static int apndDeviceCharacteristics(sqlite3_file*);
6188
+static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
6189
+static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
6190
+static void apndShmBarrier(sqlite3_file*);
6191
+static int apndShmUnmap(sqlite3_file*, int deleteFlag);
6192
+static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
6193
+static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
6194
+
6195
+/*
6196
+** Methods for ApndVfs
6197
+*/
6198
+static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
6199
+static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
6200
+static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
6201
+static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
6202
+static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
6203
+static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
6204
+static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
6205
+static void apndDlClose(sqlite3_vfs*, void*);
6206
+static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
6207
+static int apndSleep(sqlite3_vfs*, int microseconds);
6208
+static int apndCurrentTime(sqlite3_vfs*, double*);
6209
+static int apndGetLastError(sqlite3_vfs*, int, char *);
6210
+static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
6211
+static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
6212
+static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
6213
+static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
6214
+
6215
+static sqlite3_vfs apnd_vfs = {
6216
+ 3, /* iVersion (set when registered) */
6217
+ 0, /* szOsFile (set when registered) */
6218
+ 1024, /* mxPathname */
6219
+ 0, /* pNext */
6220
+ "apndvfs", /* zName */
6221
+ 0, /* pAppData (set when registered) */
6222
+ apndOpen, /* xOpen */
6223
+ apndDelete, /* xDelete */
6224
+ apndAccess, /* xAccess */
6225
+ apndFullPathname, /* xFullPathname */
6226
+ apndDlOpen, /* xDlOpen */
6227
+ apndDlError, /* xDlError */
6228
+ apndDlSym, /* xDlSym */
6229
+ apndDlClose, /* xDlClose */
6230
+ apndRandomness, /* xRandomness */
6231
+ apndSleep, /* xSleep */
6232
+ apndCurrentTime, /* xCurrentTime */
6233
+ apndGetLastError, /* xGetLastError */
6234
+ apndCurrentTimeInt64, /* xCurrentTimeInt64 */
6235
+ apndSetSystemCall, /* xSetSystemCall */
6236
+ apndGetSystemCall, /* xGetSystemCall */
6237
+ apndNextSystemCall /* xNextSystemCall */
6238
+};
6239
+
6240
+static const sqlite3_io_methods apnd_io_methods = {
6241
+ 3, /* iVersion */
6242
+ apndClose, /* xClose */
6243
+ apndRead, /* xRead */
6244
+ apndWrite, /* xWrite */
6245
+ apndTruncate, /* xTruncate */
6246
+ apndSync, /* xSync */
6247
+ apndFileSize, /* xFileSize */
6248
+ apndLock, /* xLock */
6249
+ apndUnlock, /* xUnlock */
6250
+ apndCheckReservedLock, /* xCheckReservedLock */
6251
+ apndFileControl, /* xFileControl */
6252
+ apndSectorSize, /* xSectorSize */
6253
+ apndDeviceCharacteristics, /* xDeviceCharacteristics */
6254
+ apndShmMap, /* xShmMap */
6255
+ apndShmLock, /* xShmLock */
6256
+ apndShmBarrier, /* xShmBarrier */
6257
+ apndShmUnmap, /* xShmUnmap */
6258
+ apndFetch, /* xFetch */
6259
+ apndUnfetch /* xUnfetch */
6260
+};
6261
+
6262
+/*
6263
+** Close an apnd-file.
6264
+*/
6265
+static int apndClose(sqlite3_file *pFile){
6266
+ pFile = ORIGFILE(pFile);
6267
+ return pFile->pMethods->xClose(pFile);
6268
+}
6269
+
6270
+/*
6271
+** Read data from an apnd-file.
6272
+*/
6273
+static int apndRead(
6274
+ sqlite3_file *pFile,
6275
+ void *zBuf,
6276
+ int iAmt,
6277
+ sqlite_int64 iOfst
6278
+){
6279
+ ApndFile *paf = (ApndFile *)pFile;
6280
+ pFile = ORIGFILE(pFile);
6281
+ return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
6282
+}
6283
+
6284
+/*
6285
+** Add the append-mark onto what should become the end of the file.
6286
+* If and only if this succeeds, internal ApndFile.iMark is updated.
6287
+* Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
6288
+*/
6289
+static int apndWriteMark(
6290
+ ApndFile *paf,
6291
+ sqlite3_file *pFile,
6292
+ sqlite_int64 iWriteEnd
6293
+){
6294
+ sqlite_int64 iPgOne = paf->iPgOne;
6295
+ unsigned char a[APND_MARK_SIZE];
6296
+ int i = APND_MARK_FOS_SZ;
6297
+ int rc;
6298
+ assert(pFile == ORIGFILE(paf));
6299
+ memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
6300
+ while( --i >= 0 ){
6301
+ a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
6302
+ iPgOne >>= 8;
6303
+ }
6304
+ iWriteEnd += paf->iPgOne;
6305
+ if( SQLITE_OK==(rc = pFile->pMethods->xWrite
6306
+ (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
6307
+ paf->iMark = iWriteEnd;
6308
+ }
6309
+ return rc;
6310
+}
6311
+
6312
+/*
6313
+** Write data to an apnd-file.
6314
+*/
6315
+static int apndWrite(
6316
+ sqlite3_file *pFile,
6317
+ const void *zBuf,
6318
+ int iAmt,
6319
+ sqlite_int64 iOfst
6320
+){
6321
+ ApndFile *paf = (ApndFile *)pFile;
6322
+ sqlite_int64 iWriteEnd = iOfst + iAmt;
6323
+ if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
6324
+ pFile = ORIGFILE(pFile);
6325
+ /* If append-mark is absent or will be overwritten, write it. */
6326
+ if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
6327
+ int rc = apndWriteMark(paf, pFile, iWriteEnd);
6328
+ if( SQLITE_OK!=rc ) return rc;
6329
+ }
6330
+ return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
6331
+}
6332
+
6333
+/*
6334
+** Truncate an apnd-file.
6335
+*/
6336
+static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
6337
+ ApndFile *paf = (ApndFile *)pFile;
6338
+ pFile = ORIGFILE(pFile);
6339
+ /* The append mark goes out first so truncate failure does not lose it. */
6340
+ if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
6341
+ /* Truncate underlying file just past append mark */
6342
+ return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
6343
+}
6344
+
6345
+/*
6346
+** Sync an apnd-file.
6347
+*/
6348
+static int apndSync(sqlite3_file *pFile, int flags){
6349
+ pFile = ORIGFILE(pFile);
6350
+ return pFile->pMethods->xSync(pFile, flags);
6351
+}
6352
+
6353
+/*
6354
+** Return the current file-size of an apnd-file.
6355
+** If the append mark is not yet there, the file-size is 0.
6356
+*/
6357
+static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
6358
+ ApndFile *paf = (ApndFile *)pFile;
6359
+ *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
6360
+ return SQLITE_OK;
6361
+}
6362
+
6363
+/*
6364
+** Lock an apnd-file.
6365
+*/
6366
+static int apndLock(sqlite3_file *pFile, int eLock){
6367
+ pFile = ORIGFILE(pFile);
6368
+ return pFile->pMethods->xLock(pFile, eLock);
6369
+}
6370
+
6371
+/*
6372
+** Unlock an apnd-file.
6373
+*/
6374
+static int apndUnlock(sqlite3_file *pFile, int eLock){
6375
+ pFile = ORIGFILE(pFile);
6376
+ return pFile->pMethods->xUnlock(pFile, eLock);
6377
+}
6378
+
6379
+/*
6380
+** Check if another file-handle holds a RESERVED lock on an apnd-file.
6381
+*/
6382
+static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
6383
+ pFile = ORIGFILE(pFile);
6384
+ return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
6385
+}
6386
+
6387
+/*
6388
+** File control method. For custom operations on an apnd-file.
6389
+*/
6390
+static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
6391
+ ApndFile *paf = (ApndFile *)pFile;
6392
+ int rc;
6393
+ pFile = ORIGFILE(pFile);
6394
+ if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
6395
+ rc = pFile->pMethods->xFileControl(pFile, op, pArg);
6396
+ if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
6397
+ *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
6398
+ }
6399
+ return rc;
6400
+}
6401
+
6402
+/*
6403
+** Return the sector-size in bytes for an apnd-file.
6404
+*/
6405
+static int apndSectorSize(sqlite3_file *pFile){
6406
+ pFile = ORIGFILE(pFile);
6407
+ return pFile->pMethods->xSectorSize(pFile);
6408
+}
6409
+
6410
+/*
6411
+** Return the device characteristic flags supported by an apnd-file.
6412
+*/
6413
+static int apndDeviceCharacteristics(sqlite3_file *pFile){
6414
+ pFile = ORIGFILE(pFile);
6415
+ return pFile->pMethods->xDeviceCharacteristics(pFile);
6416
+}
6417
+
6418
+/* Create a shared memory file mapping */
6419
+static int apndShmMap(
6420
+ sqlite3_file *pFile,
6421
+ int iPg,
6422
+ int pgsz,
6423
+ int bExtend,
6424
+ void volatile **pp
6425
+){
6426
+ pFile = ORIGFILE(pFile);
6427
+ return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
6428
+}
6429
+
6430
+/* Perform locking on a shared-memory segment */
6431
+static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
6432
+ pFile = ORIGFILE(pFile);
6433
+ return pFile->pMethods->xShmLock(pFile,offset,n,flags);
6434
+}
6435
+
6436
+/* Memory barrier operation on shared memory */
6437
+static void apndShmBarrier(sqlite3_file *pFile){
6438
+ pFile = ORIGFILE(pFile);
6439
+ pFile->pMethods->xShmBarrier(pFile);
6440
+}
6441
+
6442
+/* Unmap a shared memory segment */
6443
+static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
6444
+ pFile = ORIGFILE(pFile);
6445
+ return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
6446
+}
6447
+
6448
+/* Fetch a page of a memory-mapped file */
6449
+static int apndFetch(
6450
+ sqlite3_file *pFile,
6451
+ sqlite3_int64 iOfst,
6452
+ int iAmt,
6453
+ void **pp
6454
+){
6455
+ ApndFile *p = (ApndFile *)pFile;
6456
+ if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
6457
+ return SQLITE_IOERR; /* Cannot read what is not yet there. */
6458
+ }
6459
+ pFile = ORIGFILE(pFile);
6460
+ return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
6461
+}
6462
+
6463
+/* Release a memory-mapped page */
6464
+static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
6465
+ ApndFile *p = (ApndFile *)pFile;
6466
+ pFile = ORIGFILE(pFile);
6467
+ return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
6468
+}
6469
+
6470
+/*
6471
+** Try to read the append-mark off the end of a file. Return the
6472
+** start of the appended database if the append-mark is present.
6473
+** If there is no valid append-mark, return -1;
6474
+**
6475
+** An append-mark is only valid if the NNNNNNNN start-of-database offset
6476
+** indicates that the appended database contains at least one page. The
6477
+** start-of-database value must be a multiple of 512.
6478
+*/
6479
+static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
6480
+ int rc, i;
6481
+ sqlite3_int64 iMark;
6482
+ int msbs = 8 * (APND_MARK_FOS_SZ-1);
6483
+ unsigned char a[APND_MARK_SIZE];
6484
+
6485
+ if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
6486
+ rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
6487
+ if( rc ) return -1;
6488
+ if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
6489
+ iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
6490
+ for(i=1; i<8; i++){
6491
+ msbs -= 8;
6492
+ iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
6493
+ }
6494
+ if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
6495
+ if( iMark & 0x1ff ) return -1;
6496
+ return iMark;
6497
+}
6498
+
6499
+static const char apvfsSqliteHdr[] = "SQLite format 3";
6500
+/*
6501
+** Check to see if the file is an appendvfs SQLite database file.
6502
+** Return true iff it is such. Parameter sz is the file's size.
6503
+*/
6504
+static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
6505
+ int rc;
6506
+ char zHdr[16];
6507
+ sqlite3_int64 iMark = apndReadMark(sz, pFile);
6508
+ if( iMark>=0 ){
6509
+ /* If file has the correct end-marker, the expected odd size, and the
6510
+ ** SQLite DB type marker where the end-marker puts it, then it
6511
+ ** is an appendvfs database.
6512
+ */
6513
+ rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
6514
+ if( SQLITE_OK==rc
6515
+ && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
6516
+ && (sz & 0x1ff) == APND_MARK_SIZE
6517
+ && sz>=512+APND_MARK_SIZE
6518
+ ){
6519
+ return 1; /* It's an appendvfs database */
6520
+ }
6521
+ }
6522
+ return 0;
6523
+}
6524
+
6525
+/*
6526
+** Check to see if the file is an ordinary SQLite database file.
6527
+** Return true iff so. Parameter sz is the file's size.
6528
+*/
6529
+static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
6530
+ char zHdr[16];
6531
+ if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
6532
+ || (sz & 0x1ff) != 0
6533
+ || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
6534
+ || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
6535
+ ){
6536
+ return 0;
6537
+ }else{
6538
+ return 1;
6539
+ }
6540
+}
6541
+
6542
+/*
6543
+** Open an apnd file handle.
6544
+*/
6545
+static int apndOpen(
6546
+ sqlite3_vfs *pApndVfs,
6547
+ const char *zName,
6548
+ sqlite3_file *pFile,
6549
+ int flags,
6550
+ int *pOutFlags
6551
+){
6552
+ ApndFile *pApndFile = (ApndFile*)pFile;
6553
+ sqlite3_file *pBaseFile = ORIGFILE(pFile);
6554
+ sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
6555
+ int rc;
6556
+ sqlite3_int64 sz = 0;
6557
+ if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
6558
+ /* The appendvfs is not to be used for transient or temporary databases.
6559
+ ** Just use the base VFS open to initialize the given file object and
6560
+ ** open the underlying file. (Appendvfs is then unused for this file.)
6561
+ */
6562
+ return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
6563
+ }
6564
+ memset(pApndFile, 0, sizeof(ApndFile));
6565
+ pFile->pMethods = &apnd_io_methods;
6566
+ pApndFile->iMark = -1; /* Append mark not yet written */
6567
+
6568
+ rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
6569
+ if( rc==SQLITE_OK ){
6570
+ rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
6571
+ if( rc ){
6572
+ pBaseFile->pMethods->xClose(pBaseFile);
6573
+ }
6574
+ }
6575
+ if( rc ){
6576
+ pFile->pMethods = 0;
6577
+ return rc;
6578
+ }
6579
+ if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
6580
+ /* The file being opened appears to be just an ordinary DB. Copy
6581
+ ** the base dispatch-table so this instance mimics the base VFS.
6582
+ */
6583
+ memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
6584
+ return SQLITE_OK;
6585
+ }
6586
+ pApndFile->iPgOne = apndReadMark(sz, pFile);
6587
+ if( pApndFile->iPgOne>=0 ){
6588
+ pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
6589
+ return SQLITE_OK;
6590
+ }
6591
+ if( (flags & SQLITE_OPEN_CREATE)==0 ){
6592
+ pBaseFile->pMethods->xClose(pBaseFile);
6593
+ rc = SQLITE_CANTOPEN;
6594
+ pFile->pMethods = 0;
6595
+ }else{
6596
+ /* Round newly added appendvfs location to #define'd page boundary.
6597
+ ** Note that nothing has yet been written to the underlying file.
6598
+ ** The append mark will be written along with first content write.
6599
+ ** Until then, paf->iMark value indicates it is not yet written.
6600
+ */
6601
+ pApndFile->iPgOne = APND_START_ROUNDUP(sz);
6602
+ }
6603
+ return rc;
6604
+}
6605
+
6606
+/*
6607
+** Delete an apnd file.
6608
+** For an appendvfs, this could mean delete the appendvfs portion,
6609
+** leaving the appendee as it was before it gained an appendvfs.
6610
+** For now, this code deletes the underlying file too.
6611
+*/
6612
+static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
6613
+ return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
6614
+}
6615
+
6616
+/*
6617
+** All other VFS methods are pass-thrus.
6618
+*/
6619
+static int apndAccess(
6620
+ sqlite3_vfs *pVfs,
6621
+ const char *zPath,
6622
+ int flags,
6623
+ int *pResOut
6624
+){
6625
+ return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
6626
+}
6627
+static int apndFullPathname(
6628
+ sqlite3_vfs *pVfs,
6629
+ const char *zPath,
6630
+ int nOut,
6631
+ char *zOut
6632
+){
6633
+ return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
6634
+}
6635
+static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
6636
+ return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
6637
+}
6638
+static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
6639
+ ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
6640
+}
6641
+static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
6642
+ return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
6643
+}
6644
+static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
6645
+ ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
6646
+}
6647
+static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
6648
+ return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
6649
+}
6650
+static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
6651
+ return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
6652
+}
6653
+static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
6654
+ return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
6655
+}
6656
+static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
6657
+ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
6658
+}
6659
+static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
6660
+ return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
6661
+}
6662
+static int apndSetSystemCall(
6663
+ sqlite3_vfs *pVfs,
6664
+ const char *zName,
6665
+ sqlite3_syscall_ptr pCall
6666
+){
6667
+ return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
6668
+}
6669
+static sqlite3_syscall_ptr apndGetSystemCall(
6670
+ sqlite3_vfs *pVfs,
6671
+ const char *zName
6672
+){
6673
+ return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
6674
+}
6675
+static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
6676
+ return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
6677
+}
6678
+
6679
+
6680
+#ifdef _WIN32
6681
+
6682
+#endif
6683
+/*
6684
+** This routine is called when the extension is loaded.
6685
+** Register the new VFS.
6686
+*/
6687
+int sqlite3_appendvfs_init(
6688
+ sqlite3 *db,
6689
+ char **pzErrMsg,
6690
+ const sqlite3_api_routines *pApi
6691
+){
6692
+ int rc = SQLITE_OK;
6693
+ sqlite3_vfs *pOrig;
6694
+ SQLITE_EXTENSION_INIT2(pApi);
6695
+ (void)pzErrMsg;
6696
+ (void)db;
6697
+ pOrig = sqlite3_vfs_find(0);
6698
+ if( pOrig==0 ) return SQLITE_ERROR;
6699
+ apnd_vfs.iVersion = pOrig->iVersion;
6700
+ apnd_vfs.pAppData = pOrig;
6701
+ apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
6702
+ rc = sqlite3_vfs_register(&apnd_vfs, 0);
6703
+#ifdef APPENDVFS_TEST
6704
+ if( rc==SQLITE_OK ){
6705
+ rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
6706
+ }
6707
+#endif
6708
+ if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
6709
+ return rc;
6710
+}
6711
+
6712
+/************************* End ../ext/misc/appendvfs.c ********************/
6713
+#endif
67016714
#ifdef SQLITE_HAVE_ZLIB
67026715
/************************* Begin ../ext/misc/zipfile.c ******************/
67036716
/*
67046717
** 2017-12-26
67056718
**
@@ -12235,11 +12248,21 @@
1223512248
int nIndent; /* Size of array aiIndent[] */
1223612249
int iIndent; /* Index of current op in aiIndent[] */
1223712250
char *zNonce; /* Nonce for temporary safe-mode excapes */
1223812251
EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
1223912252
ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
12253
+#ifdef SQLITE_SHELL_WASM_MODE
12254
+ struct {
12255
+ const char * zInput; /* Input string from wasm/JS proxy */
12256
+ const char * zPos; /* Cursor pos into zInput */
12257
+ } wasm;
12258
+#endif
1224012259
};
12260
+
12261
+#ifdef SQLITE_SHELL_WASM_MODE
12262
+static ShellState shellState;
12263
+#endif
1224112264
1224212265
1224312266
/* Allowed values for ShellState.autoEQP
1224412267
*/
1224512268
#define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
@@ -12277,11 +12300,11 @@
1227712300
#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
1227812301
#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
1227912302
#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
1228012303
#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
1228112304
#define SHFLG_CountChanges 0x00000020 /* .changes setting */
12282
-#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
12305
+#define SHFLG_Echo 0x00000040 /* .echo on/off, or --echo setting */
1228312306
#define SHFLG_HeaderSet 0x00000080 /* showHeader has been specified */
1228412307
#define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
1228512308
#define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
1228612309
1228712310
/*
@@ -12901,11 +12924,15 @@
1290112924
UNUSED_PARAMETER(zA2);
1290212925
UNUSED_PARAMETER(zA3);
1290312926
UNUSED_PARAMETER(zA4);
1290412927
switch( op ){
1290512928
case SQLITE_ATTACH: {
12929
+#ifndef SQLITE_SHELL_WASM_MODE
12930
+ /* In WASM builds the filesystem is a virtual sandbox, so
12931
+ ** there's no harm in using ATTACH. */
1290612932
failIfSafeMode(p, "cannot run ATTACH in safe mode");
12933
+#endif
1290712934
break;
1290812935
}
1290912936
case SQLITE_FUNCTION: {
1291012937
int i;
1291112938
for(i=0; i<ArraySize(azProhibitedFunctions); i++){
@@ -14906,15 +14933,10 @@
1490614933
if( pArg ){
1490714934
pArg->pStmt = pStmt;
1490814935
pArg->cnt = 0;
1490914936
}
1491014937
14911
- /* echo the sql statement if echo on */
14912
- if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
14913
- utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
14914
- }
14915
-
1491614938
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
1491714939
if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
1491814940
sqlite3_stmt *pExplain;
1491914941
char *zEQP;
1492014942
int triggerEQP = 0;
@@ -15309,17 +15331,18 @@
1530915331
1531015332
/*
1531115333
** Text of help messages.
1531215334
**
1531315335
** The help text for each individual command begins with a line that starts
15314
-** with ".". Subsequent lines are supplimental information.
15336
+** with ".". Subsequent lines are supplemental information.
1531515337
**
1531615338
** There must be two or more spaces between the end of the command and the
1531715339
** start of the description of what that command does.
1531815340
*/
1531915341
static const char *(azHelp[]) = {
15320
-#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
15342
+#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) \
15343
+ && !defined(SQLITE_SHELL_WASM_MODE)
1532115344
".archive ... Manage SQL archives",
1532215345
" Each command must have exactly one of the following options:",
1532315346
" -c, --create Create a new archive",
1532415347
" -u, --update Add or update files with changed mtime",
1532515348
" -i, --insert Like -u but always add even if unchanged",
@@ -15341,24 +15364,32 @@
1534115364
" http://sqlite.org/cli.html#sqlite_archive_support",
1534215365
#endif
1534315366
#ifndef SQLITE_OMIT_AUTHORIZATION
1534415367
".auth ON|OFF Show authorizer callbacks",
1534515368
#endif
15369
+#ifndef SQLITE_SHELL_WASM_MODE
1534615370
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
1534715371
" Options:",
1534815372
" --append Use the appendvfs",
1534915373
" --async Write to FILE without journal and fsync()",
15374
+#endif
1535015375
".bail on|off Stop after hitting an error. Default OFF",
1535115376
".binary on|off Turn binary output on or off. Default OFF",
15377
+#ifndef SQLITE_SHELL_WASM_MODE
1535215378
".cd DIRECTORY Change the working directory to DIRECTORY",
15379
+#endif
1535315380
".changes on|off Show number of rows changed by SQL",
15381
+#ifndef SQLITE_SHELL_WASM_MODE
1535415382
".check GLOB Fail if output since .testcase does not match",
1535515383
".clone NEWDB Clone data into NEWDB from the existing database",
15384
+#endif
1535615385
".connection [close] [#] Open or close an auxiliary database connection",
1535715386
".databases List names and files of attached databases",
1535815387
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
15388
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1535915389
".dbinfo ?DB? Show status information about the database",
15390
+#endif
1536015391
".dump ?OBJECTS? Render database content as SQL",
1536115392
" Options:",
1536215393
" --data-only Output only INSERT statements",
1536315394
" --newlines Allow unescaped newline characters in output",
1536415395
" --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -15371,21 +15402,26 @@
1537115402
#ifdef SQLITE_DEBUG
1537215403
" test Show raw EXPLAIN QUERY PLAN output",
1537315404
" trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
1537415405
#endif
1537515406
" trigger Like \"full\" but also show trigger bytecode",
15407
+#ifndef SQLITE_SHELL_WASM_MODE
1537615408
".excel Display the output of next command in spreadsheet",
1537715409
" --bom Put a UTF8 byte-order mark on intermediate file",
15410
+#endif
15411
+#ifndef SQLITE_SHELL_WASM_MODE
1537815412
".exit ?CODE? Exit this program with return-code CODE",
15413
+#endif
1537915414
".expert EXPERIMENTAL. Suggest indexes for queries",
1538015415
".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
1538115416
".filectrl CMD ... Run various sqlite3_file_control() operations",
1538215417
" --schema SCHEMA Use SCHEMA instead of \"main\"",
1538315418
" --help Show CMD details",
1538415419
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
1538515420
".headers on|off Turn display of headers on or off",
1538615421
".help ?-all? ?PATTERN? Show help text for PATTERN",
15422
+#ifndef SQLITE_SHELL_WASM_MODE
1538715423
".import FILE TABLE Import data from FILE into TABLE",
1538815424
" Options:",
1538915425
" --ascii Use \\037 and \\036 as column and row separators",
1539015426
" --csv Use , and \\n as column and row separators",
1539115427
" --skip N Skip the first N rows of input",
@@ -15396,10 +15432,11 @@
1539615432
" determines the column names.",
1539715433
" * If neither --csv or --ascii are used, the input mode is derived",
1539815434
" from the \".mode\" output mode",
1539915435
" * If FILE begins with \"|\" then it is a command that generates the",
1540015436
" input text.",
15437
+#endif
1540115438
#ifndef SQLITE_OMIT_TEST_CONTROL
1540215439
".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
1540315440
#endif
1540415441
".indexes ?TABLE? Show names of indexes",
1540515442
" If TABLE is specified, only show indexes for",
@@ -15409,14 +15446,16 @@
1540915446
#endif
1541015447
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
1541115448
".lint OPTIONS Report potential schema issues.",
1541215449
" Options:",
1541315450
" fkey-indexes Find missing foreign key indexes",
15414
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
15451
+#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_WASM_MODE)
1541515452
".load FILE ?ENTRY? Load an extension library",
1541615453
#endif
15454
+#ifndef SQLITE_SHELL_WASM_MODE
1541715455
".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15456
+#endif
1541815457
".mode MODE ?OPTIONS? Set output mode",
1541915458
" MODE is one of:",
1542015459
" ascii Columns/rows delimited by 0x1F and 0x1E",
1542115460
" box Tables using unicode box-drawing characters",
1542215461
" csv Comma-separated values",
@@ -15437,35 +15476,44 @@
1543715476
" --wordwrap B Wrap or not at word boundaries per B (on/off)",
1543815477
" --ww Shorthand for \"--wordwrap 1\"",
1543915478
" --quote Quote output text as SQL literals",
1544015479
" --noquote Do not quote output text",
1544115480
" TABLE The name of SQL table used for \"insert\" mode",
15481
+#ifndef SQLITE_SHELL_WASM_MODE
1544215482
".nonce STRING Suspend safe mode for one command if nonce matches",
15483
+#endif
1544315484
".nullvalue STRING Use STRING in place of NULL values",
15485
+#ifndef SQLITE_SHELL_WASM_MODE
1544415486
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
1544515487
" If FILE begins with '|' then open as a pipe",
1544615488
" --bom Put a UTF8 byte-order mark at the beginning",
1544715489
" -e Send output to the system text editor",
1544815490
" -x Send output as CSV to a spreadsheet (same as \".excel\")",
15491
+ /* Note that .open is (partially) available in WASM builds but is
15492
+ ** currently only intended to be used by the fiddle tool, not
15493
+ ** end users, so is "undocumented." */
1544915494
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
1545015495
" Options:",
1545115496
" --append Use appendvfs to append database to the end of FILE",
15497
+#endif
1545215498
#ifndef SQLITE_OMIT_DESERIALIZE
1545315499
" --deserialize Load into memory using sqlite3_deserialize()",
1545415500
" --hexdb Load the output of \"dbtotxt\" as an in-memory db",
1545515501
" --maxsize N Maximum size for --hexdb or --deserialized database",
1545615502
#endif
1545715503
" --new Initialize FILE to an empty database",
1545815504
" --nofollow Do not follow symbolic links",
1545915505
" --readonly Open FILE readonly",
1546015506
" --zip FILE is a ZIP archive",
15507
+#ifndef SQLITE_SHELL_WASM_MODE
1546115508
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
1546215509
" If FILE begins with '|' then open it as a pipe.",
1546315510
" Options:",
1546415511
" --bom Prefix output with a UTF8 byte-order mark",
1546515512
" -e Send output to the system text editor",
1546615513
" -x Send output as CSV to a spreadsheet",
15514
+#endif
1546715515
".parameter CMD ... Manage SQL parameter bindings",
1546815516
" clear Erase all bindings",
1546915517
" init Initialize the TEMP table that holds bindings",
1547015518
" list List the current parameter bindings",
1547115519
" set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
@@ -15478,23 +15526,27 @@
1547815526
" --once Do no more than one progress interrupt",
1547915527
" --quiet|-q No output except at interrupts",
1548015528
" --reset Reset the count for each input and interrupt",
1548115529
#endif
1548215530
".prompt MAIN CONTINUE Replace the standard prompts",
15531
+#ifndef SQLITE_SHELL_WASM_MODE
1548315532
".quit Exit this program",
1548415533
".read FILE Read input from FILE or command output",
1548515534
" If FILE begins with \"|\", it is a command that generates the input.",
15535
+#endif
1548615536
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1548715537
".recover Recover as much data as possible from corrupt db.",
1548815538
" --freelist-corrupt Assume the freelist is corrupt",
1548915539
" --recovery-db NAME Store recovery metadata in database file NAME",
1549015540
" --lost-and-found TABLE Alternative name for the lost-and-found table",
1549115541
" --no-rowids Do not attempt to recover rowid values",
1549215542
" that are not also INTEGER PRIMARY KEYs",
1549315543
#endif
15544
+#ifndef SQLITE_SHELL_WASM_MODE
1549415545
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
1549515546
".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
15547
+#endif
1549615548
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
1549715549
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
1549815550
" Options:",
1549915551
" --indent Try to pretty-print the schema",
1550015552
" --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15524,24 +15576,26 @@
1552415576
" --sha3-224 Use the sha3-224 algorithm",
1552515577
" --sha3-256 Use the sha3-256 algorithm (default)",
1552615578
" --sha3-384 Use the sha3-384 algorithm",
1552715579
" --sha3-512 Use the sha3-512 algorithm",
1552815580
" Any other argument is a LIKE pattern for tables to hash",
15529
-#ifndef SQLITE_NOHAVE_SYSTEM
15581
+#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
1553015582
".shell CMD ARGS... Run CMD ARGS... in a system shell",
1553115583
#endif
1553215584
".show Show the current values for various settings",
1553315585
".stats ?ARG? Show stats or turn stats on or off",
1553415586
" off Turn off automatic stat display",
1553515587
" on Turn on automatic stat display",
1553615588
" stmt Show statement stats",
1553715589
" vmstep Show the virtual machine step count only",
15538
-#ifndef SQLITE_NOHAVE_SYSTEM
15590
+#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
1553915591
".system CMD ARGS... Run CMD ARGS... in a system shell",
1554015592
#endif
1554115593
".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
15594
+#ifndef SQLITE_SHELL_WASM_MODE
1554215595
".testcase NAME Begin redirecting output to 'testcase-out.txt'",
15596
+#endif
1554315597
".testctrl CMD ... Run various sqlite3_test_control() operations",
1554415598
" Run \".testctrl\" with no arguments for details",
1554515599
".timeout MS Try opening locked tables for MS milliseconds",
1554615600
".timer on|off Turn SQL timer on or off",
1554715601
#ifndef SQLITE_OMIT_TRACE
@@ -16082,18 +16136,20 @@
1608216136
exit(1);
1608316137
}
1608416138
#ifndef SQLITE_OMIT_LOAD_EXTENSION
1608516139
sqlite3_enable_load_extension(p->db, 1);
1608616140
#endif
16087
- sqlite3_fileio_init(p->db, 0, 0);
1608816141
sqlite3_shathree_init(p->db, 0, 0);
16089
- sqlite3_completion_init(p->db, 0, 0);
1609016142
sqlite3_uint_init(p->db, 0, 0);
1609116143
sqlite3_decimal_init(p->db, 0, 0);
1609216144
sqlite3_regexp_init(p->db, 0, 0);
1609316145
sqlite3_ieee_init(p->db, 0, 0);
1609416146
sqlite3_series_init(p->db, 0, 0);
16147
+#ifndef SQLITE_SHELL_WASM_MODE
16148
+ sqlite3_fileio_init(p->db, 0, 0);
16149
+ sqlite3_completion_init(p->db, 0, 0);
16150
+#endif
1609516151
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1609616152
sqlite3_dbdata_init(p->db, 0, 0);
1609716153
#endif
1609816154
#ifdef SQLITE_HAVE_ZLIB
1609916155
if( !p->bSafeModePersist ){
@@ -16867,10 +16923,11 @@
1686716923
}
1686816924
sqlite3_finalize(pStmt);
1686916925
return res;
1687016926
}
1687116927
16928
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1687216929
/*
1687316930
** Convert a 2-byte or 4-byte big-endian integer into a native integer
1687416931
*/
1687516932
static unsigned int get2byteInt(unsigned char *a){
1687616933
return (a[0]<<8) + a[1];
@@ -16973,10 +17030,12 @@
1697317030
sqlite3_free(zSchemaTab);
1697417031
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
1697517032
utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
1697617033
return 0;
1697717034
}
17035
+#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE)
17036
+ && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
1697817037
1697917038
/*
1698017039
** Print the current sqlite3_errmsg() value to stderr and return 1.
1698117040
*/
1698217041
static int shellDatabaseError(sqlite3 *db){
@@ -19212,18 +19271,20 @@
1921219271
sqlite3_set_authorizer(p->db, 0, 0);
1921319272
}
1921419273
}else
1921519274
#endif
1921619275
19217
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
19276
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) \
19277
+ && !defined(SQLITE_SHELL_WASM_MODE)
1921819278
if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
1921919279
open_db(p, 0);
1922019280
failIfSafeMode(p, "cannot run .archive in safe mode");
1922119281
rc = arDotCommand(p, 0, azArg, nArg);
1922219282
}else
1922319283
#endif
1922419284
19285
+#ifndef SQLITE_SHELL_WASM_MODE
1922519286
if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
1922619287
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
1922719288
){
1922819289
const char *zDestFile = 0;
1922919290
const char *zDb = 0;
@@ -19288,10 +19349,11 @@
1928819349
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1928919350
rc = 1;
1929019351
}
1929119352
close_db(pDest);
1929219353
}else
19354
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
1929319355
1929419356
if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
1929519357
if( nArg==2 ){
1929619358
bail_on_error = booleanValue(azArg[1]);
1929719359
}else{
@@ -19318,10 +19380,11 @@
1931819380
*/
1931919381
if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1932019382
test_breakpoint();
1932119383
}else
1932219384
19385
+#ifndef SQLITE_SHELL_WASM_MODE
1932319386
if( c=='c' && strcmp(azArg[0],"cd")==0 ){
1932419387
failIfSafeMode(p, "cannot run .cd in safe mode");
1932519388
if( nArg==2 ){
1932619389
#if defined(_WIN32) || defined(WIN32)
1932719390
wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
@@ -19337,10 +19400,11 @@
1933719400
}else{
1933819401
raw_printf(stderr, "Usage: .cd DIRECTORY\n");
1933919402
rc = 1;
1934019403
}
1934119404
}else
19405
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
1934219406
1934319407
if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
1934419408
if( nArg==2 ){
1934519409
setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
1934619410
}else{
@@ -19347,10 +19411,11 @@
1934719411
raw_printf(stderr, "Usage: .changes on|off\n");
1934819412
rc = 1;
1934919413
}
1935019414
}else
1935119415
19416
+#ifndef SQLITE_SHELL_WASM_MODE
1935219417
/* Cancel output redirection, if it is currently set (by .testcase)
1935319418
** Then read the content of the testcase-out.txt file and compare against
1935419419
** azArg[1]. If there are differences, report an error and exit.
1935519420
*/
1935619421
if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
@@ -19371,20 +19436,23 @@
1937119436
utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
1937219437
p->nCheck++;
1937319438
}
1937419439
sqlite3_free(zRes);
1937519440
}else
19441
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
1937619442
19443
+#ifndef SQLITE_SHELL_WASM_MODE
1937719444
if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
1937819445
failIfSafeMode(p, "cannot run .clone in safe mode");
1937919446
if( nArg==2 ){
1938019447
tryToClone(p, azArg[1]);
1938119448
}else{
1938219449
raw_printf(stderr, "Usage: .clone FILENAME\n");
1938319450
rc = 1;
1938419451
}
1938519452
}else
19453
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
1938619454
1938719455
if( c=='c' && strncmp(azArg[0], "connection", n)==0 ){
1938819456
if( nArg==1 ){
1938919457
/* List available connections */
1939019458
int i;
@@ -19506,15 +19574,15 @@
1950619574
utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
1950719575
utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
1950819576
}
1950919577
}else
1951019578
19579
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1951119580
if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
1951219581
rc = shell_dbinfo_command(p, nArg, azArg);
1951319582
}else
1951419583
19515
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1951619584
if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
1951719585
open_db(p, 0);
1951819586
rc = recoverDatabaseCmd(p, nArg, azArg);
1951919587
}else
1952019588
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
@@ -19523,11 +19591,11 @@
1952319591
char *zLike = 0;
1952419592
char *zSql;
1952519593
int i;
1952619594
int savedShowHeader = p->showHeader;
1952719595
int savedShellFlags = p->shellFlgs;
19528
- ShellClearFlag(p,
19596
+ ShellClearFlag(p,
1952919597
SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
1953019598
|SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
1953119599
for(i=1; i<nArg; i++){
1953219600
if( azArg[i][0]=='-' ){
1953319601
const char *z = azArg[i]+1;
@@ -19669,14 +19737,16 @@
1966919737
raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
1967019738
rc = 1;
1967119739
}
1967219740
}else
1967319741
19742
+#ifndef SQLITE_SHELL_WASM_MODE
1967419743
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
1967519744
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
1967619745
rc = 2;
1967719746
}else
19747
+#endif
1967819748
1967919749
/* The ".explain" command is automatic now. It is largely pointless. It
1968019750
** retained purely for backwards compatibility */
1968119751
if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
1968219752
int val = 1;
@@ -19927,10 +19997,11 @@
1992719997
}else{
1992819998
showHelp(p->out, 0);
1992919999
}
1993020000
}else
1993120001
20002
+#ifndef SQLITE_SHELL_WASM_MODE
1993220003
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
1993320004
char *zTable = 0; /* Insert data into this table */
1993420005
char *zSchema = 0; /* within this schema (may default to "main") */
1993520006
char *zFile = 0; /* Name of file to extra content from */
1993620007
sqlite3_stmt *pStmt = NULL; /* A statement */
@@ -19948,20 +20019,16 @@
1994820019
int useOutputMode = 1; /* Use output mode to determine separators */
1994920020
char *zCreate = 0; /* CREATE TABLE statement text */
1995020021
1995120022
failIfSafeMode(p, "cannot run .import in safe mode");
1995220023
memset(&sCtx, 0, sizeof(sCtx));
19953
- sCtx.z = sqlite3_malloc64(120);
19954
- if( sCtx.z==0 ){
19955
- import_cleanup(&sCtx);
19956
- shell_out_of_memory();
19957
- }
1995820024
if( p->mode==MODE_Ascii ){
1995920025
xRead = ascii_read_one_field;
1996020026
}else{
1996120027
xRead = csv_read_one_field;
1996220028
}
20029
+ rc = 1;
1996320030
for(i=1; i<nArg; i++){
1996420031
char *z = azArg[i];
1996520032
if( z[0]=='-' && z[1]=='-' ) z++;
1996620033
if( z[0]!='-' ){
1996720034
if( zFile==0 ){
@@ -19969,11 +20036,10 @@
1996920036
}else if( zTable==0 ){
1997020037
zTable = z;
1997120038
}else{
1997220039
utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
1997320040
showHelp(p->out, "import");
19974
- rc = 1;
1997520041
goto meta_command_exit;
1997620042
}
1997720043
}else if( strcmp(z,"-v")==0 ){
1997820044
eVerbose++;
1997920045
}else if( strcmp(z,"-schema")==0 && i<nArg-1 ){
@@ -19991,19 +20057,17 @@
1999120057
xRead = csv_read_one_field;
1999220058
useOutputMode = 0;
1999320059
}else{
1999420060
utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
1999520061
showHelp(p->out, "import");
19996
- rc = 1;
1999720062
goto meta_command_exit;
1999820063
}
1999920064
}
2000020065
if( zTable==0 ){
2000120066
utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
2000220067
zFile==0 ? "FILE" : "TABLE");
2000320068
showHelp(p->out, "import");
20004
- rc = 1;
2000520069
goto meta_command_exit;
2000620070
}
2000720071
seenInterrupt = 0;
2000820072
open_db(p, 0);
2000920073
if( useOutputMode ){
@@ -20011,25 +20075,22 @@
2001120075
** the column and row separator characters from the output mode. */
2001220076
nSep = strlen30(p->colSeparator);
2001320077
if( nSep==0 ){
2001420078
raw_printf(stderr,
2001520079
"Error: non-null column separator required for import\n");
20016
- rc = 1;
2001720080
goto meta_command_exit;
2001820081
}
2001920082
if( nSep>1 ){
20020
- raw_printf(stderr,
20083
+ raw_printf(stderr,
2002120084
"Error: multi-character column separators not allowed"
2002220085
" for import\n");
20023
- rc = 1;
2002420086
goto meta_command_exit;
2002520087
}
2002620088
nSep = strlen30(p->rowSeparator);
2002720089
if( nSep==0 ){
2002820090
raw_printf(stderr,
2002920091
"Error: non-null row separator required for import\n");
20030
- rc = 1;
2003120092
goto meta_command_exit;
2003220093
}
2003320094
if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
2003420095
/* When importing CSV (only), if the row separator is set to the
2003520096
** default output row separator, change it to the default input
@@ -20039,11 +20100,10 @@
2003920100
nSep = strlen30(p->rowSeparator);
2004020101
}
2004120102
if( nSep>1 ){
2004220103
raw_printf(stderr, "Error: multi-character row separators not allowed"
2004320104
" for import\n");
20044
- rc = 1;
2004520105
goto meta_command_exit;
2004620106
}
2004720107
sCtx.cColSep = p->colSeparator[0];
2004820108
sCtx.cRowSep = p->rowSeparator[0];
2004920109
}
@@ -20050,11 +20110,10 @@
2005020110
sCtx.zFile = zFile;
2005120111
sCtx.nLine = 1;
2005220112
if( sCtx.zFile[0]=='|' ){
2005320113
#ifdef SQLITE_OMIT_POPEN
2005420114
raw_printf(stderr, "Error: pipes are not supported in this OS\n");
20055
- rc = 1;
2005620115
goto meta_command_exit;
2005720116
#else
2005820117
sCtx.in = popen(sCtx.zFile+1, "r");
2005920118
sCtx.zFile = "<pipe>";
2006020119
sCtx.xCloser = pclose;
@@ -20063,12 +20122,10 @@
2006320122
sCtx.in = fopen(sCtx.zFile, "rb");
2006420123
sCtx.xCloser = fclose;
2006520124
}
2006620125
if( sCtx.in==0 ){
2006720126
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
20068
- rc = 1;
20069
- import_cleanup(&sCtx);
2007020127
goto meta_command_exit;
2007120128
}
2007220129
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
2007320130
char zSep[2];
2007420131
zSep[1] = 0;
@@ -20077,10 +20134,15 @@
2007720134
output_c_string(p->out, zSep);
2007820135
utf8_printf(p->out, ", row separator ");
2007920136
zSep[0] = sCtx.cRowSep;
2008020137
output_c_string(p->out, zSep);
2008120138
utf8_printf(p->out, "\n");
20139
+ }
20140
+ sCtx.z = sqlite3_malloc64(120);
20141
+ if( sCtx.z==0 ){
20142
+ import_cleanup(&sCtx);
20143
+ shell_out_of_memory();
2008220144
}
2008320145
/* Below, resources must be freed before exit. */
2008420146
while( (nSkip--)>0 ){
2008520147
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
2008620148
}
@@ -20226,10 +20288,11 @@
2022620288
utf8_printf(p->out,
2022720289
"Added %d rows with %d errors using %d lines of input\n",
2022820290
sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
2022920291
}
2023020292
}else
20293
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
2023120294
2023220295
#ifndef SQLITE_UNTESTABLE
2023320296
if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
2023420297
char *zSql;
2023520298
char *zCollist = 0;
@@ -20415,11 +20478,11 @@
2041520478
if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
2041620479
open_db(p, 0);
2041720480
lintDotCommand(p, azArg, nArg);
2041820481
}else
2041920482
20420
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
20483
+#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_WASM_MODE)
2042120484
if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
2042220485
const char *zFile, *zProc;
2042320486
char *zErrMsg = 0;
2042420487
failIfSafeMode(p, "cannot run .load in safe mode");
2042520488
if( nArg<2 ){
@@ -20437,10 +20500,11 @@
2043720500
rc = 1;
2043820501
}
2043920502
}else
2044020503
#endif
2044120504
20505
+#ifndef SQLITE_SHELL_WASM_MODE
2044220506
if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
2044320507
failIfSafeMode(p, "cannot run .log in safe mode");
2044420508
if( nArg!=2 ){
2044520509
raw_printf(stderr, "Usage: .log FILENAME\n");
2044620510
rc = 1;
@@ -20448,10 +20512,11 @@
2044820512
const char *zFile = azArg[1];
2044920513
output_file_close(p->pLog);
2045020514
p->pLog = output_file_open(zFile, 0);
2045120515
}
2045220516
}else
20517
+#endif
2045320518
2045420519
if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
2045520520
const char *zMode = 0;
2045620521
const char *zTabname = 0;
2045720522
int i, n2;
@@ -20572,10 +20637,11 @@
2057220637
rc = 1;
2057320638
}
2057420639
p->cMode = p->mode;
2057520640
}else
2057620641
20642
+#ifndef SQLITE_SHELL_WASM_MODE
2057720643
if( c=='n' && strcmp(azArg[0], "nonce")==0 ){
2057820644
if( nArg!=2 ){
2057920645
raw_printf(stderr, "Usage: .nonce NONCE\n");
2058020646
rc = 1;
2058120647
}else if( p->zNonce==0 || strcmp(azArg[1],p->zNonce)!=0 ){
@@ -20586,10 +20652,11 @@
2058620652
p->bSafeMode = 0;
2058720653
return 0; /* Return immediately to bypass the safe mode reset
2058820654
** at the end of this procedure */
2058920655
}
2059020656
}else
20657
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
2059120658
2059220659
if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
2059320660
if( nArg==2 ){
2059420661
sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
2059520662
"%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
@@ -20607,10 +20674,11 @@
2060720674
int openMode = SHELL_OPEN_UNSPEC;
2060820675
2060920676
/* Check for command-line arguments */
2061020677
for(iName=1; iName<nArg; iName++){
2061120678
const char *z = azArg[iName];
20679
+#ifndef SQLITE_SHELL_WASM_MODE
2061220680
if( optionMatch(z,"new") ){
2061320681
newFlag = 1;
2061420682
#ifdef SQLITE_HAVE_ZLIB
2061520683
}else if( optionMatch(z, "zip") ){
2061620684
openMode = SHELL_OPEN_ZIPFILE;
@@ -20627,11 +20695,13 @@
2062720695
}else if( optionMatch(z, "hexdb") ){
2062820696
openMode = SHELL_OPEN_HEXDB;
2062920697
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
2063020698
p->szMax = integerValue(azArg[++iName]);
2063120699
#endif /* SQLITE_OMIT_DESERIALIZE */
20632
- }else if( z[0]=='-' ){
20700
+ }else
20701
+#endif /* !SQLITE_SHELL_WASM_MODE */
20702
+ if( z[0]=='-' ){
2063320703
utf8_printf(stderr, "unknown option: %s\n", z);
2063420704
rc = 1;
2063520705
goto meta_command_exit;
2063620706
}else if( zFN ){
2063720707
utf8_printf(stderr, "extra argument: \"%s\"\n", z);
@@ -20654,17 +20724,21 @@
2065420724
p->szMax = 0;
2065520725
2065620726
/* If a filename is specified, try to open it first */
2065720727
if( zFN || p->openMode==SHELL_OPEN_HEXDB ){
2065820728
if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN);
20729
+#ifndef SQLITE_SHELL_WASM_MODE
2065920730
if( p->bSafeMode
2066020731
&& p->openMode!=SHELL_OPEN_HEXDB
2066120732
&& zFN
2066220733
&& strcmp(zFN,":memory:")!=0
2066320734
){
2066420735
failIfSafeMode(p, "cannot open disk-based database files in safe mode");
2066520736
}
20737
+#else
20738
+ /* WASM mode has its own sandboxed pseudo-filesystem. */
20739
+#endif
2066620740
if( zFN ){
2066720741
zNewFilename = sqlite3_mprintf("%s", zFN);
2066820742
shell_check_oom(zNewFilename);
2066920743
}else{
2067020744
zNewFilename = 0;
@@ -20683,10 +20757,11 @@
2068320757
p->pAuxDb->zDbFilename = 0;
2068420758
open_db(p, 0);
2068520759
}
2068620760
}else
2068720761
20762
+#ifndef SQLITE_SHELL_WASM_MODE
2068820763
if( (c=='o'
2068920764
&& (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
2069020765
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
2069120766
){
2069220767
char *zFile = 0;
@@ -20798,10 +20873,11 @@
2079820873
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
2079920874
}
2080020875
}
2080120876
sqlite3_free(zFile);
2080220877
}else
20878
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
2080320879
2080420880
if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
2080520881
open_db(p,0);
2080620882
if( nArg<=1 ) goto parameter_syntax_error;
2080720883
@@ -20967,14 +21043,17 @@
2096721043
if( nArg >= 3) {
2096821044
strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2096921045
}
2097021046
}else
2097121047
21048
+#ifndef SQLITE_SHELL_WASM_MODE
2097221049
if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
2097321050
rc = 2;
2097421051
}else
21052
+#endif
2097521053
21054
+#ifndef SQLITE_SHELL_WASM_MODE
2097621055
if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
2097721056
FILE *inSaved = p->in;
2097821057
int savedLineno = p->lineno;
2097921058
failIfSafeMode(p, "cannot run .read in safe mode");
2098021059
if( nArg!=2 ){
@@ -21005,11 +21084,13 @@
2100521084
fclose(p->in);
2100621085
}
2100721086
p->in = inSaved;
2100821087
p->lineno = savedLineno;
2100921088
}else
21089
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
2101021090
21091
+#ifndef SQLITE_SHELL_WASM_MODE
2101121092
if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
2101221093
const char *zSrcFile;
2101321094
const char *zDb;
2101421095
sqlite3 *pSrc;
2101521096
sqlite3_backup *pBackup;
@@ -21057,10 +21138,11 @@
2105721138
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2105821139
rc = 1;
2105921140
}
2106021141
close_db(pSrc);
2106121142
}else
21143
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
2106221144
2106321145
if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
2106421146
if( nArg==2 ){
2106521147
p->scanstatsOn = (u8)booleanValue(azArg[1]);
2106621148
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
@@ -21682,11 +21764,11 @@
2168221764
shell_exec(p, zSql, 0);
2168321765
}
2168421766
sqlite3_free(zSql);
2168521767
}else
2168621768
21687
-#ifndef SQLITE_NOHAVE_SYSTEM
21769
+#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
2168821770
if( c=='s'
2168921771
&& (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
2169021772
){
2169121773
char *zCmd;
2169221774
int i, x;
@@ -21703,11 +21785,11 @@
2170321785
}
2170421786
x = zCmd!=0 ? system(zCmd) : 1;
2170521787
sqlite3_free(zCmd);
2170621788
if( x ) raw_printf(stderr, "System command returns %d\n", x);
2170721789
}else
21708
-#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
21790
+#endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE) */
2170921791
2171021792
if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
2171121793
static const char *azBool[] = { "off", "on", "trigger", "full"};
2171221794
const char *zOut;
2171321795
int i;
@@ -21715,11 +21797,11 @@
2171521797
raw_printf(stderr, "Usage: .show\n");
2171621798
rc = 1;
2171721799
goto meta_command_exit;
2171821800
}
2171921801
utf8_printf(p->out, "%12.12s: %s\n","echo",
21720
- azBool[ShellHasFlag(p, SHFLG_Echo)]);
21802
+ azBool[ShellHasFlag(p, SHFLG_Echo)]);
2172121803
utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
2172221804
utf8_printf(p->out, "%12.12s: %s\n","explain",
2172321805
p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
2172421806
utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
2172521807
if( p->mode==MODE_Column
@@ -21883,10 +21965,11 @@
2188321965
2188421966
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2188521967
sqlite3_free(azResult);
2188621968
}else
2188721969
21970
+#ifndef SQLITE_SHELL_WASM_MODE
2188821971
/* Begin redirecting output to the file "testcase-out.txt" */
2188921972
if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
2189021973
output_reset(p);
2189121974
p->out = output_file_open("testcase-out.txt", 0);
2189221975
if( p->out==0 ){
@@ -21896,10 +21979,11 @@
2189621979
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
2189721980
}else{
2189821981
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
2189921982
}
2190021983
}else
21984
+#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
2190121985
2190221986
#ifndef SQLITE_UNTESTABLE
2190321987
if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
2190421988
static const struct {
2190521989
const char *zCtrlName; /* Name of a test-control option */
@@ -22465,11 +22549,11 @@
2246522549
/* fall thru */
2246622550
case ']':
2246722551
cWait = 0;
2246822552
qss = QSS_SETV(qss, 0);
2246922553
goto PlainScan;
22470
- default: assert(0);
22554
+ default: assert(0);
2247122555
}
2247222556
}
2247322557
}
2247422558
}
2247522559
return qss;
@@ -22486,11 +22570,11 @@
2248622570
zLine += 1; /* Oracle */
2248722571
else if ( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' )
2248822572
zLine += 2; /* SQL Server */
2248922573
else
2249022574
return 0;
22491
- return quickscan(zLine,QSS_Start)==QSS_Start;
22575
+ return quickscan(zLine, QSS_Start)==QSS_Start;
2249222576
}
2249322577
2249422578
/*
2249522579
** We need a default sqlite3_complete() implementation to use in case
2249622580
** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
@@ -22563,10 +22647,46 @@
2256322647
raw_printf(p->out, "%s\n", zLineBuf);
2256422648
}
2256522649
return 0;
2256622650
}
2256722651
22652
+static void echo_group_input(ShellState *p, const char *zDo){
22653
+ if( ShellHasFlag(p, SHFLG_Echo) ) utf8_printf(p->out, "%s\n", zDo);
22654
+}
22655
+
22656
+#ifdef SQLITE_SHELL_WASM_MODE
22657
+/*
22658
+** Alternate one_input_line() impl for wasm mode. This is not in the primary impl
22659
+** because we need the global shellState and cannot access it from that function
22660
+** without moving lots of code around (creating a larger/messier diff).
22661
+*/
22662
+static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
22663
+ /* Parse the next line from shellState.wasm.zInput. */
22664
+ const char *zBegin = shellState.wasm.zPos;
22665
+ const char *z = zBegin;
22666
+ char *zLine = 0;
22667
+ int nZ = 0;
22668
+
22669
+ UNUSED_PARAMETER(in);
22670
+ UNUSED_PARAMETER(isContinuation);
22671
+ if(!z || !*z){
22672
+ return 0;
22673
+ }
22674
+ while(*z && isspace(*z)) ++z;
22675
+ zBegin = z;
22676
+ for(; *z && '\n'!=*z; ++nZ, ++z){}
22677
+ if(nZ>0 && '\r'==zBegin[nZ-1]){
22678
+ --nZ;
22679
+ }
22680
+ shellState.wasm.zPos = z;
22681
+ zLine = realloc(zPrior, nZ+1);
22682
+ shell_check_oom(zLine);
22683
+ memcpy(zLine, zBegin, (size_t)nZ);
22684
+ zLine[nZ] = 0;
22685
+ return zLine;
22686
+}
22687
+#endif /* SQLITE_SHELL_WASM_MODE */
2256822688
2256922689
/*
2257022690
** Read input from *in and process it. If *in==0 then input
2257122691
** is interactive - the user is typing it it. Otherwise, input
2257222692
** is coming from a file or device. A prompt is issued and history
@@ -22612,18 +22732,17 @@
2261222732
&& line_is_complete(zSql, nSql) ){
2261322733
memcpy(zLine,";",2);
2261422734
}
2261522735
qss = quickscan(zLine, qss);
2261622736
if( QSS_PLAINWHITE(qss) && nSql==0 ){
22617
- if( ShellHasFlag(p, SHFLG_Echo) )
22618
- printf("%s\n", zLine);
2261922737
/* Just swallow single-line whitespace */
22738
+ echo_group_input(p, zLine);
2262022739
qss = QSS_Start;
2262122740
continue;
2262222741
}
2262322742
if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
22624
- if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
22743
+ echo_group_input(p, zLine);
2262522744
if( zLine[0]=='.' ){
2262622745
rc = do_meta_command(zLine, p);
2262722746
if( rc==2 ){ /* exit requested */
2262822747
break;
2262922748
}else if( rc ){
@@ -22652,10 +22771,11 @@
2265222771
zSql[nSql++] = '\n';
2265322772
memcpy(zSql+nSql, zLine, nLine+1);
2265422773
nSql += nLine;
2265522774
}
2265622775
if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
22776
+ echo_group_input(p, zSql);
2265722777
errCnt += runOneSqlLine(p, zSql, p->in, startline);
2265822778
nSql = 0;
2265922779
if( p->outCount ){
2266022780
output_reset(p);
2266122781
p->outCount = 0;
@@ -22663,17 +22783,18 @@
2266322783
clearTempFile(p);
2266422784
}
2266522785
p->bSafeMode = p->bSafeModePersist;
2266622786
qss = QSS_Start;
2266722787
}else if( nSql && QSS_PLAINWHITE(qss) ){
22668
- if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
22788
+ echo_group_input(p, zSql);
2266922789
nSql = 0;
2267022790
qss = QSS_Start;
2267122791
}
2267222792
}
2267322793
if( nSql ){
2267422794
/* This may be incomplete. Let the SQL parser deal with that. */
22795
+ echo_group_input(p, zSql);
2267522796
errCnt += runOneSqlLine(p, zSql, p->in, startline);
2267622797
}
2267722798
free(zSql);
2267822799
free(zLine);
2267922800
--p->inputNesting;
@@ -22808,11 +22929,11 @@
2280822929
" -cmd COMMAND run \"COMMAND\" before reading stdin\n"
2280922930
" -csv set output mode to 'csv'\n"
2281022931
#if !defined(SQLITE_OMIT_DESERIALIZE)
2281122932
" -deserialize open the database using sqlite3_deserialize()\n"
2281222933
#endif
22813
- " -echo print commands before execution\n"
22934
+ " -echo print inputs before execution\n"
2281422935
" -init FILENAME read/process named file\n"
2281522936
" -[no]header turn headers on or off\n"
2281622937
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2281722938
" -heap SIZE Size of heap for memsys3 or memsys5\n"
2281822939
#endif
@@ -22943,19 +23064,30 @@
2294323064
# define SQLITE_SHELL_IS_UTF8 (0)
2294423065
# else
2294523066
# define SQLITE_SHELL_IS_UTF8 (1)
2294623067
# endif
2294723068
#endif
23069
+
23070
+#ifdef SQLITE_SHELL_WASM_MODE
23071
+# define main fiddle_main
23072
+#endif
2294823073
2294923074
#if SQLITE_SHELL_IS_UTF8
2295023075
int SQLITE_CDECL main(int argc, char **argv){
2295123076
#else
2295223077
int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
2295323078
char **argv;
2295423079
#endif
23080
+#ifdef SQLITE_DEBUG
23081
+ sqlite3_uint64 mem_main_enter = sqlite3_memory_used();
23082
+#endif
2295523083
char *zErrMsg = 0;
23084
+#ifdef SQLITE_SHELL_WASM_MODE
23085
+# define data shellState
23086
+#else
2295623087
ShellState data;
23088
+#endif
2295723089
const char *zInitFile = 0;
2295823090
int i;
2295923091
int rc = 0;
2296023092
int warnInmemoryDb = 0;
2296123093
int readStdin = 1;
@@ -22967,12 +23099,17 @@
2296723099
int argcToFree = 0;
2296823100
#endif
2296923101
2297023102
setBinaryMode(stdin, 0);
2297123103
setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
23104
+#ifdef SQLITE_SHELL_WASM_MODE
23105
+ stdin_is_interactive = 0;
23106
+ stdout_is_console = 1;
23107
+#else
2297223108
stdin_is_interactive = isatty(0);
2297323109
stdout_is_console = isatty(1);
23110
+#endif
2297423111
2297523112
#if !defined(_WIN32_WCE)
2297623113
if( getenv("SQLITE_DEBUG_BREAK") ){
2297723114
if( isatty(0) && isatty(2) ){
2297823115
fprintf(stderr,
@@ -23224,11 +23361,13 @@
2322423361
utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
2322523362
return 1;
2322623363
#endif
2322723364
}
2322823365
data.out = stdout;
23366
+#ifndef SQLITE_SHELL_WASM_MODE
2322923367
sqlite3_appendvfs_init(0,0,0);
23368
+#endif
2323023369
2323123370
/* Go ahead and open the database file if it already exists. If the
2323223371
** file does not exist, delay opening it. This prevents empty database
2323323372
** files from being created if a user mistypes the database name argument
2323423373
** to the sqlite command-line tool.
@@ -23490,10 +23629,13 @@
2349023629
}else{
2349123630
data.in = stdin;
2349223631
rc = process_input(&data);
2349323632
}
2349423633
}
23634
+#ifndef SQLITE_SHELL_WASM_MODE
23635
+ /* In WASM mode we have to leave the db state in place so that
23636
+ ** client code can "push" SQL into it after this call returns. */
2349523637
free(azCmd);
2349623638
set_table_name(&data, 0);
2349723639
if( data.db ){
2349823640
session_close_all(&data, -1);
2349923641
close_db(data.db);
@@ -23516,7 +23658,138 @@
2351623658
free(data.colWidth);
2351723659
free(data.zNonce);
2351823660
/* Clear the global data structure so that valgrind will detect memory
2351923661
** leaks */
2352023662
memset(&data, 0, sizeof(data));
23663
+#ifdef SQLITE_DEBUG
23664
+ if( sqlite3_memory_used()>mem_main_enter ){
23665
+ utf8_printf(stderr, "Memory leaked: %u bytes\n",
23666
+ (unsigned int)(sqlite3_memory_used()-mem_main_enter));
23667
+ }
23668
+#endif
23669
+#endif /* !SQLITE_SHELL_WASM_MODE */
2352123670
return rc;
2352223671
}
23672
+
23673
+
23674
+#ifdef SQLITE_SHELL_WASM_MODE
23675
+/* Only for emcc experimentation purposes. */
23676
+int fiddle_experiment(int a,int b){
23677
+ return a + b;
23678
+}
23679
+
23680
+/* Only for emcc experimentation purposes.
23681
+
23682
+ Define this function in JS using:
23683
+
23684
+ emcc ... --js-library somefile.js
23685
+
23686
+ containing:
23687
+
23688
+mergeInto(LibraryManager.library, {
23689
+ my_foo: function(){
23690
+ console.debug("my_foo()",arguments);
23691
+ }
23692
+});
23693
+*/
23694
+/*extern void my_foo(sqlite3 *);*/
23695
+/* Only for emcc experimentation purposes. */
23696
+sqlite3 * fiddle_the_db(){
23697
+ printf("fiddle_the_db(%p)\n", (const void*)globalDb);
23698
+ /*my_foo(globalDb);*/
23699
+ return globalDb;
23700
+}
23701
+/* Only for emcc experimentation purposes. */
23702
+sqlite3 * fiddle_db_arg(sqlite3 *arg){
23703
+ printf("fiddle_db_arg(%p)\n", (const void*)arg);
23704
+ return arg;
23705
+}
23706
+
23707
+/*
23708
+** Intended to be called via a SharedWorker() while a separate
23709
+** SharedWorker() (which manages the wasm module) is performing work
23710
+** which should be interrupted. Unfortunately, SharedWorker is not
23711
+** portable enough to make real use of.
23712
+*/
23713
+void fiddle_interrupt(void){
23714
+ if(globalDb) sqlite3_interrupt(globalDb);
23715
+}
23716
+
23717
+/*
23718
+** Returns the filename of the given db name, assuming "main" if
23719
+** zDbName is NULL. Returns NULL if globalDb is not opened.
23720
+*/
23721
+const char * fiddle_db_filename(const char * zDbName){
23722
+ return globalDb
23723
+ ? sqlite3_db_filename(globalDb, zDbName ? zDbName : "main")
23724
+ : NULL;
23725
+}
23726
+
23727
+/*
23728
+** Closes, unlinks, and reopens the db using its current filename (or
23729
+** the default if the db is currently closed). It is assumed, for
23730
+** purposes of the fiddle build, that the file is in a transient
23731
+** virtual filesystem within the browser.
23732
+*/
23733
+void fiddle_reset_db(void){
23734
+ char *zFilename = 0;
23735
+ if(0==globalDb){
23736
+ shellState.pAuxDb->zDbFilename = "/fiddle.sqlite3";
23737
+ }else{
23738
+ zFilename =
23739
+ sqlite3_mprintf("%s", sqlite3_db_filename(globalDb, "main"));
23740
+ shell_check_oom(zFilename);
23741
+ close_db(globalDb);
23742
+ shellDeleteFile(zFilename);
23743
+ shellState.db = 0;
23744
+ shellState.pAuxDb->zDbFilename = zFilename;
23745
+ }
23746
+ open_db(&shellState, 0);
23747
+ sqlite3_free(zFilename);
23748
+}
23749
+
23750
+/*
23751
+** Trivial exportable function for emscripten. Needs to be exported using:
23752
+**
23753
+** emcc ..flags... -sEXPORTED_FUNCTIONS=_fiddle_exec -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
23754
+**
23755
+** (Note the underscore before the function name.) It processes zSql
23756
+** as if it were input to the sqlite3 shell and redirects all output
23757
+** to the wasm binding.
23758
+*/
23759
+void fiddle_exec(const char * zSql){
23760
+ static int once = 0;
23761
+ int rc = 0;
23762
+ if(!once){
23763
+ /* Simulate an argv array for main() */
23764
+ static char * argv[] = {"fiddle",
23765
+ "-bail",
23766
+ "-safe"};
23767
+ rc = fiddle_main((int)(sizeof(argv)/sizeof(argv[0])), argv);
23768
+ once = rc ? -1 : 1;
23769
+ memset(&shellState.wasm, 0, sizeof(shellState.wasm));
23770
+ printf(
23771
+ "SQLite version %s %.19s\n" /*extra-version-info*/,
23772
+ sqlite3_libversion(), sqlite3_sourceid()
23773
+ );
23774
+ puts("WASM shell");
23775
+ puts("Enter \".help\" for usage hints.");
23776
+ if(once>0){
23777
+ fiddle_reset_db();
23778
+ }
23779
+ if(shellState.db){
23780
+ printf("Connected to %s.\n", fiddle_db_filename(NULL));
23781
+ }else{
23782
+ fprintf(stderr,"ERROR initializing db!\n");
23783
+ return;
23784
+ }
23785
+ }
23786
+ if(once<0){
23787
+ puts("DB init failed. Not executing SQL.");
23788
+ }else if(zSql && *zSql){
23789
+ shellState.wasm.zInput = zSql;
23790
+ shellState.wasm.zPos = zSql;
23791
+ process_input(&shellState);
23792
+ memset(&shellState.wasm, 0, sizeof(shellState.wasm));
23793
+ }
23794
+}
23795
+#endif /* SQLITE_SHELL_WASM_MODE */
2352323796
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -245,10 +245,20 @@
245 #else
246 # define setBinaryMode(X,Y)
247 # define setTextMode(X,Y)
248 #endif
249
 
 
 
 
 
 
 
 
 
 
250
251 /* True if the timer is enabled */
252 static int enableTimer = 0;
253
254 /* Return the current wall-clock time */
@@ -707,10 +717,11 @@
707 **
708 ** The result is stored in space obtained from malloc() and must either
709 ** be freed by the caller or else passed back into this routine via the
710 ** zPrior argument for reuse.
711 */
 
712 static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
713 char *zPrompt;
714 char *zResult;
715 if( in!=0 ){
716 zResult = local_getline(zPrior, in);
@@ -726,11 +737,11 @@
726 if( zResult && *zResult ) shell_add_history(zResult);
727 #endif
728 }
729 return zResult;
730 }
731
732
733 /*
734 ** Return the value of a hexadecimal digit. Return -1 if the input
735 ** is not a hex digit.
736 */
@@ -814,11 +825,11 @@
814 ** zIn, if it was not NULL, is freed.
815 **
816 ** If the third argument, quote, is not '\0', then it is used as a
817 ** quote character for zAppend.
818 */
819 static void appendText(ShellText *p, char const *zAppend, char quote){
820 int len;
821 int i;
822 int nAppend = strlen30(zAppend);
823
824 len = nAppend+p->n+1;
@@ -1379,10 +1390,121 @@
1379 #endif /* defined(WIN32) && defined(_MSC_VER) */
1380
1381 /************************* End test_windirent.c ********************/
1382 #define dirent DIRENT
1383 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1384 /************************* Begin ../ext/misc/shathree.c ******************/
1385 /*
1386 ** 2017-03-08
1387 **
1388 ** The author disclaims copyright to this source code. In place of
@@ -2106,2333 +2228,10 @@
2106 }
2107 return rc;
2108 }
2109
2110 /************************* End ../ext/misc/shathree.c ********************/
2111 /************************* Begin ../ext/misc/fileio.c ******************/
2112 /*
2113 ** 2014-06-13
2114 **
2115 ** The author disclaims copyright to this source code. In place of
2116 ** a legal notice, here is a blessing:
2117 **
2118 ** May you do good and not evil.
2119 ** May you find forgiveness for yourself and forgive others.
2120 ** May you share freely, never taking more than you give.
2121 **
2122 ******************************************************************************
2123 **
2124 ** This SQLite extension implements SQL functions readfile() and
2125 ** writefile(), and eponymous virtual type "fsdir".
2126 **
2127 ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
2128 **
2129 ** If neither of the optional arguments is present, then this UDF
2130 ** function writes blob DATA to file FILE. If successful, the number
2131 ** of bytes written is returned. If an error occurs, NULL is returned.
2132 **
2133 ** If the first option argument - MODE - is present, then it must
2134 ** be passed an integer value that corresponds to a POSIX mode
2135 ** value (file type + permissions, as returned in the stat.st_mode
2136 ** field by the stat() system call). Three types of files may
2137 ** be written/created:
2138 **
2139 ** regular files: (mode & 0170000)==0100000
2140 ** symbolic links: (mode & 0170000)==0120000
2141 ** directories: (mode & 0170000)==0040000
2142 **
2143 ** For a directory, the DATA is ignored. For a symbolic link, it is
2144 ** interpreted as text and used as the target of the link. For a
2145 ** regular file, it is interpreted as a blob and written into the
2146 ** named file. Regardless of the type of file, its permissions are
2147 ** set to (mode & 0777) before returning.
2148 **
2149 ** If the optional MTIME argument is present, then it is interpreted
2150 ** as an integer - the number of seconds since the unix epoch. The
2151 ** modification-time of the target file is set to this value before
2152 ** returning.
2153 **
2154 ** If three or more arguments are passed to this function and an
2155 ** error is encountered, an exception is raised.
2156 **
2157 ** READFILE(FILE):
2158 **
2159 ** Read and return the contents of file FILE (type blob) from disk.
2160 **
2161 ** FSDIR:
2162 **
2163 ** Used as follows:
2164 **
2165 ** SELECT * FROM fsdir($path [, $dir]);
2166 **
2167 ** Parameter $path is an absolute or relative pathname. If the file that it
2168 ** refers to does not exist, it is an error. If the path refers to a regular
2169 ** file or symbolic link, it returns a single row. Or, if the path refers
2170 ** to a directory, it returns one row for the directory, and one row for each
2171 ** file within the hierarchy rooted at $path.
2172 **
2173 ** Each row has the following columns:
2174 **
2175 ** name: Path to file or directory (text value).
2176 ** mode: Value of stat.st_mode for directory entry (an integer).
2177 ** mtime: Value of stat.st_mtime for directory entry (an integer).
2178 ** data: For a regular file, a blob containing the file data. For a
2179 ** symlink, a text value containing the text of the link. For a
2180 ** directory, NULL.
2181 **
2182 ** If a non-NULL value is specified for the optional $dir parameter and
2183 ** $path is a relative path, then $path is interpreted relative to $dir.
2184 ** And the paths returned in the "name" column of the table are also
2185 ** relative to directory $dir.
2186 **
2187 ** Notes on building this extension for Windows:
2188 ** Unless linked statically with the SQLite library, a preprocessor
2189 ** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
2190 ** DLL form of this extension for WIN32. See its use below for details.
2191 */
2192 /* #include "sqlite3ext.h" */
2193 SQLITE_EXTENSION_INIT1
2194 #include <stdio.h>
2195 #include <string.h>
2196 #include <assert.h>
2197
2198 #include <sys/types.h>
2199 #include <sys/stat.h>
2200 #include <fcntl.h>
2201 #if !defined(_WIN32) && !defined(WIN32)
2202 # include <unistd.h>
2203 # include <dirent.h>
2204 # include <utime.h>
2205 # include <sys/time.h>
2206 #else
2207 # include "windows.h"
2208 # include <io.h>
2209 # include <direct.h>
2210 /* # include "test_windirent.h" */
2211 # define dirent DIRENT
2212 # ifndef chmod
2213 # define chmod _chmod
2214 # endif
2215 # ifndef stat
2216 # define stat _stat
2217 # endif
2218 # define mkdir(path,mode) _mkdir(path)
2219 # define lstat(path,buf) stat(path,buf)
2220 #endif
2221 #include <time.h>
2222 #include <errno.h>
2223
2224
2225 /*
2226 ** Structure of the fsdir() table-valued function
2227 */
2228 /* 0 1 2 3 4 5 */
2229 #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
2230 #define FSDIR_COLUMN_NAME 0 /* Name of the file */
2231 #define FSDIR_COLUMN_MODE 1 /* Access mode */
2232 #define FSDIR_COLUMN_MTIME 2 /* Last modification time */
2233 #define FSDIR_COLUMN_DATA 3 /* File content */
2234 #define FSDIR_COLUMN_PATH 4 /* Path to top of search */
2235 #define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
2236
2237
2238 /*
2239 ** Set the result stored by context ctx to a blob containing the
2240 ** contents of file zName. Or, leave the result unchanged (NULL)
2241 ** if the file does not exist or is unreadable.
2242 **
2243 ** If the file exceeds the SQLite blob size limit, through an
2244 ** SQLITE_TOOBIG error.
2245 **
2246 ** Throw an SQLITE_IOERR if there are difficulties pulling the file
2247 ** off of disk.
2248 */
2249 static void readFileContents(sqlite3_context *ctx, const char *zName){
2250 FILE *in;
2251 sqlite3_int64 nIn;
2252 void *pBuf;
2253 sqlite3 *db;
2254 int mxBlob;
2255
2256 in = fopen(zName, "rb");
2257 if( in==0 ){
2258 /* File does not exist or is unreadable. Leave the result set to NULL. */
2259 return;
2260 }
2261 fseek(in, 0, SEEK_END);
2262 nIn = ftell(in);
2263 rewind(in);
2264 db = sqlite3_context_db_handle(ctx);
2265 mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
2266 if( nIn>mxBlob ){
2267 sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
2268 fclose(in);
2269 return;
2270 }
2271 pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
2272 if( pBuf==0 ){
2273 sqlite3_result_error_nomem(ctx);
2274 fclose(in);
2275 return;
2276 }
2277 if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
2278 sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
2279 }else{
2280 sqlite3_result_error_code(ctx, SQLITE_IOERR);
2281 sqlite3_free(pBuf);
2282 }
2283 fclose(in);
2284 }
2285
2286 /*
2287 ** Implementation of the "readfile(X)" SQL function. The entire content
2288 ** of the file named X is read and returned as a BLOB. NULL is returned
2289 ** if the file does not exist or is unreadable.
2290 */
2291 static void readfileFunc(
2292 sqlite3_context *context,
2293 int argc,
2294 sqlite3_value **argv
2295 ){
2296 const char *zName;
2297 (void)(argc); /* Unused parameter */
2298 zName = (const char*)sqlite3_value_text(argv[0]);
2299 if( zName==0 ) return;
2300 readFileContents(context, zName);
2301 }
2302
2303 /*
2304 ** Set the error message contained in context ctx to the results of
2305 ** vprintf(zFmt, ...).
2306 */
2307 static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
2308 char *zMsg = 0;
2309 va_list ap;
2310 va_start(ap, zFmt);
2311 zMsg = sqlite3_vmprintf(zFmt, ap);
2312 sqlite3_result_error(ctx, zMsg, -1);
2313 sqlite3_free(zMsg);
2314 va_end(ap);
2315 }
2316
2317 #if defined(_WIN32)
2318 /*
2319 ** This function is designed to convert a Win32 FILETIME structure into the
2320 ** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
2321 */
2322 static sqlite3_uint64 fileTimeToUnixTime(
2323 LPFILETIME pFileTime
2324 ){
2325 SYSTEMTIME epochSystemTime;
2326 ULARGE_INTEGER epochIntervals;
2327 FILETIME epochFileTime;
2328 ULARGE_INTEGER fileIntervals;
2329
2330 memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
2331 epochSystemTime.wYear = 1970;
2332 epochSystemTime.wMonth = 1;
2333 epochSystemTime.wDay = 1;
2334 SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
2335 epochIntervals.LowPart = epochFileTime.dwLowDateTime;
2336 epochIntervals.HighPart = epochFileTime.dwHighDateTime;
2337
2338 fileIntervals.LowPart = pFileTime->dwLowDateTime;
2339 fileIntervals.HighPart = pFileTime->dwHighDateTime;
2340
2341 return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
2342 }
2343
2344
2345 #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
2346 # /* To allow a standalone DLL, use this next replacement function: */
2347 # undef sqlite3_win32_utf8_to_unicode
2348 # define sqlite3_win32_utf8_to_unicode utf8_to_utf16
2349 #
2350 LPWSTR utf8_to_utf16(const char *z){
2351 int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
2352 LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
2353 if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
2354 return rv;
2355 sqlite3_free(rv);
2356 return 0;
2357 }
2358 #endif
2359
2360 /*
2361 ** This function attempts to normalize the time values found in the stat()
2362 ** buffer to UTC. This is necessary on Win32, where the runtime library
2363 ** appears to return these values as local times.
2364 */
2365 static void statTimesToUtc(
2366 const char *zPath,
2367 struct stat *pStatBuf
2368 ){
2369 HANDLE hFindFile;
2370 WIN32_FIND_DATAW fd;
2371 LPWSTR zUnicodeName;
2372 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
2373 zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
2374 if( zUnicodeName ){
2375 memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
2376 hFindFile = FindFirstFileW(zUnicodeName, &fd);
2377 if( hFindFile!=NULL ){
2378 pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
2379 pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
2380 pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
2381 FindClose(hFindFile);
2382 }
2383 sqlite3_free(zUnicodeName);
2384 }
2385 }
2386 #endif
2387
2388 /*
2389 ** This function is used in place of stat(). On Windows, special handling
2390 ** is required in order for the included time to be returned as UTC. On all
2391 ** other systems, this function simply calls stat().
2392 */
2393 static int fileStat(
2394 const char *zPath,
2395 struct stat *pStatBuf
2396 ){
2397 #if defined(_WIN32)
2398 int rc = stat(zPath, pStatBuf);
2399 if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
2400 return rc;
2401 #else
2402 return stat(zPath, pStatBuf);
2403 #endif
2404 }
2405
2406 /*
2407 ** This function is used in place of lstat(). On Windows, special handling
2408 ** is required in order for the included time to be returned as UTC. On all
2409 ** other systems, this function simply calls lstat().
2410 */
2411 static int fileLinkStat(
2412 const char *zPath,
2413 struct stat *pStatBuf
2414 ){
2415 #if defined(_WIN32)
2416 int rc = lstat(zPath, pStatBuf);
2417 if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
2418 return rc;
2419 #else
2420 return lstat(zPath, pStatBuf);
2421 #endif
2422 }
2423
2424 /*
2425 ** Argument zFile is the name of a file that will be created and/or written
2426 ** by SQL function writefile(). This function ensures that the directory
2427 ** zFile will be written to exists, creating it if required. The permissions
2428 ** for any path components created by this function are set in accordance
2429 ** with the current umask.
2430 **
2431 ** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
2432 ** SQLITE_OK is returned if the directory is successfully created, or
2433 ** SQLITE_ERROR otherwise.
2434 */
2435 static int makeDirectory(
2436 const char *zFile
2437 ){
2438 char *zCopy = sqlite3_mprintf("%s", zFile);
2439 int rc = SQLITE_OK;
2440
2441 if( zCopy==0 ){
2442 rc = SQLITE_NOMEM;
2443 }else{
2444 int nCopy = (int)strlen(zCopy);
2445 int i = 1;
2446
2447 while( rc==SQLITE_OK ){
2448 struct stat sStat;
2449 int rc2;
2450
2451 for(; zCopy[i]!='/' && i<nCopy; i++);
2452 if( i==nCopy ) break;
2453 zCopy[i] = '\0';
2454
2455 rc2 = fileStat(zCopy, &sStat);
2456 if( rc2!=0 ){
2457 if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
2458 }else{
2459 if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
2460 }
2461 zCopy[i] = '/';
2462 i++;
2463 }
2464
2465 sqlite3_free(zCopy);
2466 }
2467
2468 return rc;
2469 }
2470
2471 /*
2472 ** This function does the work for the writefile() UDF. Refer to
2473 ** header comments at the top of this file for details.
2474 */
2475 static int writeFile(
2476 sqlite3_context *pCtx, /* Context to return bytes written in */
2477 const char *zFile, /* File to write */
2478 sqlite3_value *pData, /* Data to write */
2479 mode_t mode, /* MODE parameter passed to writefile() */
2480 sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */
2481 ){
2482 if( zFile==0 ) return 1;
2483 #if !defined(_WIN32) && !defined(WIN32)
2484 if( S_ISLNK(mode) ){
2485 const char *zTo = (const char*)sqlite3_value_text(pData);
2486 if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
2487 }else
2488 #endif
2489 {
2490 if( S_ISDIR(mode) ){
2491 if( mkdir(zFile, mode) ){
2492 /* The mkdir() call to create the directory failed. This might not
2493 ** be an error though - if there is already a directory at the same
2494 ** path and either the permissions already match or can be changed
2495 ** to do so using chmod(), it is not an error. */
2496 struct stat sStat;
2497 if( errno!=EEXIST
2498 || 0!=fileStat(zFile, &sStat)
2499 || !S_ISDIR(sStat.st_mode)
2500 || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
2501 ){
2502 return 1;
2503 }
2504 }
2505 }else{
2506 sqlite3_int64 nWrite = 0;
2507 const char *z;
2508 int rc = 0;
2509 FILE *out = fopen(zFile, "wb");
2510 if( out==0 ) return 1;
2511 z = (const char*)sqlite3_value_blob(pData);
2512 if( z ){
2513 sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
2514 nWrite = sqlite3_value_bytes(pData);
2515 if( nWrite!=n ){
2516 rc = 1;
2517 }
2518 }
2519 fclose(out);
2520 if( rc==0 && mode && chmod(zFile, mode & 0777) ){
2521 rc = 1;
2522 }
2523 if( rc ) return 2;
2524 sqlite3_result_int64(pCtx, nWrite);
2525 }
2526 }
2527
2528 if( mtime>=0 ){
2529 #if defined(_WIN32)
2530 #if !SQLITE_OS_WINRT
2531 /* Windows */
2532 FILETIME lastAccess;
2533 FILETIME lastWrite;
2534 SYSTEMTIME currentTime;
2535 LONGLONG intervals;
2536 HANDLE hFile;
2537 LPWSTR zUnicodeName;
2538 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
2539
2540 GetSystemTime(&currentTime);
2541 SystemTimeToFileTime(&currentTime, &lastAccess);
2542 intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
2543 lastWrite.dwLowDateTime = (DWORD)intervals;
2544 lastWrite.dwHighDateTime = intervals >> 32;
2545 zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
2546 if( zUnicodeName==0 ){
2547 return 1;
2548 }
2549 hFile = CreateFileW(
2550 zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
2551 FILE_FLAG_BACKUP_SEMANTICS, NULL
2552 );
2553 sqlite3_free(zUnicodeName);
2554 if( hFile!=INVALID_HANDLE_VALUE ){
2555 BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
2556 CloseHandle(hFile);
2557 return !bResult;
2558 }else{
2559 return 1;
2560 }
2561 #endif
2562 #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
2563 /* Recent unix */
2564 struct timespec times[2];
2565 times[0].tv_nsec = times[1].tv_nsec = 0;
2566 times[0].tv_sec = time(0);
2567 times[1].tv_sec = mtime;
2568 if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
2569 return 1;
2570 }
2571 #else
2572 /* Legacy unix */
2573 struct timeval times[2];
2574 times[0].tv_usec = times[1].tv_usec = 0;
2575 times[0].tv_sec = time(0);
2576 times[1].tv_sec = mtime;
2577 if( utimes(zFile, times) ){
2578 return 1;
2579 }
2580 #endif
2581 }
2582
2583 return 0;
2584 }
2585
2586 /*
2587 ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
2588 ** Refer to header comments at the top of this file for details.
2589 */
2590 static void writefileFunc(
2591 sqlite3_context *context,
2592 int argc,
2593 sqlite3_value **argv
2594 ){
2595 const char *zFile;
2596 mode_t mode = 0;
2597 int res;
2598 sqlite3_int64 mtime = -1;
2599
2600 if( argc<2 || argc>4 ){
2601 sqlite3_result_error(context,
2602 "wrong number of arguments to function writefile()", -1
2603 );
2604 return;
2605 }
2606
2607 zFile = (const char*)sqlite3_value_text(argv[0]);
2608 if( zFile==0 ) return;
2609 if( argc>=3 ){
2610 mode = (mode_t)sqlite3_value_int(argv[2]);
2611 }
2612 if( argc==4 ){
2613 mtime = sqlite3_value_int64(argv[3]);
2614 }
2615
2616 res = writeFile(context, zFile, argv[1], mode, mtime);
2617 if( res==1 && errno==ENOENT ){
2618 if( makeDirectory(zFile)==SQLITE_OK ){
2619 res = writeFile(context, zFile, argv[1], mode, mtime);
2620 }
2621 }
2622
2623 if( argc>2 && res!=0 ){
2624 if( S_ISLNK(mode) ){
2625 ctxErrorMsg(context, "failed to create symlink: %s", zFile);
2626 }else if( S_ISDIR(mode) ){
2627 ctxErrorMsg(context, "failed to create directory: %s", zFile);
2628 }else{
2629 ctxErrorMsg(context, "failed to write file: %s", zFile);
2630 }
2631 }
2632 }
2633
2634 /*
2635 ** SQL function: lsmode(MODE)
2636 **
2637 ** Given a numberic st_mode from stat(), convert it into a human-readable
2638 ** text string in the style of "ls -l".
2639 */
2640 static void lsModeFunc(
2641 sqlite3_context *context,
2642 int argc,
2643 sqlite3_value **argv
2644 ){
2645 int i;
2646 int iMode = sqlite3_value_int(argv[0]);
2647 char z[16];
2648 (void)argc;
2649 if( S_ISLNK(iMode) ){
2650 z[0] = 'l';
2651 }else if( S_ISREG(iMode) ){
2652 z[0] = '-';
2653 }else if( S_ISDIR(iMode) ){
2654 z[0] = 'd';
2655 }else{
2656 z[0] = '?';
2657 }
2658 for(i=0; i<3; i++){
2659 int m = (iMode >> ((2-i)*3));
2660 char *a = &z[1 + i*3];
2661 a[0] = (m & 0x4) ? 'r' : '-';
2662 a[1] = (m & 0x2) ? 'w' : '-';
2663 a[2] = (m & 0x1) ? 'x' : '-';
2664 }
2665 z[10] = '\0';
2666 sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
2667 }
2668
2669 #ifndef SQLITE_OMIT_VIRTUALTABLE
2670
2671 /*
2672 ** Cursor type for recursively iterating through a directory structure.
2673 */
2674 typedef struct fsdir_cursor fsdir_cursor;
2675 typedef struct FsdirLevel FsdirLevel;
2676
2677 struct FsdirLevel {
2678 DIR *pDir; /* From opendir() */
2679 char *zDir; /* Name of directory (nul-terminated) */
2680 };
2681
2682 struct fsdir_cursor {
2683 sqlite3_vtab_cursor base; /* Base class - must be first */
2684
2685 int nLvl; /* Number of entries in aLvl[] array */
2686 int iLvl; /* Index of current entry */
2687 FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
2688
2689 const char *zBase;
2690 int nBase;
2691
2692 struct stat sStat; /* Current lstat() results */
2693 char *zPath; /* Path to current entry */
2694 sqlite3_int64 iRowid; /* Current rowid */
2695 };
2696
2697 typedef struct fsdir_tab fsdir_tab;
2698 struct fsdir_tab {
2699 sqlite3_vtab base; /* Base class - must be first */
2700 };
2701
2702 /*
2703 ** Construct a new fsdir virtual table object.
2704 */
2705 static int fsdirConnect(
2706 sqlite3 *db,
2707 void *pAux,
2708 int argc, const char *const*argv,
2709 sqlite3_vtab **ppVtab,
2710 char **pzErr
2711 ){
2712 fsdir_tab *pNew = 0;
2713 int rc;
2714 (void)pAux;
2715 (void)argc;
2716 (void)argv;
2717 (void)pzErr;
2718 rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
2719 if( rc==SQLITE_OK ){
2720 pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
2721 if( pNew==0 ) return SQLITE_NOMEM;
2722 memset(pNew, 0, sizeof(*pNew));
2723 sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
2724 }
2725 *ppVtab = (sqlite3_vtab*)pNew;
2726 return rc;
2727 }
2728
2729 /*
2730 ** This method is the destructor for fsdir vtab objects.
2731 */
2732 static int fsdirDisconnect(sqlite3_vtab *pVtab){
2733 sqlite3_free(pVtab);
2734 return SQLITE_OK;
2735 }
2736
2737 /*
2738 ** Constructor for a new fsdir_cursor object.
2739 */
2740 static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
2741 fsdir_cursor *pCur;
2742 (void)p;
2743 pCur = sqlite3_malloc( sizeof(*pCur) );
2744 if( pCur==0 ) return SQLITE_NOMEM;
2745 memset(pCur, 0, sizeof(*pCur));
2746 pCur->iLvl = -1;
2747 *ppCursor = &pCur->base;
2748 return SQLITE_OK;
2749 }
2750
2751 /*
2752 ** Reset a cursor back to the state it was in when first returned
2753 ** by fsdirOpen().
2754 */
2755 static void fsdirResetCursor(fsdir_cursor *pCur){
2756 int i;
2757 for(i=0; i<=pCur->iLvl; i++){
2758 FsdirLevel *pLvl = &pCur->aLvl[i];
2759 if( pLvl->pDir ) closedir(pLvl->pDir);
2760 sqlite3_free(pLvl->zDir);
2761 }
2762 sqlite3_free(pCur->zPath);
2763 sqlite3_free(pCur->aLvl);
2764 pCur->aLvl = 0;
2765 pCur->zPath = 0;
2766 pCur->zBase = 0;
2767 pCur->nBase = 0;
2768 pCur->nLvl = 0;
2769 pCur->iLvl = -1;
2770 pCur->iRowid = 1;
2771 }
2772
2773 /*
2774 ** Destructor for an fsdir_cursor.
2775 */
2776 static int fsdirClose(sqlite3_vtab_cursor *cur){
2777 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2778
2779 fsdirResetCursor(pCur);
2780 sqlite3_free(pCur);
2781 return SQLITE_OK;
2782 }
2783
2784 /*
2785 ** Set the error message for the virtual table associated with cursor
2786 ** pCur to the results of vprintf(zFmt, ...).
2787 */
2788 static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
2789 va_list ap;
2790 va_start(ap, zFmt);
2791 pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
2792 va_end(ap);
2793 }
2794
2795
2796 /*
2797 ** Advance an fsdir_cursor to its next row of output.
2798 */
2799 static int fsdirNext(sqlite3_vtab_cursor *cur){
2800 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2801 mode_t m = pCur->sStat.st_mode;
2802
2803 pCur->iRowid++;
2804 if( S_ISDIR(m) ){
2805 /* Descend into this directory */
2806 int iNew = pCur->iLvl + 1;
2807 FsdirLevel *pLvl;
2808 if( iNew>=pCur->nLvl ){
2809 int nNew = iNew+1;
2810 sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
2811 FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
2812 if( aNew==0 ) return SQLITE_NOMEM;
2813 memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
2814 pCur->aLvl = aNew;
2815 pCur->nLvl = nNew;
2816 }
2817 pCur->iLvl = iNew;
2818 pLvl = &pCur->aLvl[iNew];
2819
2820 pLvl->zDir = pCur->zPath;
2821 pCur->zPath = 0;
2822 pLvl->pDir = opendir(pLvl->zDir);
2823 if( pLvl->pDir==0 ){
2824 fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
2825 return SQLITE_ERROR;
2826 }
2827 }
2828
2829 while( pCur->iLvl>=0 ){
2830 FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
2831 struct dirent *pEntry = readdir(pLvl->pDir);
2832 if( pEntry ){
2833 if( pEntry->d_name[0]=='.' ){
2834 if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
2835 if( pEntry->d_name[1]=='\0' ) continue;
2836 }
2837 sqlite3_free(pCur->zPath);
2838 pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
2839 if( pCur->zPath==0 ) return SQLITE_NOMEM;
2840 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
2841 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
2842 return SQLITE_ERROR;
2843 }
2844 return SQLITE_OK;
2845 }
2846 closedir(pLvl->pDir);
2847 sqlite3_free(pLvl->zDir);
2848 pLvl->pDir = 0;
2849 pLvl->zDir = 0;
2850 pCur->iLvl--;
2851 }
2852
2853 /* EOF */
2854 sqlite3_free(pCur->zPath);
2855 pCur->zPath = 0;
2856 return SQLITE_OK;
2857 }
2858
2859 /*
2860 ** Return values of columns for the row at which the series_cursor
2861 ** is currently pointing.
2862 */
2863 static int fsdirColumn(
2864 sqlite3_vtab_cursor *cur, /* The cursor */
2865 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
2866 int i /* Which column to return */
2867 ){
2868 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2869 switch( i ){
2870 case FSDIR_COLUMN_NAME: {
2871 sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
2872 break;
2873 }
2874
2875 case FSDIR_COLUMN_MODE:
2876 sqlite3_result_int64(ctx, pCur->sStat.st_mode);
2877 break;
2878
2879 case FSDIR_COLUMN_MTIME:
2880 sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
2881 break;
2882
2883 case FSDIR_COLUMN_DATA: {
2884 mode_t m = pCur->sStat.st_mode;
2885 if( S_ISDIR(m) ){
2886 sqlite3_result_null(ctx);
2887 #if !defined(_WIN32) && !defined(WIN32)
2888 }else if( S_ISLNK(m) ){
2889 char aStatic[64];
2890 char *aBuf = aStatic;
2891 sqlite3_int64 nBuf = 64;
2892 int n;
2893
2894 while( 1 ){
2895 n = readlink(pCur->zPath, aBuf, nBuf);
2896 if( n<nBuf ) break;
2897 if( aBuf!=aStatic ) sqlite3_free(aBuf);
2898 nBuf = nBuf*2;
2899 aBuf = sqlite3_malloc64(nBuf);
2900 if( aBuf==0 ){
2901 sqlite3_result_error_nomem(ctx);
2902 return SQLITE_NOMEM;
2903 }
2904 }
2905
2906 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
2907 if( aBuf!=aStatic ) sqlite3_free(aBuf);
2908 #endif
2909 }else{
2910 readFileContents(ctx, pCur->zPath);
2911 }
2912 }
2913 case FSDIR_COLUMN_PATH:
2914 default: {
2915 /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
2916 ** always return their values as NULL */
2917 break;
2918 }
2919 }
2920 return SQLITE_OK;
2921 }
2922
2923 /*
2924 ** Return the rowid for the current row. In this implementation, the
2925 ** first row returned is assigned rowid value 1, and each subsequent
2926 ** row a value 1 more than that of the previous.
2927 */
2928 static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
2929 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2930 *pRowid = pCur->iRowid;
2931 return SQLITE_OK;
2932 }
2933
2934 /*
2935 ** Return TRUE if the cursor has been moved off of the last
2936 ** row of output.
2937 */
2938 static int fsdirEof(sqlite3_vtab_cursor *cur){
2939 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2940 return (pCur->zPath==0);
2941 }
2942
2943 /*
2944 ** xFilter callback.
2945 **
2946 ** idxNum==1 PATH parameter only
2947 ** idxNum==2 Both PATH and DIR supplied
2948 */
2949 static int fsdirFilter(
2950 sqlite3_vtab_cursor *cur,
2951 int idxNum, const char *idxStr,
2952 int argc, sqlite3_value **argv
2953 ){
2954 const char *zDir = 0;
2955 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2956 (void)idxStr;
2957 fsdirResetCursor(pCur);
2958
2959 if( idxNum==0 ){
2960 fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
2961 return SQLITE_ERROR;
2962 }
2963
2964 assert( argc==idxNum && (argc==1 || argc==2) );
2965 zDir = (const char*)sqlite3_value_text(argv[0]);
2966 if( zDir==0 ){
2967 fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
2968 return SQLITE_ERROR;
2969 }
2970 if( argc==2 ){
2971 pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
2972 }
2973 if( pCur->zBase ){
2974 pCur->nBase = (int)strlen(pCur->zBase)+1;
2975 pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
2976 }else{
2977 pCur->zPath = sqlite3_mprintf("%s", zDir);
2978 }
2979
2980 if( pCur->zPath==0 ){
2981 return SQLITE_NOMEM;
2982 }
2983 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
2984 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
2985 return SQLITE_ERROR;
2986 }
2987
2988 return SQLITE_OK;
2989 }
2990
2991 /*
2992 ** SQLite will invoke this method one or more times while planning a query
2993 ** that uses the generate_series virtual table. This routine needs to create
2994 ** a query plan for each invocation and compute an estimated cost for that
2995 ** plan.
2996 **
2997 ** In this implementation idxNum is used to represent the
2998 ** query plan. idxStr is unused.
2999 **
3000 ** The query plan is represented by values of idxNum:
3001 **
3002 ** (1) The path value is supplied by argv[0]
3003 ** (2) Path is in argv[0] and dir is in argv[1]
3004 */
3005 static int fsdirBestIndex(
3006 sqlite3_vtab *tab,
3007 sqlite3_index_info *pIdxInfo
3008 ){
3009 int i; /* Loop over constraints */
3010 int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
3011 int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
3012 int seenPath = 0; /* True if an unusable PATH= constraint is seen */
3013 int seenDir = 0; /* True if an unusable DIR= constraint is seen */
3014 const struct sqlite3_index_constraint *pConstraint;
3015
3016 (void)tab;
3017 pConstraint = pIdxInfo->aConstraint;
3018 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
3019 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
3020 switch( pConstraint->iColumn ){
3021 case FSDIR_COLUMN_PATH: {
3022 if( pConstraint->usable ){
3023 idxPath = i;
3024 seenPath = 0;
3025 }else if( idxPath<0 ){
3026 seenPath = 1;
3027 }
3028 break;
3029 }
3030 case FSDIR_COLUMN_DIR: {
3031 if( pConstraint->usable ){
3032 idxDir = i;
3033 seenDir = 0;
3034 }else if( idxDir<0 ){
3035 seenDir = 1;
3036 }
3037 break;
3038 }
3039 }
3040 }
3041 if( seenPath || seenDir ){
3042 /* If input parameters are unusable, disallow this plan */
3043 return SQLITE_CONSTRAINT;
3044 }
3045
3046 if( idxPath<0 ){
3047 pIdxInfo->idxNum = 0;
3048 /* The pIdxInfo->estimatedCost should have been initialized to a huge
3049 ** number. Leave it unchanged. */
3050 pIdxInfo->estimatedRows = 0x7fffffff;
3051 }else{
3052 pIdxInfo->aConstraintUsage[idxPath].omit = 1;
3053 pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
3054 if( idxDir>=0 ){
3055 pIdxInfo->aConstraintUsage[idxDir].omit = 1;
3056 pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
3057 pIdxInfo->idxNum = 2;
3058 pIdxInfo->estimatedCost = 10.0;
3059 }else{
3060 pIdxInfo->idxNum = 1;
3061 pIdxInfo->estimatedCost = 100.0;
3062 }
3063 }
3064
3065 return SQLITE_OK;
3066 }
3067
3068 /*
3069 ** Register the "fsdir" virtual table.
3070 */
3071 static int fsdirRegister(sqlite3 *db){
3072 static sqlite3_module fsdirModule = {
3073 0, /* iVersion */
3074 0, /* xCreate */
3075 fsdirConnect, /* xConnect */
3076 fsdirBestIndex, /* xBestIndex */
3077 fsdirDisconnect, /* xDisconnect */
3078 0, /* xDestroy */
3079 fsdirOpen, /* xOpen - open a cursor */
3080 fsdirClose, /* xClose - close a cursor */
3081 fsdirFilter, /* xFilter - configure scan constraints */
3082 fsdirNext, /* xNext - advance a cursor */
3083 fsdirEof, /* xEof - check for end of scan */
3084 fsdirColumn, /* xColumn - read data */
3085 fsdirRowid, /* xRowid - read data */
3086 0, /* xUpdate */
3087 0, /* xBegin */
3088 0, /* xSync */
3089 0, /* xCommit */
3090 0, /* xRollback */
3091 0, /* xFindMethod */
3092 0, /* xRename */
3093 0, /* xSavepoint */
3094 0, /* xRelease */
3095 0, /* xRollbackTo */
3096 0, /* xShadowName */
3097 };
3098
3099 int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
3100 return rc;
3101 }
3102 #else /* SQLITE_OMIT_VIRTUALTABLE */
3103 # define fsdirRegister(x) SQLITE_OK
3104 #endif
3105
3106 #ifdef _WIN32
3107
3108 #endif
3109 int sqlite3_fileio_init(
3110 sqlite3 *db,
3111 char **pzErrMsg,
3112 const sqlite3_api_routines *pApi
3113 ){
3114 int rc = SQLITE_OK;
3115 SQLITE_EXTENSION_INIT2(pApi);
3116 (void)pzErrMsg; /* Unused parameter */
3117 rc = sqlite3_create_function(db, "readfile", 1,
3118 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
3119 readfileFunc, 0, 0);
3120 if( rc==SQLITE_OK ){
3121 rc = sqlite3_create_function(db, "writefile", -1,
3122 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
3123 writefileFunc, 0, 0);
3124 }
3125 if( rc==SQLITE_OK ){
3126 rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
3127 lsModeFunc, 0, 0);
3128 }
3129 if( rc==SQLITE_OK ){
3130 rc = fsdirRegister(db);
3131 }
3132 return rc;
3133 }
3134
3135 #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
3136 /* To allow a standalone DLL, make test_windirent.c use the same
3137 * redefined SQLite API calls as the above extension code does.
3138 * Just pull in this .c to accomplish this. As a beneficial side
3139 * effect, this extension becomes a single translation unit. */
3140 # include "test_windirent.c"
3141 #endif
3142
3143 /************************* End ../ext/misc/fileio.c ********************/
3144 /************************* Begin ../ext/misc/completion.c ******************/
3145 /*
3146 ** 2017-07-10
3147 **
3148 ** The author disclaims copyright to this source code. In place of
3149 ** a legal notice, here is a blessing:
3150 **
3151 ** May you do good and not evil.
3152 ** May you find forgiveness for yourself and forgive others.
3153 ** May you share freely, never taking more than you give.
3154 **
3155 *************************************************************************
3156 **
3157 ** This file implements an eponymous virtual table that returns suggested
3158 ** completions for a partial SQL input.
3159 **
3160 ** Suggested usage:
3161 **
3162 ** SELECT DISTINCT candidate COLLATE nocase
3163 ** FROM completion($prefix,$wholeline)
3164 ** ORDER BY 1;
3165 **
3166 ** The two query parameters are optional. $prefix is the text of the
3167 ** current word being typed and that is to be completed. $wholeline is
3168 ** the complete input line, used for context.
3169 **
3170 ** The raw completion() table might return the same candidate multiple
3171 ** times, for example if the same column name is used to two or more
3172 ** tables. And the candidates are returned in an arbitrary order. Hence,
3173 ** the DISTINCT and ORDER BY are recommended.
3174 **
3175 ** This virtual table operates at the speed of human typing, and so there
3176 ** is no attempt to make it fast. Even a slow implementation will be much
3177 ** faster than any human can type.
3178 **
3179 */
3180 /* #include "sqlite3ext.h" */
3181 SQLITE_EXTENSION_INIT1
3182 #include <assert.h>
3183 #include <string.h>
3184 #include <ctype.h>
3185
3186 #ifndef SQLITE_OMIT_VIRTUALTABLE
3187
3188 /* completion_vtab is a subclass of sqlite3_vtab which will
3189 ** serve as the underlying representation of a completion virtual table
3190 */
3191 typedef struct completion_vtab completion_vtab;
3192 struct completion_vtab {
3193 sqlite3_vtab base; /* Base class - must be first */
3194 sqlite3 *db; /* Database connection for this completion vtab */
3195 };
3196
3197 /* completion_cursor is a subclass of sqlite3_vtab_cursor which will
3198 ** serve as the underlying representation of a cursor that scans
3199 ** over rows of the result
3200 */
3201 typedef struct completion_cursor completion_cursor;
3202 struct completion_cursor {
3203 sqlite3_vtab_cursor base; /* Base class - must be first */
3204 sqlite3 *db; /* Database connection for this cursor */
3205 int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */
3206 char *zPrefix; /* The prefix for the word we want to complete */
3207 char *zLine; /* The whole that we want to complete */
3208 const char *zCurrentRow; /* Current output row */
3209 int szRow; /* Length of the zCurrentRow string */
3210 sqlite3_stmt *pStmt; /* Current statement */
3211 sqlite3_int64 iRowid; /* The rowid */
3212 int ePhase; /* Current phase */
3213 int j; /* inter-phase counter */
3214 };
3215
3216 /* Values for ePhase:
3217 */
3218 #define COMPLETION_FIRST_PHASE 1
3219 #define COMPLETION_KEYWORDS 1
3220 #define COMPLETION_PRAGMAS 2
3221 #define COMPLETION_FUNCTIONS 3
3222 #define COMPLETION_COLLATIONS 4
3223 #define COMPLETION_INDEXES 5
3224 #define COMPLETION_TRIGGERS 6
3225 #define COMPLETION_DATABASES 7
3226 #define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */
3227 #define COMPLETION_COLUMNS 9
3228 #define COMPLETION_MODULES 10
3229 #define COMPLETION_EOF 11
3230
3231 /*
3232 ** The completionConnect() method is invoked to create a new
3233 ** completion_vtab that describes the completion virtual table.
3234 **
3235 ** Think of this routine as the constructor for completion_vtab objects.
3236 **
3237 ** All this routine needs to do is:
3238 **
3239 ** (1) Allocate the completion_vtab object and initialize all fields.
3240 **
3241 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
3242 ** result set of queries against completion will look like.
3243 */
3244 static int completionConnect(
3245 sqlite3 *db,
3246 void *pAux,
3247 int argc, const char *const*argv,
3248 sqlite3_vtab **ppVtab,
3249 char **pzErr
3250 ){
3251 completion_vtab *pNew;
3252 int rc;
3253
3254 (void)(pAux); /* Unused parameter */
3255 (void)(argc); /* Unused parameter */
3256 (void)(argv); /* Unused parameter */
3257 (void)(pzErr); /* Unused parameter */
3258
3259 /* Column numbers */
3260 #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
3261 #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
3262 #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
3263 #define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
3264
3265 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
3266 rc = sqlite3_declare_vtab(db,
3267 "CREATE TABLE x("
3268 " candidate TEXT,"
3269 " prefix TEXT HIDDEN,"
3270 " wholeline TEXT HIDDEN,"
3271 " phase INT HIDDEN" /* Used for debugging only */
3272 ")");
3273 if( rc==SQLITE_OK ){
3274 pNew = sqlite3_malloc( sizeof(*pNew) );
3275 *ppVtab = (sqlite3_vtab*)pNew;
3276 if( pNew==0 ) return SQLITE_NOMEM;
3277 memset(pNew, 0, sizeof(*pNew));
3278 pNew->db = db;
3279 }
3280 return rc;
3281 }
3282
3283 /*
3284 ** This method is the destructor for completion_cursor objects.
3285 */
3286 static int completionDisconnect(sqlite3_vtab *pVtab){
3287 sqlite3_free(pVtab);
3288 return SQLITE_OK;
3289 }
3290
3291 /*
3292 ** Constructor for a new completion_cursor object.
3293 */
3294 static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
3295 completion_cursor *pCur;
3296 pCur = sqlite3_malloc( sizeof(*pCur) );
3297 if( pCur==0 ) return SQLITE_NOMEM;
3298 memset(pCur, 0, sizeof(*pCur));
3299 pCur->db = ((completion_vtab*)p)->db;
3300 *ppCursor = &pCur->base;
3301 return SQLITE_OK;
3302 }
3303
3304 /*
3305 ** Reset the completion_cursor.
3306 */
3307 static void completionCursorReset(completion_cursor *pCur){
3308 sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0;
3309 sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0;
3310 sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
3311 pCur->j = 0;
3312 }
3313
3314 /*
3315 ** Destructor for a completion_cursor.
3316 */
3317 static int completionClose(sqlite3_vtab_cursor *cur){
3318 completionCursorReset((completion_cursor*)cur);
3319 sqlite3_free(cur);
3320 return SQLITE_OK;
3321 }
3322
3323 /*
3324 ** Advance a completion_cursor to its next row of output.
3325 **
3326 ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
3327 ** record the current state of the scan. This routine sets ->zCurrentRow
3328 ** to the current row of output and then returns. If no more rows remain,
3329 ** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
3330 ** table that has reached the end of its scan.
3331 **
3332 ** The current implementation just lists potential identifiers and
3333 ** keywords and filters them by zPrefix. Future enhancements should
3334 ** take zLine into account to try to restrict the set of identifiers and
3335 ** keywords based on what would be legal at the current point of input.
3336 */
3337 static int completionNext(sqlite3_vtab_cursor *cur){
3338 completion_cursor *pCur = (completion_cursor*)cur;
3339 int eNextPhase = 0; /* Next phase to try if current phase reaches end */
3340 int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
3341 pCur->iRowid++;
3342 while( pCur->ePhase!=COMPLETION_EOF ){
3343 switch( pCur->ePhase ){
3344 case COMPLETION_KEYWORDS: {
3345 if( pCur->j >= sqlite3_keyword_count() ){
3346 pCur->zCurrentRow = 0;
3347 pCur->ePhase = COMPLETION_DATABASES;
3348 }else{
3349 sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
3350 }
3351 iCol = -1;
3352 break;
3353 }
3354 case COMPLETION_DATABASES: {
3355 if( pCur->pStmt==0 ){
3356 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
3357 &pCur->pStmt, 0);
3358 }
3359 iCol = 1;
3360 eNextPhase = COMPLETION_TABLES;
3361 break;
3362 }
3363 case COMPLETION_TABLES: {
3364 if( pCur->pStmt==0 ){
3365 sqlite3_stmt *pS2;
3366 char *zSql = 0;
3367 const char *zSep = "";
3368 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
3369 while( sqlite3_step(pS2)==SQLITE_ROW ){
3370 const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
3371 zSql = sqlite3_mprintf(
3372 "%z%s"
3373 "SELECT name FROM \"%w\".sqlite_schema",
3374 zSql, zSep, zDb
3375 );
3376 if( zSql==0 ) return SQLITE_NOMEM;
3377 zSep = " UNION ";
3378 }
3379 sqlite3_finalize(pS2);
3380 sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
3381 sqlite3_free(zSql);
3382 }
3383 iCol = 0;
3384 eNextPhase = COMPLETION_COLUMNS;
3385 break;
3386 }
3387 case COMPLETION_COLUMNS: {
3388 if( pCur->pStmt==0 ){
3389 sqlite3_stmt *pS2;
3390 char *zSql = 0;
3391 const char *zSep = "";
3392 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
3393 while( sqlite3_step(pS2)==SQLITE_ROW ){
3394 const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
3395 zSql = sqlite3_mprintf(
3396 "%z%s"
3397 "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
3398 " JOIN pragma_table_info(sm.name,%Q) AS pti"
3399 " WHERE sm.type='table'",
3400 zSql, zSep, zDb, zDb
3401 );
3402 if( zSql==0 ) return SQLITE_NOMEM;
3403 zSep = " UNION ";
3404 }
3405 sqlite3_finalize(pS2);
3406 sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
3407 sqlite3_free(zSql);
3408 }
3409 iCol = 0;
3410 eNextPhase = COMPLETION_EOF;
3411 break;
3412 }
3413 }
3414 if( iCol<0 ){
3415 /* This case is when the phase presets zCurrentRow */
3416 if( pCur->zCurrentRow==0 ) continue;
3417 }else{
3418 if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
3419 /* Extract the next row of content */
3420 pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
3421 pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
3422 }else{
3423 /* When all rows are finished, advance to the next phase */
3424 sqlite3_finalize(pCur->pStmt);
3425 pCur->pStmt = 0;
3426 pCur->ePhase = eNextPhase;
3427 continue;
3428 }
3429 }
3430 if( pCur->nPrefix==0 ) break;
3431 if( pCur->nPrefix<=pCur->szRow
3432 && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
3433 ){
3434 break;
3435 }
3436 }
3437
3438 return SQLITE_OK;
3439 }
3440
3441 /*
3442 ** Return values of columns for the row at which the completion_cursor
3443 ** is currently pointing.
3444 */
3445 static int completionColumn(
3446 sqlite3_vtab_cursor *cur, /* The cursor */
3447 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
3448 int i /* Which column to return */
3449 ){
3450 completion_cursor *pCur = (completion_cursor*)cur;
3451 switch( i ){
3452 case COMPLETION_COLUMN_CANDIDATE: {
3453 sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
3454 break;
3455 }
3456 case COMPLETION_COLUMN_PREFIX: {
3457 sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
3458 break;
3459 }
3460 case COMPLETION_COLUMN_WHOLELINE: {
3461 sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
3462 break;
3463 }
3464 case COMPLETION_COLUMN_PHASE: {
3465 sqlite3_result_int(ctx, pCur->ePhase);
3466 break;
3467 }
3468 }
3469 return SQLITE_OK;
3470 }
3471
3472 /*
3473 ** Return the rowid for the current row. In this implementation, the
3474 ** rowid is the same as the output value.
3475 */
3476 static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
3477 completion_cursor *pCur = (completion_cursor*)cur;
3478 *pRowid = pCur->iRowid;
3479 return SQLITE_OK;
3480 }
3481
3482 /*
3483 ** Return TRUE if the cursor has been moved off of the last
3484 ** row of output.
3485 */
3486 static int completionEof(sqlite3_vtab_cursor *cur){
3487 completion_cursor *pCur = (completion_cursor*)cur;
3488 return pCur->ePhase >= COMPLETION_EOF;
3489 }
3490
3491 /*
3492 ** This method is called to "rewind" the completion_cursor object back
3493 ** to the first row of output. This method is always called at least
3494 ** once prior to any call to completionColumn() or completionRowid() or
3495 ** completionEof().
3496 */
3497 static int completionFilter(
3498 sqlite3_vtab_cursor *pVtabCursor,
3499 int idxNum, const char *idxStr,
3500 int argc, sqlite3_value **argv
3501 ){
3502 completion_cursor *pCur = (completion_cursor *)pVtabCursor;
3503 int iArg = 0;
3504 (void)(idxStr); /* Unused parameter */
3505 (void)(argc); /* Unused parameter */
3506 completionCursorReset(pCur);
3507 if( idxNum & 1 ){
3508 pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
3509 if( pCur->nPrefix>0 ){
3510 pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
3511 if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
3512 }
3513 iArg = 1;
3514 }
3515 if( idxNum & 2 ){
3516 pCur->nLine = sqlite3_value_bytes(argv[iArg]);
3517 if( pCur->nLine>0 ){
3518 pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
3519 if( pCur->zLine==0 ) return SQLITE_NOMEM;
3520 }
3521 }
3522 if( pCur->zLine!=0 && pCur->zPrefix==0 ){
3523 int i = pCur->nLine;
3524 while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
3525 i--;
3526 }
3527 pCur->nPrefix = pCur->nLine - i;
3528 if( pCur->nPrefix>0 ){
3529 pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
3530 if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
3531 }
3532 }
3533 pCur->iRowid = 0;
3534 pCur->ePhase = COMPLETION_FIRST_PHASE;
3535 return completionNext(pVtabCursor);
3536 }
3537
3538 /*
3539 ** SQLite will invoke this method one or more times while planning a query
3540 ** that uses the completion virtual table. This routine needs to create
3541 ** a query plan for each invocation and compute an estimated cost for that
3542 ** plan.
3543 **
3544 ** There are two hidden parameters that act as arguments to the table-valued
3545 ** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix"
3546 ** is available and bit 1 is set if "wholeline" is available.
3547 */
3548 static int completionBestIndex(
3549 sqlite3_vtab *tab,
3550 sqlite3_index_info *pIdxInfo
3551 ){
3552 int i; /* Loop over constraints */
3553 int idxNum = 0; /* The query plan bitmask */
3554 int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */
3555 int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
3556 int nArg = 0; /* Number of arguments that completeFilter() expects */
3557 const struct sqlite3_index_constraint *pConstraint;
3558
3559 (void)(tab); /* Unused parameter */
3560 pConstraint = pIdxInfo->aConstraint;
3561 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
3562 if( pConstraint->usable==0 ) continue;
3563 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
3564 switch( pConstraint->iColumn ){
3565 case COMPLETION_COLUMN_PREFIX:
3566 prefixIdx = i;
3567 idxNum |= 1;
3568 break;
3569 case COMPLETION_COLUMN_WHOLELINE:
3570 wholelineIdx = i;
3571 idxNum |= 2;
3572 break;
3573 }
3574 }
3575 if( prefixIdx>=0 ){
3576 pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
3577 pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
3578 }
3579 if( wholelineIdx>=0 ){
3580 pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
3581 pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
3582 }
3583 pIdxInfo->idxNum = idxNum;
3584 pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
3585 pIdxInfo->estimatedRows = 500 - 100*nArg;
3586 return SQLITE_OK;
3587 }
3588
3589 /*
3590 ** This following structure defines all the methods for the
3591 ** completion virtual table.
3592 */
3593 static sqlite3_module completionModule = {
3594 0, /* iVersion */
3595 0, /* xCreate */
3596 completionConnect, /* xConnect */
3597 completionBestIndex, /* xBestIndex */
3598 completionDisconnect, /* xDisconnect */
3599 0, /* xDestroy */
3600 completionOpen, /* xOpen - open a cursor */
3601 completionClose, /* xClose - close a cursor */
3602 completionFilter, /* xFilter - configure scan constraints */
3603 completionNext, /* xNext - advance a cursor */
3604 completionEof, /* xEof - check for end of scan */
3605 completionColumn, /* xColumn - read data */
3606 completionRowid, /* xRowid - read data */
3607 0, /* xUpdate */
3608 0, /* xBegin */
3609 0, /* xSync */
3610 0, /* xCommit */
3611 0, /* xRollback */
3612 0, /* xFindMethod */
3613 0, /* xRename */
3614 0, /* xSavepoint */
3615 0, /* xRelease */
3616 0, /* xRollbackTo */
3617 0 /* xShadowName */
3618 };
3619
3620 #endif /* SQLITE_OMIT_VIRTUALTABLE */
3621
3622 int sqlite3CompletionVtabInit(sqlite3 *db){
3623 int rc = SQLITE_OK;
3624 #ifndef SQLITE_OMIT_VIRTUALTABLE
3625 rc = sqlite3_create_module(db, "completion", &completionModule, 0);
3626 #endif
3627 return rc;
3628 }
3629
3630 #ifdef _WIN32
3631
3632 #endif
3633 int sqlite3_completion_init(
3634 sqlite3 *db,
3635 char **pzErrMsg,
3636 const sqlite3_api_routines *pApi
3637 ){
3638 int rc = SQLITE_OK;
3639 SQLITE_EXTENSION_INIT2(pApi);
3640 (void)(pzErrMsg); /* Unused parameter */
3641 #ifndef SQLITE_OMIT_VIRTUALTABLE
3642 rc = sqlite3CompletionVtabInit(db);
3643 #endif
3644 return rc;
3645 }
3646
3647 /************************* End ../ext/misc/completion.c ********************/
3648 /************************* Begin ../ext/misc/appendvfs.c ******************/
3649 /*
3650 ** 2017-10-20
3651 **
3652 ** The author disclaims copyright to this source code. In place of
3653 ** a legal notice, here is a blessing:
3654 **
3655 ** May you do good and not evil.
3656 ** May you find forgiveness for yourself and forgive others.
3657 ** May you share freely, never taking more than you give.
3658 **
3659 ******************************************************************************
3660 **
3661 ** This file implements a VFS shim that allows an SQLite database to be
3662 ** appended onto the end of some other file, such as an executable.
3663 **
3664 ** A special record must appear at the end of the file that identifies the
3665 ** file as an appended database and provides the offset to the first page
3666 ** of the exposed content. (Or, it is the length of the content prefix.)
3667 ** For best performance page 1 should be located at a disk page boundary,
3668 ** though that is not required.
3669 **
3670 ** When opening a database using this VFS, the connection might treat
3671 ** the file as an ordinary SQLite database, or it might treat it as a
3672 ** database appended onto some other file. The decision is made by
3673 ** applying the following rules in order:
3674 **
3675 ** (1) An empty file is an ordinary database.
3676 **
3677 ** (2) If the file ends with the appendvfs trailer string
3678 ** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
3679 **
3680 ** (3) If the file begins with the standard SQLite prefix string
3681 ** "SQLite format 3", that file is an ordinary database.
3682 **
3683 ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
3684 ** set, then a new database is appended to the already existing file.
3685 **
3686 ** (5) Otherwise, SQLITE_CANTOPEN is returned.
3687 **
3688 ** To avoid unnecessary complications with the PENDING_BYTE, the size of
3689 ** the file containing the database is limited to 1GiB. (1073741824 bytes)
3690 ** This VFS will not read or write past the 1GiB mark. This restriction
3691 ** might be lifted in future versions. For now, if you need a larger
3692 ** database, then keep it in a separate file.
3693 **
3694 ** If the file being opened is a plain database (not an appended one), then
3695 ** this shim is a pass-through into the default underlying VFS. (rule 3)
3696 **/
3697 /* #include "sqlite3ext.h" */
3698 SQLITE_EXTENSION_INIT1
3699 #include <string.h>
3700 #include <assert.h>
3701
3702 /* The append mark at the end of the database is:
3703 **
3704 ** Start-Of-SQLite3-NNNNNNNN
3705 ** 123456789 123456789 12345
3706 **
3707 ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
3708 ** the offset to page 1, and also the length of the prefix content.
3709 */
3710 #define APND_MARK_PREFIX "Start-Of-SQLite3-"
3711 #define APND_MARK_PREFIX_SZ 17
3712 #define APND_MARK_FOS_SZ 8
3713 #define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
3714
3715 /*
3716 ** Maximum size of the combined prefix + database + append-mark. This
3717 ** must be less than 0x40000000 to avoid locking issues on Windows.
3718 */
3719 #define APND_MAX_SIZE (0x40000000)
3720
3721 /*
3722 ** Try to align the database to an even multiple of APND_ROUNDUP bytes.
3723 */
3724 #ifndef APND_ROUNDUP
3725 #define APND_ROUNDUP 4096
3726 #endif
3727 #define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1))
3728 #define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
3729
3730 /*
3731 ** Forward declaration of objects used by this utility
3732 */
3733 typedef struct sqlite3_vfs ApndVfs;
3734 typedef struct ApndFile ApndFile;
3735
3736 /* Access to a lower-level VFS that (might) implement dynamic loading,
3737 ** access to randomness, etc.
3738 */
3739 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
3740 #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
3741
3742 /* An open appendvfs file
3743 **
3744 ** An instance of this structure describes the appended database file.
3745 ** A separate sqlite3_file object is always appended. The appended
3746 ** sqlite3_file object (which can be accessed using ORIGFILE()) describes
3747 ** the entire file, including the prefix, the database, and the
3748 ** append-mark.
3749 **
3750 ** The structure of an AppendVFS database is like this:
3751 **
3752 ** +-------------+---------+----------+-------------+
3753 ** | prefix-file | padding | database | append-mark |
3754 ** +-------------+---------+----------+-------------+
3755 ** ^ ^
3756 ** | |
3757 ** iPgOne iMark
3758 **
3759 **
3760 ** "prefix file" - file onto which the database has been appended.
3761 ** "padding" - zero or more bytes inserted so that "database"
3762 ** starts on an APND_ROUNDUP boundary
3763 ** "database" - The SQLite database file
3764 ** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
3765 ** the offset from the start of prefix-file to the start
3766 ** of "database".
3767 **
3768 ** The size of the database is iMark - iPgOne.
3769 **
3770 ** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
3771 ** of iPgOne stored as a big-ending 64-bit integer.
3772 **
3773 ** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
3774 ** Or, iMark is -1 to indicate that it has not yet been written.
3775 */
3776 struct ApndFile {
3777 sqlite3_file base; /* Subclass. MUST BE FIRST! */
3778 sqlite3_int64 iPgOne; /* Offset to the start of the database */
3779 sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */
3780 /* Always followed by another sqlite3_file that describes the whole file */
3781 };
3782
3783 /*
3784 ** Methods for ApndFile
3785 */
3786 static int apndClose(sqlite3_file*);
3787 static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
3788 static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
3789 static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
3790 static int apndSync(sqlite3_file*, int flags);
3791 static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
3792 static int apndLock(sqlite3_file*, int);
3793 static int apndUnlock(sqlite3_file*, int);
3794 static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
3795 static int apndFileControl(sqlite3_file*, int op, void *pArg);
3796 static int apndSectorSize(sqlite3_file*);
3797 static int apndDeviceCharacteristics(sqlite3_file*);
3798 static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
3799 static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
3800 static void apndShmBarrier(sqlite3_file*);
3801 static int apndShmUnmap(sqlite3_file*, int deleteFlag);
3802 static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
3803 static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
3804
3805 /*
3806 ** Methods for ApndVfs
3807 */
3808 static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
3809 static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
3810 static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
3811 static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
3812 static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
3813 static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
3814 static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
3815 static void apndDlClose(sqlite3_vfs*, void*);
3816 static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
3817 static int apndSleep(sqlite3_vfs*, int microseconds);
3818 static int apndCurrentTime(sqlite3_vfs*, double*);
3819 static int apndGetLastError(sqlite3_vfs*, int, char *);
3820 static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
3821 static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
3822 static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
3823 static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
3824
3825 static sqlite3_vfs apnd_vfs = {
3826 3, /* iVersion (set when registered) */
3827 0, /* szOsFile (set when registered) */
3828 1024, /* mxPathname */
3829 0, /* pNext */
3830 "apndvfs", /* zName */
3831 0, /* pAppData (set when registered) */
3832 apndOpen, /* xOpen */
3833 apndDelete, /* xDelete */
3834 apndAccess, /* xAccess */
3835 apndFullPathname, /* xFullPathname */
3836 apndDlOpen, /* xDlOpen */
3837 apndDlError, /* xDlError */
3838 apndDlSym, /* xDlSym */
3839 apndDlClose, /* xDlClose */
3840 apndRandomness, /* xRandomness */
3841 apndSleep, /* xSleep */
3842 apndCurrentTime, /* xCurrentTime */
3843 apndGetLastError, /* xGetLastError */
3844 apndCurrentTimeInt64, /* xCurrentTimeInt64 */
3845 apndSetSystemCall, /* xSetSystemCall */
3846 apndGetSystemCall, /* xGetSystemCall */
3847 apndNextSystemCall /* xNextSystemCall */
3848 };
3849
3850 static const sqlite3_io_methods apnd_io_methods = {
3851 3, /* iVersion */
3852 apndClose, /* xClose */
3853 apndRead, /* xRead */
3854 apndWrite, /* xWrite */
3855 apndTruncate, /* xTruncate */
3856 apndSync, /* xSync */
3857 apndFileSize, /* xFileSize */
3858 apndLock, /* xLock */
3859 apndUnlock, /* xUnlock */
3860 apndCheckReservedLock, /* xCheckReservedLock */
3861 apndFileControl, /* xFileControl */
3862 apndSectorSize, /* xSectorSize */
3863 apndDeviceCharacteristics, /* xDeviceCharacteristics */
3864 apndShmMap, /* xShmMap */
3865 apndShmLock, /* xShmLock */
3866 apndShmBarrier, /* xShmBarrier */
3867 apndShmUnmap, /* xShmUnmap */
3868 apndFetch, /* xFetch */
3869 apndUnfetch /* xUnfetch */
3870 };
3871
3872 /*
3873 ** Close an apnd-file.
3874 */
3875 static int apndClose(sqlite3_file *pFile){
3876 pFile = ORIGFILE(pFile);
3877 return pFile->pMethods->xClose(pFile);
3878 }
3879
3880 /*
3881 ** Read data from an apnd-file.
3882 */
3883 static int apndRead(
3884 sqlite3_file *pFile,
3885 void *zBuf,
3886 int iAmt,
3887 sqlite_int64 iOfst
3888 ){
3889 ApndFile *paf = (ApndFile *)pFile;
3890 pFile = ORIGFILE(pFile);
3891 return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
3892 }
3893
3894 /*
3895 ** Add the append-mark onto what should become the end of the file.
3896 * If and only if this succeeds, internal ApndFile.iMark is updated.
3897 * Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
3898 */
3899 static int apndWriteMark(
3900 ApndFile *paf,
3901 sqlite3_file *pFile,
3902 sqlite_int64 iWriteEnd
3903 ){
3904 sqlite_int64 iPgOne = paf->iPgOne;
3905 unsigned char a[APND_MARK_SIZE];
3906 int i = APND_MARK_FOS_SZ;
3907 int rc;
3908 assert(pFile == ORIGFILE(paf));
3909 memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
3910 while( --i >= 0 ){
3911 a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
3912 iPgOne >>= 8;
3913 }
3914 iWriteEnd += paf->iPgOne;
3915 if( SQLITE_OK==(rc = pFile->pMethods->xWrite
3916 (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
3917 paf->iMark = iWriteEnd;
3918 }
3919 return rc;
3920 }
3921
3922 /*
3923 ** Write data to an apnd-file.
3924 */
3925 static int apndWrite(
3926 sqlite3_file *pFile,
3927 const void *zBuf,
3928 int iAmt,
3929 sqlite_int64 iOfst
3930 ){
3931 ApndFile *paf = (ApndFile *)pFile;
3932 sqlite_int64 iWriteEnd = iOfst + iAmt;
3933 if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
3934 pFile = ORIGFILE(pFile);
3935 /* If append-mark is absent or will be overwritten, write it. */
3936 if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
3937 int rc = apndWriteMark(paf, pFile, iWriteEnd);
3938 if( SQLITE_OK!=rc ) return rc;
3939 }
3940 return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
3941 }
3942
3943 /*
3944 ** Truncate an apnd-file.
3945 */
3946 static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
3947 ApndFile *paf = (ApndFile *)pFile;
3948 pFile = ORIGFILE(pFile);
3949 /* The append mark goes out first so truncate failure does not lose it. */
3950 if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
3951 /* Truncate underlying file just past append mark */
3952 return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
3953 }
3954
3955 /*
3956 ** Sync an apnd-file.
3957 */
3958 static int apndSync(sqlite3_file *pFile, int flags){
3959 pFile = ORIGFILE(pFile);
3960 return pFile->pMethods->xSync(pFile, flags);
3961 }
3962
3963 /*
3964 ** Return the current file-size of an apnd-file.
3965 ** If the append mark is not yet there, the file-size is 0.
3966 */
3967 static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
3968 ApndFile *paf = (ApndFile *)pFile;
3969 *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
3970 return SQLITE_OK;
3971 }
3972
3973 /*
3974 ** Lock an apnd-file.
3975 */
3976 static int apndLock(sqlite3_file *pFile, int eLock){
3977 pFile = ORIGFILE(pFile);
3978 return pFile->pMethods->xLock(pFile, eLock);
3979 }
3980
3981 /*
3982 ** Unlock an apnd-file.
3983 */
3984 static int apndUnlock(sqlite3_file *pFile, int eLock){
3985 pFile = ORIGFILE(pFile);
3986 return pFile->pMethods->xUnlock(pFile, eLock);
3987 }
3988
3989 /*
3990 ** Check if another file-handle holds a RESERVED lock on an apnd-file.
3991 */
3992 static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
3993 pFile = ORIGFILE(pFile);
3994 return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
3995 }
3996
3997 /*
3998 ** File control method. For custom operations on an apnd-file.
3999 */
4000 static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
4001 ApndFile *paf = (ApndFile *)pFile;
4002 int rc;
4003 pFile = ORIGFILE(pFile);
4004 if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
4005 rc = pFile->pMethods->xFileControl(pFile, op, pArg);
4006 if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
4007 *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
4008 }
4009 return rc;
4010 }
4011
4012 /*
4013 ** Return the sector-size in bytes for an apnd-file.
4014 */
4015 static int apndSectorSize(sqlite3_file *pFile){
4016 pFile = ORIGFILE(pFile);
4017 return pFile->pMethods->xSectorSize(pFile);
4018 }
4019
4020 /*
4021 ** Return the device characteristic flags supported by an apnd-file.
4022 */
4023 static int apndDeviceCharacteristics(sqlite3_file *pFile){
4024 pFile = ORIGFILE(pFile);
4025 return pFile->pMethods->xDeviceCharacteristics(pFile);
4026 }
4027
4028 /* Create a shared memory file mapping */
4029 static int apndShmMap(
4030 sqlite3_file *pFile,
4031 int iPg,
4032 int pgsz,
4033 int bExtend,
4034 void volatile **pp
4035 ){
4036 pFile = ORIGFILE(pFile);
4037 return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
4038 }
4039
4040 /* Perform locking on a shared-memory segment */
4041 static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
4042 pFile = ORIGFILE(pFile);
4043 return pFile->pMethods->xShmLock(pFile,offset,n,flags);
4044 }
4045
4046 /* Memory barrier operation on shared memory */
4047 static void apndShmBarrier(sqlite3_file *pFile){
4048 pFile = ORIGFILE(pFile);
4049 pFile->pMethods->xShmBarrier(pFile);
4050 }
4051
4052 /* Unmap a shared memory segment */
4053 static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
4054 pFile = ORIGFILE(pFile);
4055 return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
4056 }
4057
4058 /* Fetch a page of a memory-mapped file */
4059 static int apndFetch(
4060 sqlite3_file *pFile,
4061 sqlite3_int64 iOfst,
4062 int iAmt,
4063 void **pp
4064 ){
4065 ApndFile *p = (ApndFile *)pFile;
4066 if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
4067 return SQLITE_IOERR; /* Cannot read what is not yet there. */
4068 }
4069 pFile = ORIGFILE(pFile);
4070 return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
4071 }
4072
4073 /* Release a memory-mapped page */
4074 static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
4075 ApndFile *p = (ApndFile *)pFile;
4076 pFile = ORIGFILE(pFile);
4077 return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
4078 }
4079
4080 /*
4081 ** Try to read the append-mark off the end of a file. Return the
4082 ** start of the appended database if the append-mark is present.
4083 ** If there is no valid append-mark, return -1;
4084 **
4085 ** An append-mark is only valid if the NNNNNNNN start-of-database offset
4086 ** indicates that the appended database contains at least one page. The
4087 ** start-of-database value must be a multiple of 512.
4088 */
4089 static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
4090 int rc, i;
4091 sqlite3_int64 iMark;
4092 int msbs = 8 * (APND_MARK_FOS_SZ-1);
4093 unsigned char a[APND_MARK_SIZE];
4094
4095 if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
4096 rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
4097 if( rc ) return -1;
4098 if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
4099 iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
4100 for(i=1; i<8; i++){
4101 msbs -= 8;
4102 iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
4103 }
4104 if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
4105 if( iMark & 0x1ff ) return -1;
4106 return iMark;
4107 }
4108
4109 static const char apvfsSqliteHdr[] = "SQLite format 3";
4110 /*
4111 ** Check to see if the file is an appendvfs SQLite database file.
4112 ** Return true iff it is such. Parameter sz is the file's size.
4113 */
4114 static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
4115 int rc;
4116 char zHdr[16];
4117 sqlite3_int64 iMark = apndReadMark(sz, pFile);
4118 if( iMark>=0 ){
4119 /* If file has the correct end-marker, the expected odd size, and the
4120 ** SQLite DB type marker where the end-marker puts it, then it
4121 ** is an appendvfs database.
4122 */
4123 rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
4124 if( SQLITE_OK==rc
4125 && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
4126 && (sz & 0x1ff) == APND_MARK_SIZE
4127 && sz>=512+APND_MARK_SIZE
4128 ){
4129 return 1; /* It's an appendvfs database */
4130 }
4131 }
4132 return 0;
4133 }
4134
4135 /*
4136 ** Check to see if the file is an ordinary SQLite database file.
4137 ** Return true iff so. Parameter sz is the file's size.
4138 */
4139 static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
4140 char zHdr[16];
4141 if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
4142 || (sz & 0x1ff) != 0
4143 || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
4144 || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
4145 ){
4146 return 0;
4147 }else{
4148 return 1;
4149 }
4150 }
4151
4152 /*
4153 ** Open an apnd file handle.
4154 */
4155 static int apndOpen(
4156 sqlite3_vfs *pApndVfs,
4157 const char *zName,
4158 sqlite3_file *pFile,
4159 int flags,
4160 int *pOutFlags
4161 ){
4162 ApndFile *pApndFile = (ApndFile*)pFile;
4163 sqlite3_file *pBaseFile = ORIGFILE(pFile);
4164 sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
4165 int rc;
4166 sqlite3_int64 sz = 0;
4167 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
4168 /* The appendvfs is not to be used for transient or temporary databases.
4169 ** Just use the base VFS open to initialize the given file object and
4170 ** open the underlying file. (Appendvfs is then unused for this file.)
4171 */
4172 return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
4173 }
4174 memset(pApndFile, 0, sizeof(ApndFile));
4175 pFile->pMethods = &apnd_io_methods;
4176 pApndFile->iMark = -1; /* Append mark not yet written */
4177
4178 rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
4179 if( rc==SQLITE_OK ){
4180 rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
4181 if( rc ){
4182 pBaseFile->pMethods->xClose(pBaseFile);
4183 }
4184 }
4185 if( rc ){
4186 pFile->pMethods = 0;
4187 return rc;
4188 }
4189 if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
4190 /* The file being opened appears to be just an ordinary DB. Copy
4191 ** the base dispatch-table so this instance mimics the base VFS.
4192 */
4193 memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
4194 return SQLITE_OK;
4195 }
4196 pApndFile->iPgOne = apndReadMark(sz, pFile);
4197 if( pApndFile->iPgOne>=0 ){
4198 pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
4199 return SQLITE_OK;
4200 }
4201 if( (flags & SQLITE_OPEN_CREATE)==0 ){
4202 pBaseFile->pMethods->xClose(pBaseFile);
4203 rc = SQLITE_CANTOPEN;
4204 pFile->pMethods = 0;
4205 }else{
4206 /* Round newly added appendvfs location to #define'd page boundary.
4207 ** Note that nothing has yet been written to the underlying file.
4208 ** The append mark will be written along with first content write.
4209 ** Until then, paf->iMark value indicates it is not yet written.
4210 */
4211 pApndFile->iPgOne = APND_START_ROUNDUP(sz);
4212 }
4213 return rc;
4214 }
4215
4216 /*
4217 ** Delete an apnd file.
4218 ** For an appendvfs, this could mean delete the appendvfs portion,
4219 ** leaving the appendee as it was before it gained an appendvfs.
4220 ** For now, this code deletes the underlying file too.
4221 */
4222 static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
4223 return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
4224 }
4225
4226 /*
4227 ** All other VFS methods are pass-thrus.
4228 */
4229 static int apndAccess(
4230 sqlite3_vfs *pVfs,
4231 const char *zPath,
4232 int flags,
4233 int *pResOut
4234 ){
4235 return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
4236 }
4237 static int apndFullPathname(
4238 sqlite3_vfs *pVfs,
4239 const char *zPath,
4240 int nOut,
4241 char *zOut
4242 ){
4243 return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
4244 }
4245 static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
4246 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
4247 }
4248 static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
4249 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
4250 }
4251 static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
4252 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
4253 }
4254 static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
4255 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
4256 }
4257 static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
4258 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
4259 }
4260 static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
4261 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
4262 }
4263 static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
4264 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
4265 }
4266 static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
4267 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
4268 }
4269 static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
4270 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
4271 }
4272 static int apndSetSystemCall(
4273 sqlite3_vfs *pVfs,
4274 const char *zName,
4275 sqlite3_syscall_ptr pCall
4276 ){
4277 return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
4278 }
4279 static sqlite3_syscall_ptr apndGetSystemCall(
4280 sqlite3_vfs *pVfs,
4281 const char *zName
4282 ){
4283 return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
4284 }
4285 static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
4286 return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
4287 }
4288
4289
4290 #ifdef _WIN32
4291
4292 #endif
4293 /*
4294 ** This routine is called when the extension is loaded.
4295 ** Register the new VFS.
4296 */
4297 int sqlite3_appendvfs_init(
4298 sqlite3 *db,
4299 char **pzErrMsg,
4300 const sqlite3_api_routines *pApi
4301 ){
4302 int rc = SQLITE_OK;
4303 sqlite3_vfs *pOrig;
4304 SQLITE_EXTENSION_INIT2(pApi);
4305 (void)pzErrMsg;
4306 (void)db;
4307 pOrig = sqlite3_vfs_find(0);
4308 if( pOrig==0 ) return SQLITE_ERROR;
4309 apnd_vfs.iVersion = pOrig->iVersion;
4310 apnd_vfs.pAppData = pOrig;
4311 apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
4312 rc = sqlite3_vfs_register(&apnd_vfs, 0);
4313 #ifdef APPENDVFS_TEST
4314 if( rc==SQLITE_OK ){
4315 rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
4316 }
4317 #endif
4318 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
4319 return rc;
4320 }
4321
4322 /************************* End ../ext/misc/appendvfs.c ********************/
4323 /************************* Begin ../ext/misc/memtrace.c ******************/
4324 /*
4325 ** 2019-01-21
4326 **
4327 ** The author disclaims copyright to this source code. In place of
4328 ** a legal notice, here is a blessing:
4329 **
4330 ** May you do good and not evil.
4331 ** May you find forgiveness for yourself and forgive others.
4332 ** May you share freely, never taking more than you give.
4333 **
4334 *************************************************************************
4335 **
4336 ** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
4337 ** mechanism to add a tracing layer on top of SQLite. If this extension
4338 ** is registered prior to sqlite3_initialize(), it will cause all memory
4339 ** allocation activities to be logged on standard output, or to some other
4340 ** FILE specified by the initializer.
4341 **
4342 ** This file needs to be compiled into the application that uses it.
4343 **
4344 ** This extension is used to implement the --memtrace option of the
4345 ** command-line shell.
4346 */
4347 #include <assert.h>
4348 #include <string.h>
4349 #include <stdio.h>
4350
4351 /* The original memory allocation routines */
4352 static sqlite3_mem_methods memtraceBase;
4353 static FILE *memtraceOut;
4354
4355 /* Methods that trace memory allocations */
4356 static void *memtraceMalloc(int n){
4357 if( memtraceOut ){
4358 fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
4359 memtraceBase.xRoundup(n));
4360 }
4361 return memtraceBase.xMalloc(n);
4362 }
4363 static void memtraceFree(void *p){
4364 if( p==0 ) return;
4365 if( memtraceOut ){
4366 fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
4367 }
4368 memtraceBase.xFree(p);
4369 }
4370 static void *memtraceRealloc(void *p, int n){
4371 if( p==0 ) return memtraceMalloc(n);
4372 if( n==0 ){
4373 memtraceFree(p);
4374 return 0;
4375 }
4376 if( memtraceOut ){
4377 fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
4378 memtraceBase.xSize(p), memtraceBase.xRoundup(n));
4379 }
4380 return memtraceBase.xRealloc(p, n);
4381 }
4382 static int memtraceSize(void *p){
4383 return memtraceBase.xSize(p);
4384 }
4385 static int memtraceRoundup(int n){
4386 return memtraceBase.xRoundup(n);
4387 }
4388 static int memtraceInit(void *p){
4389 return memtraceBase.xInit(p);
4390 }
4391 static void memtraceShutdown(void *p){
4392 memtraceBase.xShutdown(p);
4393 }
4394
4395 /* The substitute memory allocator */
4396 static sqlite3_mem_methods ersaztMethods = {
4397 memtraceMalloc,
4398 memtraceFree,
4399 memtraceRealloc,
4400 memtraceSize,
4401 memtraceRoundup,
4402 memtraceInit,
4403 memtraceShutdown,
4404 0
4405 };
4406
4407 /* Begin tracing memory allocations to out. */
4408 int sqlite3MemTraceActivate(FILE *out){
4409 int rc = SQLITE_OK;
4410 if( memtraceBase.xMalloc==0 ){
4411 rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
4412 if( rc==SQLITE_OK ){
4413 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
4414 }
4415 }
4416 memtraceOut = out;
4417 return rc;
4418 }
4419
4420 /* Deactivate memory tracing */
4421 int sqlite3MemTraceDeactivate(void){
4422 int rc = SQLITE_OK;
4423 if( memtraceBase.xMalloc!=0 ){
4424 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
4425 if( rc==SQLITE_OK ){
4426 memset(&memtraceBase, 0, sizeof(memtraceBase));
4427 }
4428 }
4429 memtraceOut = 0;
4430 return rc;
4431 }
4432
4433 /************************* End ../ext/misc/memtrace.c ********************/
4434 /************************* Begin ../ext/misc/uint.c ******************/
4435 /*
4436 ** 2020-04-14
4437 **
4438 ** The author disclaims copyright to this source code. In place of
@@ -6696,10 +4495,2224 @@
6696 }
6697 return rc;
6698 }
6699
6700 /************************* End ../ext/misc/regexp.c ********************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6701 #ifdef SQLITE_HAVE_ZLIB
6702 /************************* Begin ../ext/misc/zipfile.c ******************/
6703 /*
6704 ** 2017-12-26
6705 **
@@ -12235,11 +12248,21 @@
12235 int nIndent; /* Size of array aiIndent[] */
12236 int iIndent; /* Index of current op in aiIndent[] */
12237 char *zNonce; /* Nonce for temporary safe-mode excapes */
12238 EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
12239 ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
 
 
 
 
 
 
12240 };
 
 
 
 
12241
12242
12243 /* Allowed values for ShellState.autoEQP
12244 */
12245 #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
@@ -12277,11 +12300,11 @@
12277 #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
12278 #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
12279 #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
12280 #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
12281 #define SHFLG_CountChanges 0x00000020 /* .changes setting */
12282 #define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
12283 #define SHFLG_HeaderSet 0x00000080 /* showHeader has been specified */
12284 #define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
12285 #define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
12286
12287 /*
@@ -12901,11 +12924,15 @@
12901 UNUSED_PARAMETER(zA2);
12902 UNUSED_PARAMETER(zA3);
12903 UNUSED_PARAMETER(zA4);
12904 switch( op ){
12905 case SQLITE_ATTACH: {
 
 
 
12906 failIfSafeMode(p, "cannot run ATTACH in safe mode");
 
12907 break;
12908 }
12909 case SQLITE_FUNCTION: {
12910 int i;
12911 for(i=0; i<ArraySize(azProhibitedFunctions); i++){
@@ -14906,15 +14933,10 @@
14906 if( pArg ){
14907 pArg->pStmt = pStmt;
14908 pArg->cnt = 0;
14909 }
14910
14911 /* echo the sql statement if echo on */
14912 if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
14913 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
14914 }
14915
14916 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
14917 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
14918 sqlite3_stmt *pExplain;
14919 char *zEQP;
14920 int triggerEQP = 0;
@@ -15309,17 +15331,18 @@
15309
15310 /*
15311 ** Text of help messages.
15312 **
15313 ** The help text for each individual command begins with a line that starts
15314 ** with ".". Subsequent lines are supplimental information.
15315 **
15316 ** There must be two or more spaces between the end of the command and the
15317 ** start of the description of what that command does.
15318 */
15319 static const char *(azHelp[]) = {
15320 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
 
15321 ".archive ... Manage SQL archives",
15322 " Each command must have exactly one of the following options:",
15323 " -c, --create Create a new archive",
15324 " -u, --update Add or update files with changed mtime",
15325 " -i, --insert Like -u but always add even if unchanged",
@@ -15341,24 +15364,32 @@
15341 " http://sqlite.org/cli.html#sqlite_archive_support",
15342 #endif
15343 #ifndef SQLITE_OMIT_AUTHORIZATION
15344 ".auth ON|OFF Show authorizer callbacks",
15345 #endif
 
15346 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
15347 " Options:",
15348 " --append Use the appendvfs",
15349 " --async Write to FILE without journal and fsync()",
 
15350 ".bail on|off Stop after hitting an error. Default OFF",
15351 ".binary on|off Turn binary output on or off. Default OFF",
 
15352 ".cd DIRECTORY Change the working directory to DIRECTORY",
 
15353 ".changes on|off Show number of rows changed by SQL",
 
15354 ".check GLOB Fail if output since .testcase does not match",
15355 ".clone NEWDB Clone data into NEWDB from the existing database",
 
15356 ".connection [close] [#] Open or close an auxiliary database connection",
15357 ".databases List names and files of attached databases",
15358 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
 
15359 ".dbinfo ?DB? Show status information about the database",
 
15360 ".dump ?OBJECTS? Render database content as SQL",
15361 " Options:",
15362 " --data-only Output only INSERT statements",
15363 " --newlines Allow unescaped newline characters in output",
15364 " --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -15371,21 +15402,26 @@
15371 #ifdef SQLITE_DEBUG
15372 " test Show raw EXPLAIN QUERY PLAN output",
15373 " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
15374 #endif
15375 " trigger Like \"full\" but also show trigger bytecode",
 
15376 ".excel Display the output of next command in spreadsheet",
15377 " --bom Put a UTF8 byte-order mark on intermediate file",
 
 
15378 ".exit ?CODE? Exit this program with return-code CODE",
 
15379 ".expert EXPERIMENTAL. Suggest indexes for queries",
15380 ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
15381 ".filectrl CMD ... Run various sqlite3_file_control() operations",
15382 " --schema SCHEMA Use SCHEMA instead of \"main\"",
15383 " --help Show CMD details",
15384 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
15385 ".headers on|off Turn display of headers on or off",
15386 ".help ?-all? ?PATTERN? Show help text for PATTERN",
 
15387 ".import FILE TABLE Import data from FILE into TABLE",
15388 " Options:",
15389 " --ascii Use \\037 and \\036 as column and row separators",
15390 " --csv Use , and \\n as column and row separators",
15391 " --skip N Skip the first N rows of input",
@@ -15396,10 +15432,11 @@
15396 " determines the column names.",
15397 " * If neither --csv or --ascii are used, the input mode is derived",
15398 " from the \".mode\" output mode",
15399 " * If FILE begins with \"|\" then it is a command that generates the",
15400 " input text.",
 
15401 #ifndef SQLITE_OMIT_TEST_CONTROL
15402 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
15403 #endif
15404 ".indexes ?TABLE? Show names of indexes",
15405 " If TABLE is specified, only show indexes for",
@@ -15409,14 +15446,16 @@
15409 #endif
15410 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
15411 ".lint OPTIONS Report potential schema issues.",
15412 " Options:",
15413 " fkey-indexes Find missing foreign key indexes",
15414 #ifndef SQLITE_OMIT_LOAD_EXTENSION
15415 ".load FILE ?ENTRY? Load an extension library",
15416 #endif
 
15417 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
 
15418 ".mode MODE ?OPTIONS? Set output mode",
15419 " MODE is one of:",
15420 " ascii Columns/rows delimited by 0x1F and 0x1E",
15421 " box Tables using unicode box-drawing characters",
15422 " csv Comma-separated values",
@@ -15437,35 +15476,44 @@
15437 " --wordwrap B Wrap or not at word boundaries per B (on/off)",
15438 " --ww Shorthand for \"--wordwrap 1\"",
15439 " --quote Quote output text as SQL literals",
15440 " --noquote Do not quote output text",
15441 " TABLE The name of SQL table used for \"insert\" mode",
 
15442 ".nonce STRING Suspend safe mode for one command if nonce matches",
 
15443 ".nullvalue STRING Use STRING in place of NULL values",
 
15444 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
15445 " If FILE begins with '|' then open as a pipe",
15446 " --bom Put a UTF8 byte-order mark at the beginning",
15447 " -e Send output to the system text editor",
15448 " -x Send output as CSV to a spreadsheet (same as \".excel\")",
 
 
 
15449 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
15450 " Options:",
15451 " --append Use appendvfs to append database to the end of FILE",
 
15452 #ifndef SQLITE_OMIT_DESERIALIZE
15453 " --deserialize Load into memory using sqlite3_deserialize()",
15454 " --hexdb Load the output of \"dbtotxt\" as an in-memory db",
15455 " --maxsize N Maximum size for --hexdb or --deserialized database",
15456 #endif
15457 " --new Initialize FILE to an empty database",
15458 " --nofollow Do not follow symbolic links",
15459 " --readonly Open FILE readonly",
15460 " --zip FILE is a ZIP archive",
 
15461 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
15462 " If FILE begins with '|' then open it as a pipe.",
15463 " Options:",
15464 " --bom Prefix output with a UTF8 byte-order mark",
15465 " -e Send output to the system text editor",
15466 " -x Send output as CSV to a spreadsheet",
 
15467 ".parameter CMD ... Manage SQL parameter bindings",
15468 " clear Erase all bindings",
15469 " init Initialize the TEMP table that holds bindings",
15470 " list List the current parameter bindings",
15471 " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
@@ -15478,23 +15526,27 @@
15478 " --once Do no more than one progress interrupt",
15479 " --quiet|-q No output except at interrupts",
15480 " --reset Reset the count for each input and interrupt",
15481 #endif
15482 ".prompt MAIN CONTINUE Replace the standard prompts",
 
15483 ".quit Exit this program",
15484 ".read FILE Read input from FILE or command output",
15485 " If FILE begins with \"|\", it is a command that generates the input.",
 
15486 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
15487 ".recover Recover as much data as possible from corrupt db.",
15488 " --freelist-corrupt Assume the freelist is corrupt",
15489 " --recovery-db NAME Store recovery metadata in database file NAME",
15490 " --lost-and-found TABLE Alternative name for the lost-and-found table",
15491 " --no-rowids Do not attempt to recover rowid values",
15492 " that are not also INTEGER PRIMARY KEYs",
15493 #endif
 
15494 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15495 ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
 
15496 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
15497 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
15498 " Options:",
15499 " --indent Try to pretty-print the schema",
15500 " --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15524,24 +15576,26 @@
15524 " --sha3-224 Use the sha3-224 algorithm",
15525 " --sha3-256 Use the sha3-256 algorithm (default)",
15526 " --sha3-384 Use the sha3-384 algorithm",
15527 " --sha3-512 Use the sha3-512 algorithm",
15528 " Any other argument is a LIKE pattern for tables to hash",
15529 #ifndef SQLITE_NOHAVE_SYSTEM
15530 ".shell CMD ARGS... Run CMD ARGS... in a system shell",
15531 #endif
15532 ".show Show the current values for various settings",
15533 ".stats ?ARG? Show stats or turn stats on or off",
15534 " off Turn off automatic stat display",
15535 " on Turn on automatic stat display",
15536 " stmt Show statement stats",
15537 " vmstep Show the virtual machine step count only",
15538 #ifndef SQLITE_NOHAVE_SYSTEM
15539 ".system CMD ARGS... Run CMD ARGS... in a system shell",
15540 #endif
15541 ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
 
15542 ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
 
15543 ".testctrl CMD ... Run various sqlite3_test_control() operations",
15544 " Run \".testctrl\" with no arguments for details",
15545 ".timeout MS Try opening locked tables for MS milliseconds",
15546 ".timer on|off Turn SQL timer on or off",
15547 #ifndef SQLITE_OMIT_TRACE
@@ -16082,18 +16136,20 @@
16082 exit(1);
16083 }
16084 #ifndef SQLITE_OMIT_LOAD_EXTENSION
16085 sqlite3_enable_load_extension(p->db, 1);
16086 #endif
16087 sqlite3_fileio_init(p->db, 0, 0);
16088 sqlite3_shathree_init(p->db, 0, 0);
16089 sqlite3_completion_init(p->db, 0, 0);
16090 sqlite3_uint_init(p->db, 0, 0);
16091 sqlite3_decimal_init(p->db, 0, 0);
16092 sqlite3_regexp_init(p->db, 0, 0);
16093 sqlite3_ieee_init(p->db, 0, 0);
16094 sqlite3_series_init(p->db, 0, 0);
 
 
 
 
16095 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
16096 sqlite3_dbdata_init(p->db, 0, 0);
16097 #endif
16098 #ifdef SQLITE_HAVE_ZLIB
16099 if( !p->bSafeModePersist ){
@@ -16867,10 +16923,11 @@
16867 }
16868 sqlite3_finalize(pStmt);
16869 return res;
16870 }
16871
 
16872 /*
16873 ** Convert a 2-byte or 4-byte big-endian integer into a native integer
16874 */
16875 static unsigned int get2byteInt(unsigned char *a){
16876 return (a[0]<<8) + a[1];
@@ -16973,10 +17030,12 @@
16973 sqlite3_free(zSchemaTab);
16974 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
16975 utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
16976 return 0;
16977 }
 
 
16978
16979 /*
16980 ** Print the current sqlite3_errmsg() value to stderr and return 1.
16981 */
16982 static int shellDatabaseError(sqlite3 *db){
@@ -19212,18 +19271,20 @@
19212 sqlite3_set_authorizer(p->db, 0, 0);
19213 }
19214 }else
19215 #endif
19216
19217 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
 
19218 if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
19219 open_db(p, 0);
19220 failIfSafeMode(p, "cannot run .archive in safe mode");
19221 rc = arDotCommand(p, 0, azArg, nArg);
19222 }else
19223 #endif
19224
 
19225 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
19226 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
19227 ){
19228 const char *zDestFile = 0;
19229 const char *zDb = 0;
@@ -19288,10 +19349,11 @@
19288 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
19289 rc = 1;
19290 }
19291 close_db(pDest);
19292 }else
 
19293
19294 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
19295 if( nArg==2 ){
19296 bail_on_error = booleanValue(azArg[1]);
19297 }else{
@@ -19318,10 +19380,11 @@
19318 */
19319 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
19320 test_breakpoint();
19321 }else
19322
 
19323 if( c=='c' && strcmp(azArg[0],"cd")==0 ){
19324 failIfSafeMode(p, "cannot run .cd in safe mode");
19325 if( nArg==2 ){
19326 #if defined(_WIN32) || defined(WIN32)
19327 wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
@@ -19337,10 +19400,11 @@
19337 }else{
19338 raw_printf(stderr, "Usage: .cd DIRECTORY\n");
19339 rc = 1;
19340 }
19341 }else
 
19342
19343 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
19344 if( nArg==2 ){
19345 setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
19346 }else{
@@ -19347,10 +19411,11 @@
19347 raw_printf(stderr, "Usage: .changes on|off\n");
19348 rc = 1;
19349 }
19350 }else
19351
 
19352 /* Cancel output redirection, if it is currently set (by .testcase)
19353 ** Then read the content of the testcase-out.txt file and compare against
19354 ** azArg[1]. If there are differences, report an error and exit.
19355 */
19356 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
@@ -19371,20 +19436,23 @@
19371 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
19372 p->nCheck++;
19373 }
19374 sqlite3_free(zRes);
19375 }else
 
19376
 
19377 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
19378 failIfSafeMode(p, "cannot run .clone in safe mode");
19379 if( nArg==2 ){
19380 tryToClone(p, azArg[1]);
19381 }else{
19382 raw_printf(stderr, "Usage: .clone FILENAME\n");
19383 rc = 1;
19384 }
19385 }else
 
19386
19387 if( c=='c' && strncmp(azArg[0], "connection", n)==0 ){
19388 if( nArg==1 ){
19389 /* List available connections */
19390 int i;
@@ -19506,15 +19574,15 @@
19506 utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
19507 utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
19508 }
19509 }else
19510
 
19511 if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
19512 rc = shell_dbinfo_command(p, nArg, azArg);
19513 }else
19514
19515 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
19516 if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
19517 open_db(p, 0);
19518 rc = recoverDatabaseCmd(p, nArg, azArg);
19519 }else
19520 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
@@ -19523,11 +19591,11 @@
19523 char *zLike = 0;
19524 char *zSql;
19525 int i;
19526 int savedShowHeader = p->showHeader;
19527 int savedShellFlags = p->shellFlgs;
19528 ShellClearFlag(p,
19529 SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
19530 |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
19531 for(i=1; i<nArg; i++){
19532 if( azArg[i][0]=='-' ){
19533 const char *z = azArg[i]+1;
@@ -19669,14 +19737,16 @@
19669 raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
19670 rc = 1;
19671 }
19672 }else
19673
 
19674 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
19675 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
19676 rc = 2;
19677 }else
 
19678
19679 /* The ".explain" command is automatic now. It is largely pointless. It
19680 ** retained purely for backwards compatibility */
19681 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
19682 int val = 1;
@@ -19927,10 +19997,11 @@
19927 }else{
19928 showHelp(p->out, 0);
19929 }
19930 }else
19931
 
19932 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
19933 char *zTable = 0; /* Insert data into this table */
19934 char *zSchema = 0; /* within this schema (may default to "main") */
19935 char *zFile = 0; /* Name of file to extra content from */
19936 sqlite3_stmt *pStmt = NULL; /* A statement */
@@ -19948,20 +20019,16 @@
19948 int useOutputMode = 1; /* Use output mode to determine separators */
19949 char *zCreate = 0; /* CREATE TABLE statement text */
19950
19951 failIfSafeMode(p, "cannot run .import in safe mode");
19952 memset(&sCtx, 0, sizeof(sCtx));
19953 sCtx.z = sqlite3_malloc64(120);
19954 if( sCtx.z==0 ){
19955 import_cleanup(&sCtx);
19956 shell_out_of_memory();
19957 }
19958 if( p->mode==MODE_Ascii ){
19959 xRead = ascii_read_one_field;
19960 }else{
19961 xRead = csv_read_one_field;
19962 }
 
19963 for(i=1; i<nArg; i++){
19964 char *z = azArg[i];
19965 if( z[0]=='-' && z[1]=='-' ) z++;
19966 if( z[0]!='-' ){
19967 if( zFile==0 ){
@@ -19969,11 +20036,10 @@
19969 }else if( zTable==0 ){
19970 zTable = z;
19971 }else{
19972 utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
19973 showHelp(p->out, "import");
19974 rc = 1;
19975 goto meta_command_exit;
19976 }
19977 }else if( strcmp(z,"-v")==0 ){
19978 eVerbose++;
19979 }else if( strcmp(z,"-schema")==0 && i<nArg-1 ){
@@ -19991,19 +20057,17 @@
19991 xRead = csv_read_one_field;
19992 useOutputMode = 0;
19993 }else{
19994 utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
19995 showHelp(p->out, "import");
19996 rc = 1;
19997 goto meta_command_exit;
19998 }
19999 }
20000 if( zTable==0 ){
20001 utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
20002 zFile==0 ? "FILE" : "TABLE");
20003 showHelp(p->out, "import");
20004 rc = 1;
20005 goto meta_command_exit;
20006 }
20007 seenInterrupt = 0;
20008 open_db(p, 0);
20009 if( useOutputMode ){
@@ -20011,25 +20075,22 @@
20011 ** the column and row separator characters from the output mode. */
20012 nSep = strlen30(p->colSeparator);
20013 if( nSep==0 ){
20014 raw_printf(stderr,
20015 "Error: non-null column separator required for import\n");
20016 rc = 1;
20017 goto meta_command_exit;
20018 }
20019 if( nSep>1 ){
20020 raw_printf(stderr,
20021 "Error: multi-character column separators not allowed"
20022 " for import\n");
20023 rc = 1;
20024 goto meta_command_exit;
20025 }
20026 nSep = strlen30(p->rowSeparator);
20027 if( nSep==0 ){
20028 raw_printf(stderr,
20029 "Error: non-null row separator required for import\n");
20030 rc = 1;
20031 goto meta_command_exit;
20032 }
20033 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
20034 /* When importing CSV (only), if the row separator is set to the
20035 ** default output row separator, change it to the default input
@@ -20039,11 +20100,10 @@
20039 nSep = strlen30(p->rowSeparator);
20040 }
20041 if( nSep>1 ){
20042 raw_printf(stderr, "Error: multi-character row separators not allowed"
20043 " for import\n");
20044 rc = 1;
20045 goto meta_command_exit;
20046 }
20047 sCtx.cColSep = p->colSeparator[0];
20048 sCtx.cRowSep = p->rowSeparator[0];
20049 }
@@ -20050,11 +20110,10 @@
20050 sCtx.zFile = zFile;
20051 sCtx.nLine = 1;
20052 if( sCtx.zFile[0]=='|' ){
20053 #ifdef SQLITE_OMIT_POPEN
20054 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
20055 rc = 1;
20056 goto meta_command_exit;
20057 #else
20058 sCtx.in = popen(sCtx.zFile+1, "r");
20059 sCtx.zFile = "<pipe>";
20060 sCtx.xCloser = pclose;
@@ -20063,12 +20122,10 @@
20063 sCtx.in = fopen(sCtx.zFile, "rb");
20064 sCtx.xCloser = fclose;
20065 }
20066 if( sCtx.in==0 ){
20067 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
20068 rc = 1;
20069 import_cleanup(&sCtx);
20070 goto meta_command_exit;
20071 }
20072 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
20073 char zSep[2];
20074 zSep[1] = 0;
@@ -20077,10 +20134,15 @@
20077 output_c_string(p->out, zSep);
20078 utf8_printf(p->out, ", row separator ");
20079 zSep[0] = sCtx.cRowSep;
20080 output_c_string(p->out, zSep);
20081 utf8_printf(p->out, "\n");
 
 
 
 
 
20082 }
20083 /* Below, resources must be freed before exit. */
20084 while( (nSkip--)>0 ){
20085 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
20086 }
@@ -20226,10 +20288,11 @@
20226 utf8_printf(p->out,
20227 "Added %d rows with %d errors using %d lines of input\n",
20228 sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
20229 }
20230 }else
 
20231
20232 #ifndef SQLITE_UNTESTABLE
20233 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
20234 char *zSql;
20235 char *zCollist = 0;
@@ -20415,11 +20478,11 @@
20415 if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
20416 open_db(p, 0);
20417 lintDotCommand(p, azArg, nArg);
20418 }else
20419
20420 #ifndef SQLITE_OMIT_LOAD_EXTENSION
20421 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
20422 const char *zFile, *zProc;
20423 char *zErrMsg = 0;
20424 failIfSafeMode(p, "cannot run .load in safe mode");
20425 if( nArg<2 ){
@@ -20437,10 +20500,11 @@
20437 rc = 1;
20438 }
20439 }else
20440 #endif
20441
 
20442 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
20443 failIfSafeMode(p, "cannot run .log in safe mode");
20444 if( nArg!=2 ){
20445 raw_printf(stderr, "Usage: .log FILENAME\n");
20446 rc = 1;
@@ -20448,10 +20512,11 @@
20448 const char *zFile = azArg[1];
20449 output_file_close(p->pLog);
20450 p->pLog = output_file_open(zFile, 0);
20451 }
20452 }else
 
20453
20454 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
20455 const char *zMode = 0;
20456 const char *zTabname = 0;
20457 int i, n2;
@@ -20572,10 +20637,11 @@
20572 rc = 1;
20573 }
20574 p->cMode = p->mode;
20575 }else
20576
 
20577 if( c=='n' && strcmp(azArg[0], "nonce")==0 ){
20578 if( nArg!=2 ){
20579 raw_printf(stderr, "Usage: .nonce NONCE\n");
20580 rc = 1;
20581 }else if( p->zNonce==0 || strcmp(azArg[1],p->zNonce)!=0 ){
@@ -20586,10 +20652,11 @@
20586 p->bSafeMode = 0;
20587 return 0; /* Return immediately to bypass the safe mode reset
20588 ** at the end of this procedure */
20589 }
20590 }else
 
20591
20592 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
20593 if( nArg==2 ){
20594 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
20595 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
@@ -20607,10 +20674,11 @@
20607 int openMode = SHELL_OPEN_UNSPEC;
20608
20609 /* Check for command-line arguments */
20610 for(iName=1; iName<nArg; iName++){
20611 const char *z = azArg[iName];
 
20612 if( optionMatch(z,"new") ){
20613 newFlag = 1;
20614 #ifdef SQLITE_HAVE_ZLIB
20615 }else if( optionMatch(z, "zip") ){
20616 openMode = SHELL_OPEN_ZIPFILE;
@@ -20627,11 +20695,13 @@
20627 }else if( optionMatch(z, "hexdb") ){
20628 openMode = SHELL_OPEN_HEXDB;
20629 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
20630 p->szMax = integerValue(azArg[++iName]);
20631 #endif /* SQLITE_OMIT_DESERIALIZE */
20632 }else if( z[0]=='-' ){
 
 
20633 utf8_printf(stderr, "unknown option: %s\n", z);
20634 rc = 1;
20635 goto meta_command_exit;
20636 }else if( zFN ){
20637 utf8_printf(stderr, "extra argument: \"%s\"\n", z);
@@ -20654,17 +20724,21 @@
20654 p->szMax = 0;
20655
20656 /* If a filename is specified, try to open it first */
20657 if( zFN || p->openMode==SHELL_OPEN_HEXDB ){
20658 if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN);
 
20659 if( p->bSafeMode
20660 && p->openMode!=SHELL_OPEN_HEXDB
20661 && zFN
20662 && strcmp(zFN,":memory:")!=0
20663 ){
20664 failIfSafeMode(p, "cannot open disk-based database files in safe mode");
20665 }
 
 
 
20666 if( zFN ){
20667 zNewFilename = sqlite3_mprintf("%s", zFN);
20668 shell_check_oom(zNewFilename);
20669 }else{
20670 zNewFilename = 0;
@@ -20683,10 +20757,11 @@
20683 p->pAuxDb->zDbFilename = 0;
20684 open_db(p, 0);
20685 }
20686 }else
20687
 
20688 if( (c=='o'
20689 && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
20690 || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
20691 ){
20692 char *zFile = 0;
@@ -20798,10 +20873,11 @@
20798 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20799 }
20800 }
20801 sqlite3_free(zFile);
20802 }else
 
20803
20804 if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
20805 open_db(p,0);
20806 if( nArg<=1 ) goto parameter_syntax_error;
20807
@@ -20967,14 +21043,17 @@
20967 if( nArg >= 3) {
20968 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
20969 }
20970 }else
20971
 
20972 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
20973 rc = 2;
20974 }else
 
20975
 
20976 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
20977 FILE *inSaved = p->in;
20978 int savedLineno = p->lineno;
20979 failIfSafeMode(p, "cannot run .read in safe mode");
20980 if( nArg!=2 ){
@@ -21005,11 +21084,13 @@
21005 fclose(p->in);
21006 }
21007 p->in = inSaved;
21008 p->lineno = savedLineno;
21009 }else
 
21010
 
21011 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
21012 const char *zSrcFile;
21013 const char *zDb;
21014 sqlite3 *pSrc;
21015 sqlite3_backup *pBackup;
@@ -21057,10 +21138,11 @@
21057 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
21058 rc = 1;
21059 }
21060 close_db(pSrc);
21061 }else
 
21062
21063 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
21064 if( nArg==2 ){
21065 p->scanstatsOn = (u8)booleanValue(azArg[1]);
21066 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
@@ -21682,11 +21764,11 @@
21682 shell_exec(p, zSql, 0);
21683 }
21684 sqlite3_free(zSql);
21685 }else
21686
21687 #ifndef SQLITE_NOHAVE_SYSTEM
21688 if( c=='s'
21689 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
21690 ){
21691 char *zCmd;
21692 int i, x;
@@ -21703,11 +21785,11 @@
21703 }
21704 x = zCmd!=0 ? system(zCmd) : 1;
21705 sqlite3_free(zCmd);
21706 if( x ) raw_printf(stderr, "System command returns %d\n", x);
21707 }else
21708 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
21709
21710 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
21711 static const char *azBool[] = { "off", "on", "trigger", "full"};
21712 const char *zOut;
21713 int i;
@@ -21715,11 +21797,11 @@
21715 raw_printf(stderr, "Usage: .show\n");
21716 rc = 1;
21717 goto meta_command_exit;
21718 }
21719 utf8_printf(p->out, "%12.12s: %s\n","echo",
21720 azBool[ShellHasFlag(p, SHFLG_Echo)]);
21721 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
21722 utf8_printf(p->out, "%12.12s: %s\n","explain",
21723 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
21724 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21725 if( p->mode==MODE_Column
@@ -21883,10 +21965,11 @@
21883
21884 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
21885 sqlite3_free(azResult);
21886 }else
21887
 
21888 /* Begin redirecting output to the file "testcase-out.txt" */
21889 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
21890 output_reset(p);
21891 p->out = output_file_open("testcase-out.txt", 0);
21892 if( p->out==0 ){
@@ -21896,10 +21979,11 @@
21896 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
21897 }else{
21898 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
21899 }
21900 }else
 
21901
21902 #ifndef SQLITE_UNTESTABLE
21903 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
21904 static const struct {
21905 const char *zCtrlName; /* Name of a test-control option */
@@ -22465,11 +22549,11 @@
22465 /* fall thru */
22466 case ']':
22467 cWait = 0;
22468 qss = QSS_SETV(qss, 0);
22469 goto PlainScan;
22470 default: assert(0);
22471 }
22472 }
22473 }
22474 }
22475 return qss;
@@ -22486,11 +22570,11 @@
22486 zLine += 1; /* Oracle */
22487 else if ( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' )
22488 zLine += 2; /* SQL Server */
22489 else
22490 return 0;
22491 return quickscan(zLine,QSS_Start)==QSS_Start;
22492 }
22493
22494 /*
22495 ** We need a default sqlite3_complete() implementation to use in case
22496 ** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
@@ -22563,10 +22647,46 @@
22563 raw_printf(p->out, "%s\n", zLineBuf);
22564 }
22565 return 0;
22566 }
22567
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22568
22569 /*
22570 ** Read input from *in and process it. If *in==0 then input
22571 ** is interactive - the user is typing it it. Otherwise, input
22572 ** is coming from a file or device. A prompt is issued and history
@@ -22612,18 +22732,17 @@
22612 && line_is_complete(zSql, nSql) ){
22613 memcpy(zLine,";",2);
22614 }
22615 qss = quickscan(zLine, qss);
22616 if( QSS_PLAINWHITE(qss) && nSql==0 ){
22617 if( ShellHasFlag(p, SHFLG_Echo) )
22618 printf("%s\n", zLine);
22619 /* Just swallow single-line whitespace */
 
22620 qss = QSS_Start;
22621 continue;
22622 }
22623 if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
22624 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
22625 if( zLine[0]=='.' ){
22626 rc = do_meta_command(zLine, p);
22627 if( rc==2 ){ /* exit requested */
22628 break;
22629 }else if( rc ){
@@ -22652,10 +22771,11 @@
22652 zSql[nSql++] = '\n';
22653 memcpy(zSql+nSql, zLine, nLine+1);
22654 nSql += nLine;
22655 }
22656 if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
 
22657 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22658 nSql = 0;
22659 if( p->outCount ){
22660 output_reset(p);
22661 p->outCount = 0;
@@ -22663,17 +22783,18 @@
22663 clearTempFile(p);
22664 }
22665 p->bSafeMode = p->bSafeModePersist;
22666 qss = QSS_Start;
22667 }else if( nSql && QSS_PLAINWHITE(qss) ){
22668 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
22669 nSql = 0;
22670 qss = QSS_Start;
22671 }
22672 }
22673 if( nSql ){
22674 /* This may be incomplete. Let the SQL parser deal with that. */
 
22675 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22676 }
22677 free(zSql);
22678 free(zLine);
22679 --p->inputNesting;
@@ -22808,11 +22929,11 @@
22808 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
22809 " -csv set output mode to 'csv'\n"
22810 #if !defined(SQLITE_OMIT_DESERIALIZE)
22811 " -deserialize open the database using sqlite3_deserialize()\n"
22812 #endif
22813 " -echo print commands before execution\n"
22814 " -init FILENAME read/process named file\n"
22815 " -[no]header turn headers on or off\n"
22816 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
22817 " -heap SIZE Size of heap for memsys3 or memsys5\n"
22818 #endif
@@ -22943,19 +23064,30 @@
22943 # define SQLITE_SHELL_IS_UTF8 (0)
22944 # else
22945 # define SQLITE_SHELL_IS_UTF8 (1)
22946 # endif
22947 #endif
 
 
 
 
22948
22949 #if SQLITE_SHELL_IS_UTF8
22950 int SQLITE_CDECL main(int argc, char **argv){
22951 #else
22952 int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
22953 char **argv;
22954 #endif
 
 
 
22955 char *zErrMsg = 0;
 
 
 
22956 ShellState data;
 
22957 const char *zInitFile = 0;
22958 int i;
22959 int rc = 0;
22960 int warnInmemoryDb = 0;
22961 int readStdin = 1;
@@ -22967,12 +23099,17 @@
22967 int argcToFree = 0;
22968 #endif
22969
22970 setBinaryMode(stdin, 0);
22971 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
 
 
 
 
22972 stdin_is_interactive = isatty(0);
22973 stdout_is_console = isatty(1);
 
22974
22975 #if !defined(_WIN32_WCE)
22976 if( getenv("SQLITE_DEBUG_BREAK") ){
22977 if( isatty(0) && isatty(2) ){
22978 fprintf(stderr,
@@ -23224,11 +23361,13 @@
23224 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
23225 return 1;
23226 #endif
23227 }
23228 data.out = stdout;
 
23229 sqlite3_appendvfs_init(0,0,0);
 
23230
23231 /* Go ahead and open the database file if it already exists. If the
23232 ** file does not exist, delay opening it. This prevents empty database
23233 ** files from being created if a user mistypes the database name argument
23234 ** to the sqlite command-line tool.
@@ -23490,10 +23629,13 @@
23490 }else{
23491 data.in = stdin;
23492 rc = process_input(&data);
23493 }
23494 }
 
 
 
23495 free(azCmd);
23496 set_table_name(&data, 0);
23497 if( data.db ){
23498 session_close_all(&data, -1);
23499 close_db(data.db);
@@ -23516,7 +23658,138 @@
23516 free(data.colWidth);
23517 free(data.zNonce);
23518 /* Clear the global data structure so that valgrind will detect memory
23519 ** leaks */
23520 memset(&data, 0, sizeof(data));
 
 
 
 
 
 
 
23521 return rc;
23522 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23523
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -245,10 +245,20 @@
245 #else
246 # define setBinaryMode(X,Y)
247 # define setTextMode(X,Y)
248 #endif
249
250 /*
251 ** When compiling with emcc (a.k.a. emscripten), we're building a
252 ** WebAssembly (WASM) bundle and need to disable and rewire a few
253 ** things.
254 */
255 #ifdef __EMSCRIPTEN__
256 #define SQLITE_SHELL_WASM_MODE
257 #else
258 #undef SQLITE_SHELL_WASM_MODE
259 #endif
260
261 /* True if the timer is enabled */
262 static int enableTimer = 0;
263
264 /* Return the current wall-clock time */
@@ -707,10 +717,11 @@
717 **
718 ** The result is stored in space obtained from malloc() and must either
719 ** be freed by the caller or else passed back into this routine via the
720 ** zPrior argument for reuse.
721 */
722 #ifndef SQLITE_SHELL_WASM_MODE
723 static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
724 char *zPrompt;
725 char *zResult;
726 if( in!=0 ){
727 zResult = local_getline(zPrior, in);
@@ -726,11 +737,11 @@
737 if( zResult && *zResult ) shell_add_history(zResult);
738 #endif
739 }
740 return zResult;
741 }
742 #endif /* !SQLITE_SHELL_WASM_MODE */
743
744 /*
745 ** Return the value of a hexadecimal digit. Return -1 if the input
746 ** is not a hex digit.
747 */
@@ -814,11 +825,11 @@
825 ** zIn, if it was not NULL, is freed.
826 **
827 ** If the third argument, quote, is not '\0', then it is used as a
828 ** quote character for zAppend.
829 */
830 static void appendText(ShellText *p, const char *zAppend, char quote){
831 int len;
832 int i;
833 int nAppend = strlen30(zAppend);
834
835 len = nAppend+p->n+1;
@@ -1379,10 +1390,121 @@
1390 #endif /* defined(WIN32) && defined(_MSC_VER) */
1391
1392 /************************* End test_windirent.c ********************/
1393 #define dirent DIRENT
1394 #endif
1395 /************************* Begin ../ext/misc/memtrace.c ******************/
1396 /*
1397 ** 2019-01-21
1398 **
1399 ** The author disclaims copyright to this source code. In place of
1400 ** a legal notice, here is a blessing:
1401 **
1402 ** May you do good and not evil.
1403 ** May you find forgiveness for yourself and forgive others.
1404 ** May you share freely, never taking more than you give.
1405 **
1406 *************************************************************************
1407 **
1408 ** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
1409 ** mechanism to add a tracing layer on top of SQLite. If this extension
1410 ** is registered prior to sqlite3_initialize(), it will cause all memory
1411 ** allocation activities to be logged on standard output, or to some other
1412 ** FILE specified by the initializer.
1413 **
1414 ** This file needs to be compiled into the application that uses it.
1415 **
1416 ** This extension is used to implement the --memtrace option of the
1417 ** command-line shell.
1418 */
1419 #include <assert.h>
1420 #include <string.h>
1421 #include <stdio.h>
1422
1423 /* The original memory allocation routines */
1424 static sqlite3_mem_methods memtraceBase;
1425 static FILE *memtraceOut;
1426
1427 /* Methods that trace memory allocations */
1428 static void *memtraceMalloc(int n){
1429 if( memtraceOut ){
1430 fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
1431 memtraceBase.xRoundup(n));
1432 }
1433 return memtraceBase.xMalloc(n);
1434 }
1435 static void memtraceFree(void *p){
1436 if( p==0 ) return;
1437 if( memtraceOut ){
1438 fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
1439 }
1440 memtraceBase.xFree(p);
1441 }
1442 static void *memtraceRealloc(void *p, int n){
1443 if( p==0 ) return memtraceMalloc(n);
1444 if( n==0 ){
1445 memtraceFree(p);
1446 return 0;
1447 }
1448 if( memtraceOut ){
1449 fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
1450 memtraceBase.xSize(p), memtraceBase.xRoundup(n));
1451 }
1452 return memtraceBase.xRealloc(p, n);
1453 }
1454 static int memtraceSize(void *p){
1455 return memtraceBase.xSize(p);
1456 }
1457 static int memtraceRoundup(int n){
1458 return memtraceBase.xRoundup(n);
1459 }
1460 static int memtraceInit(void *p){
1461 return memtraceBase.xInit(p);
1462 }
1463 static void memtraceShutdown(void *p){
1464 memtraceBase.xShutdown(p);
1465 }
1466
1467 /* The substitute memory allocator */
1468 static sqlite3_mem_methods ersaztMethods = {
1469 memtraceMalloc,
1470 memtraceFree,
1471 memtraceRealloc,
1472 memtraceSize,
1473 memtraceRoundup,
1474 memtraceInit,
1475 memtraceShutdown,
1476 0
1477 };
1478
1479 /* Begin tracing memory allocations to out. */
1480 int sqlite3MemTraceActivate(FILE *out){
1481 int rc = SQLITE_OK;
1482 if( memtraceBase.xMalloc==0 ){
1483 rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
1484 if( rc==SQLITE_OK ){
1485 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
1486 }
1487 }
1488 memtraceOut = out;
1489 return rc;
1490 }
1491
1492 /* Deactivate memory tracing */
1493 int sqlite3MemTraceDeactivate(void){
1494 int rc = SQLITE_OK;
1495 if( memtraceBase.xMalloc!=0 ){
1496 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
1497 if( rc==SQLITE_OK ){
1498 memset(&memtraceBase, 0, sizeof(memtraceBase));
1499 }
1500 }
1501 memtraceOut = 0;
1502 return rc;
1503 }
1504
1505 /************************* End ../ext/misc/memtrace.c ********************/
1506 /************************* Begin ../ext/misc/shathree.c ******************/
1507 /*
1508 ** 2017-03-08
1509 **
1510 ** The author disclaims copyright to this source code. In place of
@@ -2106,2333 +2228,10 @@
2228 }
2229 return rc;
2230 }
2231
2232 /************************* End ../ext/misc/shathree.c ********************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2233 /************************* Begin ../ext/misc/uint.c ******************/
2234 /*
2235 ** 2020-04-14
2236 **
2237 ** The author disclaims copyright to this source code. In place of
@@ -6696,10 +4495,2224 @@
4495 }
4496 return rc;
4497 }
4498
4499 /************************* End ../ext/misc/regexp.c ********************/
4500 #ifndef SQLITE_SHELL_WASM_MODE
4501 /************************* Begin ../ext/misc/fileio.c ******************/
4502 /*
4503 ** 2014-06-13
4504 **
4505 ** The author disclaims copyright to this source code. In place of
4506 ** a legal notice, here is a blessing:
4507 **
4508 ** May you do good and not evil.
4509 ** May you find forgiveness for yourself and forgive others.
4510 ** May you share freely, never taking more than you give.
4511 **
4512 ******************************************************************************
4513 **
4514 ** This SQLite extension implements SQL functions readfile() and
4515 ** writefile(), and eponymous virtual type "fsdir".
4516 **
4517 ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
4518 **
4519 ** If neither of the optional arguments is present, then this UDF
4520 ** function writes blob DATA to file FILE. If successful, the number
4521 ** of bytes written is returned. If an error occurs, NULL is returned.
4522 **
4523 ** If the first option argument - MODE - is present, then it must
4524 ** be passed an integer value that corresponds to a POSIX mode
4525 ** value (file type + permissions, as returned in the stat.st_mode
4526 ** field by the stat() system call). Three types of files may
4527 ** be written/created:
4528 **
4529 ** regular files: (mode & 0170000)==0100000
4530 ** symbolic links: (mode & 0170000)==0120000
4531 ** directories: (mode & 0170000)==0040000
4532 **
4533 ** For a directory, the DATA is ignored. For a symbolic link, it is
4534 ** interpreted as text and used as the target of the link. For a
4535 ** regular file, it is interpreted as a blob and written into the
4536 ** named file. Regardless of the type of file, its permissions are
4537 ** set to (mode & 0777) before returning.
4538 **
4539 ** If the optional MTIME argument is present, then it is interpreted
4540 ** as an integer - the number of seconds since the unix epoch. The
4541 ** modification-time of the target file is set to this value before
4542 ** returning.
4543 **
4544 ** If three or more arguments are passed to this function and an
4545 ** error is encountered, an exception is raised.
4546 **
4547 ** READFILE(FILE):
4548 **
4549 ** Read and return the contents of file FILE (type blob) from disk.
4550 **
4551 ** FSDIR:
4552 **
4553 ** Used as follows:
4554 **
4555 ** SELECT * FROM fsdir($path [, $dir]);
4556 **
4557 ** Parameter $path is an absolute or relative pathname. If the file that it
4558 ** refers to does not exist, it is an error. If the path refers to a regular
4559 ** file or symbolic link, it returns a single row. Or, if the path refers
4560 ** to a directory, it returns one row for the directory, and one row for each
4561 ** file within the hierarchy rooted at $path.
4562 **
4563 ** Each row has the following columns:
4564 **
4565 ** name: Path to file or directory (text value).
4566 ** mode: Value of stat.st_mode for directory entry (an integer).
4567 ** mtime: Value of stat.st_mtime for directory entry (an integer).
4568 ** data: For a regular file, a blob containing the file data. For a
4569 ** symlink, a text value containing the text of the link. For a
4570 ** directory, NULL.
4571 **
4572 ** If a non-NULL value is specified for the optional $dir parameter and
4573 ** $path is a relative path, then $path is interpreted relative to $dir.
4574 ** And the paths returned in the "name" column of the table are also
4575 ** relative to directory $dir.
4576 **
4577 ** Notes on building this extension for Windows:
4578 ** Unless linked statically with the SQLite library, a preprocessor
4579 ** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
4580 ** DLL form of this extension for WIN32. See its use below for details.
4581 */
4582 /* #include "sqlite3ext.h" */
4583 SQLITE_EXTENSION_INIT1
4584 #include <stdio.h>
4585 #include <string.h>
4586 #include <assert.h>
4587
4588 #include <sys/types.h>
4589 #include <sys/stat.h>
4590 #include <fcntl.h>
4591 #if !defined(_WIN32) && !defined(WIN32)
4592 # include <unistd.h>
4593 # include <dirent.h>
4594 # include <utime.h>
4595 # include <sys/time.h>
4596 #else
4597 # include "windows.h"
4598 # include <io.h>
4599 # include <direct.h>
4600 /* # include "test_windirent.h" */
4601 # define dirent DIRENT
4602 # ifndef chmod
4603 # define chmod _chmod
4604 # endif
4605 # ifndef stat
4606 # define stat _stat
4607 # endif
4608 # define mkdir(path,mode) _mkdir(path)
4609 # define lstat(path,buf) stat(path,buf)
4610 #endif
4611 #include <time.h>
4612 #include <errno.h>
4613
4614
4615 /*
4616 ** Structure of the fsdir() table-valued function
4617 */
4618 /* 0 1 2 3 4 5 */
4619 #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
4620 #define FSDIR_COLUMN_NAME 0 /* Name of the file */
4621 #define FSDIR_COLUMN_MODE 1 /* Access mode */
4622 #define FSDIR_COLUMN_MTIME 2 /* Last modification time */
4623 #define FSDIR_COLUMN_DATA 3 /* File content */
4624 #define FSDIR_COLUMN_PATH 4 /* Path to top of search */
4625 #define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
4626
4627
4628 /*
4629 ** Set the result stored by context ctx to a blob containing the
4630 ** contents of file zName. Or, leave the result unchanged (NULL)
4631 ** if the file does not exist or is unreadable.
4632 **
4633 ** If the file exceeds the SQLite blob size limit, through an
4634 ** SQLITE_TOOBIG error.
4635 **
4636 ** Throw an SQLITE_IOERR if there are difficulties pulling the file
4637 ** off of disk.
4638 */
4639 static void readFileContents(sqlite3_context *ctx, const char *zName){
4640 FILE *in;
4641 sqlite3_int64 nIn;
4642 void *pBuf;
4643 sqlite3 *db;
4644 int mxBlob;
4645
4646 in = fopen(zName, "rb");
4647 if( in==0 ){
4648 /* File does not exist or is unreadable. Leave the result set to NULL. */
4649 return;
4650 }
4651 fseek(in, 0, SEEK_END);
4652 nIn = ftell(in);
4653 rewind(in);
4654 db = sqlite3_context_db_handle(ctx);
4655 mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
4656 if( nIn>mxBlob ){
4657 sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
4658 fclose(in);
4659 return;
4660 }
4661 pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
4662 if( pBuf==0 ){
4663 sqlite3_result_error_nomem(ctx);
4664 fclose(in);
4665 return;
4666 }
4667 if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
4668 sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
4669 }else{
4670 sqlite3_result_error_code(ctx, SQLITE_IOERR);
4671 sqlite3_free(pBuf);
4672 }
4673 fclose(in);
4674 }
4675
4676 /*
4677 ** Implementation of the "readfile(X)" SQL function. The entire content
4678 ** of the file named X is read and returned as a BLOB. NULL is returned
4679 ** if the file does not exist or is unreadable.
4680 */
4681 static void readfileFunc(
4682 sqlite3_context *context,
4683 int argc,
4684 sqlite3_value **argv
4685 ){
4686 const char *zName;
4687 (void)(argc); /* Unused parameter */
4688 zName = (const char*)sqlite3_value_text(argv[0]);
4689 if( zName==0 ) return;
4690 readFileContents(context, zName);
4691 }
4692
4693 /*
4694 ** Set the error message contained in context ctx to the results of
4695 ** vprintf(zFmt, ...).
4696 */
4697 static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
4698 char *zMsg = 0;
4699 va_list ap;
4700 va_start(ap, zFmt);
4701 zMsg = sqlite3_vmprintf(zFmt, ap);
4702 sqlite3_result_error(ctx, zMsg, -1);
4703 sqlite3_free(zMsg);
4704 va_end(ap);
4705 }
4706
4707 #if defined(_WIN32)
4708 /*
4709 ** This function is designed to convert a Win32 FILETIME structure into the
4710 ** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
4711 */
4712 static sqlite3_uint64 fileTimeToUnixTime(
4713 LPFILETIME pFileTime
4714 ){
4715 SYSTEMTIME epochSystemTime;
4716 ULARGE_INTEGER epochIntervals;
4717 FILETIME epochFileTime;
4718 ULARGE_INTEGER fileIntervals;
4719
4720 memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
4721 epochSystemTime.wYear = 1970;
4722 epochSystemTime.wMonth = 1;
4723 epochSystemTime.wDay = 1;
4724 SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
4725 epochIntervals.LowPart = epochFileTime.dwLowDateTime;
4726 epochIntervals.HighPart = epochFileTime.dwHighDateTime;
4727
4728 fileIntervals.LowPart = pFileTime->dwLowDateTime;
4729 fileIntervals.HighPart = pFileTime->dwHighDateTime;
4730
4731 return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
4732 }
4733
4734
4735 #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
4736 # /* To allow a standalone DLL, use this next replacement function: */
4737 # undef sqlite3_win32_utf8_to_unicode
4738 # define sqlite3_win32_utf8_to_unicode utf8_to_utf16
4739 #
4740 LPWSTR utf8_to_utf16(const char *z){
4741 int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
4742 LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
4743 if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
4744 return rv;
4745 sqlite3_free(rv);
4746 return 0;
4747 }
4748 #endif
4749
4750 /*
4751 ** This function attempts to normalize the time values found in the stat()
4752 ** buffer to UTC. This is necessary on Win32, where the runtime library
4753 ** appears to return these values as local times.
4754 */
4755 static void statTimesToUtc(
4756 const char *zPath,
4757 struct stat *pStatBuf
4758 ){
4759 HANDLE hFindFile;
4760 WIN32_FIND_DATAW fd;
4761 LPWSTR zUnicodeName;
4762 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
4763 zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
4764 if( zUnicodeName ){
4765 memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
4766 hFindFile = FindFirstFileW(zUnicodeName, &fd);
4767 if( hFindFile!=NULL ){
4768 pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
4769 pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
4770 pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
4771 FindClose(hFindFile);
4772 }
4773 sqlite3_free(zUnicodeName);
4774 }
4775 }
4776 #endif
4777
4778 /*
4779 ** This function is used in place of stat(). On Windows, special handling
4780 ** is required in order for the included time to be returned as UTC. On all
4781 ** other systems, this function simply calls stat().
4782 */
4783 static int fileStat(
4784 const char *zPath,
4785 struct stat *pStatBuf
4786 ){
4787 #if defined(_WIN32)
4788 int rc = stat(zPath, pStatBuf);
4789 if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
4790 return rc;
4791 #else
4792 return stat(zPath, pStatBuf);
4793 #endif
4794 }
4795
4796 /*
4797 ** This function is used in place of lstat(). On Windows, special handling
4798 ** is required in order for the included time to be returned as UTC. On all
4799 ** other systems, this function simply calls lstat().
4800 */
4801 static int fileLinkStat(
4802 const char *zPath,
4803 struct stat *pStatBuf
4804 ){
4805 #if defined(_WIN32)
4806 int rc = lstat(zPath, pStatBuf);
4807 if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
4808 return rc;
4809 #else
4810 return lstat(zPath, pStatBuf);
4811 #endif
4812 }
4813
4814 /*
4815 ** Argument zFile is the name of a file that will be created and/or written
4816 ** by SQL function writefile(). This function ensures that the directory
4817 ** zFile will be written to exists, creating it if required. The permissions
4818 ** for any path components created by this function are set in accordance
4819 ** with the current umask.
4820 **
4821 ** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
4822 ** SQLITE_OK is returned if the directory is successfully created, or
4823 ** SQLITE_ERROR otherwise.
4824 */
4825 static int makeDirectory(
4826 const char *zFile
4827 ){
4828 char *zCopy = sqlite3_mprintf("%s", zFile);
4829 int rc = SQLITE_OK;
4830
4831 if( zCopy==0 ){
4832 rc = SQLITE_NOMEM;
4833 }else{
4834 int nCopy = (int)strlen(zCopy);
4835 int i = 1;
4836
4837 while( rc==SQLITE_OK ){
4838 struct stat sStat;
4839 int rc2;
4840
4841 for(; zCopy[i]!='/' && i<nCopy; i++);
4842 if( i==nCopy ) break;
4843 zCopy[i] = '\0';
4844
4845 rc2 = fileStat(zCopy, &sStat);
4846 if( rc2!=0 ){
4847 if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
4848 }else{
4849 if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
4850 }
4851 zCopy[i] = '/';
4852 i++;
4853 }
4854
4855 sqlite3_free(zCopy);
4856 }
4857
4858 return rc;
4859 }
4860
4861 /*
4862 ** This function does the work for the writefile() UDF. Refer to
4863 ** header comments at the top of this file for details.
4864 */
4865 static int writeFile(
4866 sqlite3_context *pCtx, /* Context to return bytes written in */
4867 const char *zFile, /* File to write */
4868 sqlite3_value *pData, /* Data to write */
4869 mode_t mode, /* MODE parameter passed to writefile() */
4870 sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */
4871 ){
4872 if( zFile==0 ) return 1;
4873 #if !defined(_WIN32) && !defined(WIN32)
4874 if( S_ISLNK(mode) ){
4875 const char *zTo = (const char*)sqlite3_value_text(pData);
4876 if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
4877 }else
4878 #endif
4879 {
4880 if( S_ISDIR(mode) ){
4881 if( mkdir(zFile, mode) ){
4882 /* The mkdir() call to create the directory failed. This might not
4883 ** be an error though - if there is already a directory at the same
4884 ** path and either the permissions already match or can be changed
4885 ** to do so using chmod(), it is not an error. */
4886 struct stat sStat;
4887 if( errno!=EEXIST
4888 || 0!=fileStat(zFile, &sStat)
4889 || !S_ISDIR(sStat.st_mode)
4890 || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
4891 ){
4892 return 1;
4893 }
4894 }
4895 }else{
4896 sqlite3_int64 nWrite = 0;
4897 const char *z;
4898 int rc = 0;
4899 FILE *out = fopen(zFile, "wb");
4900 if( out==0 ) return 1;
4901 z = (const char*)sqlite3_value_blob(pData);
4902 if( z ){
4903 sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
4904 nWrite = sqlite3_value_bytes(pData);
4905 if( nWrite!=n ){
4906 rc = 1;
4907 }
4908 }
4909 fclose(out);
4910 if( rc==0 && mode && chmod(zFile, mode & 0777) ){
4911 rc = 1;
4912 }
4913 if( rc ) return 2;
4914 sqlite3_result_int64(pCtx, nWrite);
4915 }
4916 }
4917
4918 if( mtime>=0 ){
4919 #if defined(_WIN32)
4920 #if !SQLITE_OS_WINRT
4921 /* Windows */
4922 FILETIME lastAccess;
4923 FILETIME lastWrite;
4924 SYSTEMTIME currentTime;
4925 LONGLONG intervals;
4926 HANDLE hFile;
4927 LPWSTR zUnicodeName;
4928 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
4929
4930 GetSystemTime(&currentTime);
4931 SystemTimeToFileTime(&currentTime, &lastAccess);
4932 intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
4933 lastWrite.dwLowDateTime = (DWORD)intervals;
4934 lastWrite.dwHighDateTime = intervals >> 32;
4935 zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
4936 if( zUnicodeName==0 ){
4937 return 1;
4938 }
4939 hFile = CreateFileW(
4940 zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
4941 FILE_FLAG_BACKUP_SEMANTICS, NULL
4942 );
4943 sqlite3_free(zUnicodeName);
4944 if( hFile!=INVALID_HANDLE_VALUE ){
4945 BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
4946 CloseHandle(hFile);
4947 return !bResult;
4948 }else{
4949 return 1;
4950 }
4951 #endif
4952 #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
4953 /* Recent unix */
4954 struct timespec times[2];
4955 times[0].tv_nsec = times[1].tv_nsec = 0;
4956 times[0].tv_sec = time(0);
4957 times[1].tv_sec = mtime;
4958 if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
4959 return 1;
4960 }
4961 #else
4962 /* Legacy unix */
4963 struct timeval times[2];
4964 times[0].tv_usec = times[1].tv_usec = 0;
4965 times[0].tv_sec = time(0);
4966 times[1].tv_sec = mtime;
4967 if( utimes(zFile, times) ){
4968 return 1;
4969 }
4970 #endif
4971 }
4972
4973 return 0;
4974 }
4975
4976 /*
4977 ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
4978 ** Refer to header comments at the top of this file for details.
4979 */
4980 static void writefileFunc(
4981 sqlite3_context *context,
4982 int argc,
4983 sqlite3_value **argv
4984 ){
4985 const char *zFile;
4986 mode_t mode = 0;
4987 int res;
4988 sqlite3_int64 mtime = -1;
4989
4990 if( argc<2 || argc>4 ){
4991 sqlite3_result_error(context,
4992 "wrong number of arguments to function writefile()", -1
4993 );
4994 return;
4995 }
4996
4997 zFile = (const char*)sqlite3_value_text(argv[0]);
4998 if( zFile==0 ) return;
4999 if( argc>=3 ){
5000 mode = (mode_t)sqlite3_value_int(argv[2]);
5001 }
5002 if( argc==4 ){
5003 mtime = sqlite3_value_int64(argv[3]);
5004 }
5005
5006 res = writeFile(context, zFile, argv[1], mode, mtime);
5007 if( res==1 && errno==ENOENT ){
5008 if( makeDirectory(zFile)==SQLITE_OK ){
5009 res = writeFile(context, zFile, argv[1], mode, mtime);
5010 }
5011 }
5012
5013 if( argc>2 && res!=0 ){
5014 if( S_ISLNK(mode) ){
5015 ctxErrorMsg(context, "failed to create symlink: %s", zFile);
5016 }else if( S_ISDIR(mode) ){
5017 ctxErrorMsg(context, "failed to create directory: %s", zFile);
5018 }else{
5019 ctxErrorMsg(context, "failed to write file: %s", zFile);
5020 }
5021 }
5022 }
5023
5024 /*
5025 ** SQL function: lsmode(MODE)
5026 **
5027 ** Given a numberic st_mode from stat(), convert it into a human-readable
5028 ** text string in the style of "ls -l".
5029 */
5030 static void lsModeFunc(
5031 sqlite3_context *context,
5032 int argc,
5033 sqlite3_value **argv
5034 ){
5035 int i;
5036 int iMode = sqlite3_value_int(argv[0]);
5037 char z[16];
5038 (void)argc;
5039 if( S_ISLNK(iMode) ){
5040 z[0] = 'l';
5041 }else if( S_ISREG(iMode) ){
5042 z[0] = '-';
5043 }else if( S_ISDIR(iMode) ){
5044 z[0] = 'd';
5045 }else{
5046 z[0] = '?';
5047 }
5048 for(i=0; i<3; i++){
5049 int m = (iMode >> ((2-i)*3));
5050 char *a = &z[1 + i*3];
5051 a[0] = (m & 0x4) ? 'r' : '-';
5052 a[1] = (m & 0x2) ? 'w' : '-';
5053 a[2] = (m & 0x1) ? 'x' : '-';
5054 }
5055 z[10] = '\0';
5056 sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
5057 }
5058
5059 #ifndef SQLITE_OMIT_VIRTUALTABLE
5060
5061 /*
5062 ** Cursor type for recursively iterating through a directory structure.
5063 */
5064 typedef struct fsdir_cursor fsdir_cursor;
5065 typedef struct FsdirLevel FsdirLevel;
5066
5067 struct FsdirLevel {
5068 DIR *pDir; /* From opendir() */
5069 char *zDir; /* Name of directory (nul-terminated) */
5070 };
5071
5072 struct fsdir_cursor {
5073 sqlite3_vtab_cursor base; /* Base class - must be first */
5074
5075 int nLvl; /* Number of entries in aLvl[] array */
5076 int iLvl; /* Index of current entry */
5077 FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
5078
5079 const char *zBase;
5080 int nBase;
5081
5082 struct stat sStat; /* Current lstat() results */
5083 char *zPath; /* Path to current entry */
5084 sqlite3_int64 iRowid; /* Current rowid */
5085 };
5086
5087 typedef struct fsdir_tab fsdir_tab;
5088 struct fsdir_tab {
5089 sqlite3_vtab base; /* Base class - must be first */
5090 };
5091
5092 /*
5093 ** Construct a new fsdir virtual table object.
5094 */
5095 static int fsdirConnect(
5096 sqlite3 *db,
5097 void *pAux,
5098 int argc, const char *const*argv,
5099 sqlite3_vtab **ppVtab,
5100 char **pzErr
5101 ){
5102 fsdir_tab *pNew = 0;
5103 int rc;
5104 (void)pAux;
5105 (void)argc;
5106 (void)argv;
5107 (void)pzErr;
5108 rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
5109 if( rc==SQLITE_OK ){
5110 pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
5111 if( pNew==0 ) return SQLITE_NOMEM;
5112 memset(pNew, 0, sizeof(*pNew));
5113 sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
5114 }
5115 *ppVtab = (sqlite3_vtab*)pNew;
5116 return rc;
5117 }
5118
5119 /*
5120 ** This method is the destructor for fsdir vtab objects.
5121 */
5122 static int fsdirDisconnect(sqlite3_vtab *pVtab){
5123 sqlite3_free(pVtab);
5124 return SQLITE_OK;
5125 }
5126
5127 /*
5128 ** Constructor for a new fsdir_cursor object.
5129 */
5130 static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
5131 fsdir_cursor *pCur;
5132 (void)p;
5133 pCur = sqlite3_malloc( sizeof(*pCur) );
5134 if( pCur==0 ) return SQLITE_NOMEM;
5135 memset(pCur, 0, sizeof(*pCur));
5136 pCur->iLvl = -1;
5137 *ppCursor = &pCur->base;
5138 return SQLITE_OK;
5139 }
5140
5141 /*
5142 ** Reset a cursor back to the state it was in when first returned
5143 ** by fsdirOpen().
5144 */
5145 static void fsdirResetCursor(fsdir_cursor *pCur){
5146 int i;
5147 for(i=0; i<=pCur->iLvl; i++){
5148 FsdirLevel *pLvl = &pCur->aLvl[i];
5149 if( pLvl->pDir ) closedir(pLvl->pDir);
5150 sqlite3_free(pLvl->zDir);
5151 }
5152 sqlite3_free(pCur->zPath);
5153 sqlite3_free(pCur->aLvl);
5154 pCur->aLvl = 0;
5155 pCur->zPath = 0;
5156 pCur->zBase = 0;
5157 pCur->nBase = 0;
5158 pCur->nLvl = 0;
5159 pCur->iLvl = -1;
5160 pCur->iRowid = 1;
5161 }
5162
5163 /*
5164 ** Destructor for an fsdir_cursor.
5165 */
5166 static int fsdirClose(sqlite3_vtab_cursor *cur){
5167 fsdir_cursor *pCur = (fsdir_cursor*)cur;
5168
5169 fsdirResetCursor(pCur);
5170 sqlite3_free(pCur);
5171 return SQLITE_OK;
5172 }
5173
5174 /*
5175 ** Set the error message for the virtual table associated with cursor
5176 ** pCur to the results of vprintf(zFmt, ...).
5177 */
5178 static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
5179 va_list ap;
5180 va_start(ap, zFmt);
5181 pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
5182 va_end(ap);
5183 }
5184
5185
5186 /*
5187 ** Advance an fsdir_cursor to its next row of output.
5188 */
5189 static int fsdirNext(sqlite3_vtab_cursor *cur){
5190 fsdir_cursor *pCur = (fsdir_cursor*)cur;
5191 mode_t m = pCur->sStat.st_mode;
5192
5193 pCur->iRowid++;
5194 if( S_ISDIR(m) ){
5195 /* Descend into this directory */
5196 int iNew = pCur->iLvl + 1;
5197 FsdirLevel *pLvl;
5198 if( iNew>=pCur->nLvl ){
5199 int nNew = iNew+1;
5200 sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
5201 FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
5202 if( aNew==0 ) return SQLITE_NOMEM;
5203 memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
5204 pCur->aLvl = aNew;
5205 pCur->nLvl = nNew;
5206 }
5207 pCur->iLvl = iNew;
5208 pLvl = &pCur->aLvl[iNew];
5209
5210 pLvl->zDir = pCur->zPath;
5211 pCur->zPath = 0;
5212 pLvl->pDir = opendir(pLvl->zDir);
5213 if( pLvl->pDir==0 ){
5214 fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
5215 return SQLITE_ERROR;
5216 }
5217 }
5218
5219 while( pCur->iLvl>=0 ){
5220 FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
5221 struct dirent *pEntry = readdir(pLvl->pDir);
5222 if( pEntry ){
5223 if( pEntry->d_name[0]=='.' ){
5224 if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
5225 if( pEntry->d_name[1]=='\0' ) continue;
5226 }
5227 sqlite3_free(pCur->zPath);
5228 pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
5229 if( pCur->zPath==0 ) return SQLITE_NOMEM;
5230 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
5231 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
5232 return SQLITE_ERROR;
5233 }
5234 return SQLITE_OK;
5235 }
5236 closedir(pLvl->pDir);
5237 sqlite3_free(pLvl->zDir);
5238 pLvl->pDir = 0;
5239 pLvl->zDir = 0;
5240 pCur->iLvl--;
5241 }
5242
5243 /* EOF */
5244 sqlite3_free(pCur->zPath);
5245 pCur->zPath = 0;
5246 return SQLITE_OK;
5247 }
5248
5249 /*
5250 ** Return values of columns for the row at which the series_cursor
5251 ** is currently pointing.
5252 */
5253 static int fsdirColumn(
5254 sqlite3_vtab_cursor *cur, /* The cursor */
5255 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
5256 int i /* Which column to return */
5257 ){
5258 fsdir_cursor *pCur = (fsdir_cursor*)cur;
5259 switch( i ){
5260 case FSDIR_COLUMN_NAME: {
5261 sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
5262 break;
5263 }
5264
5265 case FSDIR_COLUMN_MODE:
5266 sqlite3_result_int64(ctx, pCur->sStat.st_mode);
5267 break;
5268
5269 case FSDIR_COLUMN_MTIME:
5270 sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
5271 break;
5272
5273 case FSDIR_COLUMN_DATA: {
5274 mode_t m = pCur->sStat.st_mode;
5275 if( S_ISDIR(m) ){
5276 sqlite3_result_null(ctx);
5277 #if !defined(_WIN32) && !defined(WIN32)
5278 }else if( S_ISLNK(m) ){
5279 char aStatic[64];
5280 char *aBuf = aStatic;
5281 sqlite3_int64 nBuf = 64;
5282 int n;
5283
5284 while( 1 ){
5285 n = readlink(pCur->zPath, aBuf, nBuf);
5286 if( n<nBuf ) break;
5287 if( aBuf!=aStatic ) sqlite3_free(aBuf);
5288 nBuf = nBuf*2;
5289 aBuf = sqlite3_malloc64(nBuf);
5290 if( aBuf==0 ){
5291 sqlite3_result_error_nomem(ctx);
5292 return SQLITE_NOMEM;
5293 }
5294 }
5295
5296 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
5297 if( aBuf!=aStatic ) sqlite3_free(aBuf);
5298 #endif
5299 }else{
5300 readFileContents(ctx, pCur->zPath);
5301 }
5302 }
5303 case FSDIR_COLUMN_PATH:
5304 default: {
5305 /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
5306 ** always return their values as NULL */
5307 break;
5308 }
5309 }
5310 return SQLITE_OK;
5311 }
5312
5313 /*
5314 ** Return the rowid for the current row. In this implementation, the
5315 ** first row returned is assigned rowid value 1, and each subsequent
5316 ** row a value 1 more than that of the previous.
5317 */
5318 static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
5319 fsdir_cursor *pCur = (fsdir_cursor*)cur;
5320 *pRowid = pCur->iRowid;
5321 return SQLITE_OK;
5322 }
5323
5324 /*
5325 ** Return TRUE if the cursor has been moved off of the last
5326 ** row of output.
5327 */
5328 static int fsdirEof(sqlite3_vtab_cursor *cur){
5329 fsdir_cursor *pCur = (fsdir_cursor*)cur;
5330 return (pCur->zPath==0);
5331 }
5332
5333 /*
5334 ** xFilter callback.
5335 **
5336 ** idxNum==1 PATH parameter only
5337 ** idxNum==2 Both PATH and DIR supplied
5338 */
5339 static int fsdirFilter(
5340 sqlite3_vtab_cursor *cur,
5341 int idxNum, const char *idxStr,
5342 int argc, sqlite3_value **argv
5343 ){
5344 const char *zDir = 0;
5345 fsdir_cursor *pCur = (fsdir_cursor*)cur;
5346 (void)idxStr;
5347 fsdirResetCursor(pCur);
5348
5349 if( idxNum==0 ){
5350 fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
5351 return SQLITE_ERROR;
5352 }
5353
5354 assert( argc==idxNum && (argc==1 || argc==2) );
5355 zDir = (const char*)sqlite3_value_text(argv[0]);
5356 if( zDir==0 ){
5357 fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
5358 return SQLITE_ERROR;
5359 }
5360 if( argc==2 ){
5361 pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
5362 }
5363 if( pCur->zBase ){
5364 pCur->nBase = (int)strlen(pCur->zBase)+1;
5365 pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
5366 }else{
5367 pCur->zPath = sqlite3_mprintf("%s", zDir);
5368 }
5369
5370 if( pCur->zPath==0 ){
5371 return SQLITE_NOMEM;
5372 }
5373 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
5374 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
5375 return SQLITE_ERROR;
5376 }
5377
5378 return SQLITE_OK;
5379 }
5380
5381 /*
5382 ** SQLite will invoke this method one or more times while planning a query
5383 ** that uses the generate_series virtual table. This routine needs to create
5384 ** a query plan for each invocation and compute an estimated cost for that
5385 ** plan.
5386 **
5387 ** In this implementation idxNum is used to represent the
5388 ** query plan. idxStr is unused.
5389 **
5390 ** The query plan is represented by values of idxNum:
5391 **
5392 ** (1) The path value is supplied by argv[0]
5393 ** (2) Path is in argv[0] and dir is in argv[1]
5394 */
5395 static int fsdirBestIndex(
5396 sqlite3_vtab *tab,
5397 sqlite3_index_info *pIdxInfo
5398 ){
5399 int i; /* Loop over constraints */
5400 int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
5401 int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
5402 int seenPath = 0; /* True if an unusable PATH= constraint is seen */
5403 int seenDir = 0; /* True if an unusable DIR= constraint is seen */
5404 const struct sqlite3_index_constraint *pConstraint;
5405
5406 (void)tab;
5407 pConstraint = pIdxInfo->aConstraint;
5408 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
5409 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
5410 switch( pConstraint->iColumn ){
5411 case FSDIR_COLUMN_PATH: {
5412 if( pConstraint->usable ){
5413 idxPath = i;
5414 seenPath = 0;
5415 }else if( idxPath<0 ){
5416 seenPath = 1;
5417 }
5418 break;
5419 }
5420 case FSDIR_COLUMN_DIR: {
5421 if( pConstraint->usable ){
5422 idxDir = i;
5423 seenDir = 0;
5424 }else if( idxDir<0 ){
5425 seenDir = 1;
5426 }
5427 break;
5428 }
5429 }
5430 }
5431 if( seenPath || seenDir ){
5432 /* If input parameters are unusable, disallow this plan */
5433 return SQLITE_CONSTRAINT;
5434 }
5435
5436 if( idxPath<0 ){
5437 pIdxInfo->idxNum = 0;
5438 /* The pIdxInfo->estimatedCost should have been initialized to a huge
5439 ** number. Leave it unchanged. */
5440 pIdxInfo->estimatedRows = 0x7fffffff;
5441 }else{
5442 pIdxInfo->aConstraintUsage[idxPath].omit = 1;
5443 pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
5444 if( idxDir>=0 ){
5445 pIdxInfo->aConstraintUsage[idxDir].omit = 1;
5446 pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
5447 pIdxInfo->idxNum = 2;
5448 pIdxInfo->estimatedCost = 10.0;
5449 }else{
5450 pIdxInfo->idxNum = 1;
5451 pIdxInfo->estimatedCost = 100.0;
5452 }
5453 }
5454
5455 return SQLITE_OK;
5456 }
5457
5458 /*
5459 ** Register the "fsdir" virtual table.
5460 */
5461 static int fsdirRegister(sqlite3 *db){
5462 static sqlite3_module fsdirModule = {
5463 0, /* iVersion */
5464 0, /* xCreate */
5465 fsdirConnect, /* xConnect */
5466 fsdirBestIndex, /* xBestIndex */
5467 fsdirDisconnect, /* xDisconnect */
5468 0, /* xDestroy */
5469 fsdirOpen, /* xOpen - open a cursor */
5470 fsdirClose, /* xClose - close a cursor */
5471 fsdirFilter, /* xFilter - configure scan constraints */
5472 fsdirNext, /* xNext - advance a cursor */
5473 fsdirEof, /* xEof - check for end of scan */
5474 fsdirColumn, /* xColumn - read data */
5475 fsdirRowid, /* xRowid - read data */
5476 0, /* xUpdate */
5477 0, /* xBegin */
5478 0, /* xSync */
5479 0, /* xCommit */
5480 0, /* xRollback */
5481 0, /* xFindMethod */
5482 0, /* xRename */
5483 0, /* xSavepoint */
5484 0, /* xRelease */
5485 0, /* xRollbackTo */
5486 0, /* xShadowName */
5487 };
5488
5489 int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
5490 return rc;
5491 }
5492 #else /* SQLITE_OMIT_VIRTUALTABLE */
5493 # define fsdirRegister(x) SQLITE_OK
5494 #endif
5495
5496 #ifdef _WIN32
5497
5498 #endif
5499 int sqlite3_fileio_init(
5500 sqlite3 *db,
5501 char **pzErrMsg,
5502 const sqlite3_api_routines *pApi
5503 ){
5504 int rc = SQLITE_OK;
5505 SQLITE_EXTENSION_INIT2(pApi);
5506 (void)pzErrMsg; /* Unused parameter */
5507 rc = sqlite3_create_function(db, "readfile", 1,
5508 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
5509 readfileFunc, 0, 0);
5510 if( rc==SQLITE_OK ){
5511 rc = sqlite3_create_function(db, "writefile", -1,
5512 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
5513 writefileFunc, 0, 0);
5514 }
5515 if( rc==SQLITE_OK ){
5516 rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
5517 lsModeFunc, 0, 0);
5518 }
5519 if( rc==SQLITE_OK ){
5520 rc = fsdirRegister(db);
5521 }
5522 return rc;
5523 }
5524
5525 #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
5526 /* To allow a standalone DLL, make test_windirent.c use the same
5527 * redefined SQLite API calls as the above extension code does.
5528 * Just pull in this .c to accomplish this. As a beneficial side
5529 * effect, this extension becomes a single translation unit. */
5530 # include "test_windirent.c"
5531 #endif
5532
5533 /************************* End ../ext/misc/fileio.c ********************/
5534 /************************* Begin ../ext/misc/completion.c ******************/
5535 /*
5536 ** 2017-07-10
5537 **
5538 ** The author disclaims copyright to this source code. In place of
5539 ** a legal notice, here is a blessing:
5540 **
5541 ** May you do good and not evil.
5542 ** May you find forgiveness for yourself and forgive others.
5543 ** May you share freely, never taking more than you give.
5544 **
5545 *************************************************************************
5546 **
5547 ** This file implements an eponymous virtual table that returns suggested
5548 ** completions for a partial SQL input.
5549 **
5550 ** Suggested usage:
5551 **
5552 ** SELECT DISTINCT candidate COLLATE nocase
5553 ** FROM completion($prefix,$wholeline)
5554 ** ORDER BY 1;
5555 **
5556 ** The two query parameters are optional. $prefix is the text of the
5557 ** current word being typed and that is to be completed. $wholeline is
5558 ** the complete input line, used for context.
5559 **
5560 ** The raw completion() table might return the same candidate multiple
5561 ** times, for example if the same column name is used to two or more
5562 ** tables. And the candidates are returned in an arbitrary order. Hence,
5563 ** the DISTINCT and ORDER BY are recommended.
5564 **
5565 ** This virtual table operates at the speed of human typing, and so there
5566 ** is no attempt to make it fast. Even a slow implementation will be much
5567 ** faster than any human can type.
5568 **
5569 */
5570 /* #include "sqlite3ext.h" */
5571 SQLITE_EXTENSION_INIT1
5572 #include <assert.h>
5573 #include <string.h>
5574 #include <ctype.h>
5575
5576 #ifndef SQLITE_OMIT_VIRTUALTABLE
5577
5578 /* completion_vtab is a subclass of sqlite3_vtab which will
5579 ** serve as the underlying representation of a completion virtual table
5580 */
5581 typedef struct completion_vtab completion_vtab;
5582 struct completion_vtab {
5583 sqlite3_vtab base; /* Base class - must be first */
5584 sqlite3 *db; /* Database connection for this completion vtab */
5585 };
5586
5587 /* completion_cursor is a subclass of sqlite3_vtab_cursor which will
5588 ** serve as the underlying representation of a cursor that scans
5589 ** over rows of the result
5590 */
5591 typedef struct completion_cursor completion_cursor;
5592 struct completion_cursor {
5593 sqlite3_vtab_cursor base; /* Base class - must be first */
5594 sqlite3 *db; /* Database connection for this cursor */
5595 int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */
5596 char *zPrefix; /* The prefix for the word we want to complete */
5597 char *zLine; /* The whole that we want to complete */
5598 const char *zCurrentRow; /* Current output row */
5599 int szRow; /* Length of the zCurrentRow string */
5600 sqlite3_stmt *pStmt; /* Current statement */
5601 sqlite3_int64 iRowid; /* The rowid */
5602 int ePhase; /* Current phase */
5603 int j; /* inter-phase counter */
5604 };
5605
5606 /* Values for ePhase:
5607 */
5608 #define COMPLETION_FIRST_PHASE 1
5609 #define COMPLETION_KEYWORDS 1
5610 #define COMPLETION_PRAGMAS 2
5611 #define COMPLETION_FUNCTIONS 3
5612 #define COMPLETION_COLLATIONS 4
5613 #define COMPLETION_INDEXES 5
5614 #define COMPLETION_TRIGGERS 6
5615 #define COMPLETION_DATABASES 7
5616 #define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */
5617 #define COMPLETION_COLUMNS 9
5618 #define COMPLETION_MODULES 10
5619 #define COMPLETION_EOF 11
5620
5621 /*
5622 ** The completionConnect() method is invoked to create a new
5623 ** completion_vtab that describes the completion virtual table.
5624 **
5625 ** Think of this routine as the constructor for completion_vtab objects.
5626 **
5627 ** All this routine needs to do is:
5628 **
5629 ** (1) Allocate the completion_vtab object and initialize all fields.
5630 **
5631 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
5632 ** result set of queries against completion will look like.
5633 */
5634 static int completionConnect(
5635 sqlite3 *db,
5636 void *pAux,
5637 int argc, const char *const*argv,
5638 sqlite3_vtab **ppVtab,
5639 char **pzErr
5640 ){
5641 completion_vtab *pNew;
5642 int rc;
5643
5644 (void)(pAux); /* Unused parameter */
5645 (void)(argc); /* Unused parameter */
5646 (void)(argv); /* Unused parameter */
5647 (void)(pzErr); /* Unused parameter */
5648
5649 /* Column numbers */
5650 #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
5651 #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
5652 #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
5653 #define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
5654
5655 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
5656 rc = sqlite3_declare_vtab(db,
5657 "CREATE TABLE x("
5658 " candidate TEXT,"
5659 " prefix TEXT HIDDEN,"
5660 " wholeline TEXT HIDDEN,"
5661 " phase INT HIDDEN" /* Used for debugging only */
5662 ")");
5663 if( rc==SQLITE_OK ){
5664 pNew = sqlite3_malloc( sizeof(*pNew) );
5665 *ppVtab = (sqlite3_vtab*)pNew;
5666 if( pNew==0 ) return SQLITE_NOMEM;
5667 memset(pNew, 0, sizeof(*pNew));
5668 pNew->db = db;
5669 }
5670 return rc;
5671 }
5672
5673 /*
5674 ** This method is the destructor for completion_cursor objects.
5675 */
5676 static int completionDisconnect(sqlite3_vtab *pVtab){
5677 sqlite3_free(pVtab);
5678 return SQLITE_OK;
5679 }
5680
5681 /*
5682 ** Constructor for a new completion_cursor object.
5683 */
5684 static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
5685 completion_cursor *pCur;
5686 pCur = sqlite3_malloc( sizeof(*pCur) );
5687 if( pCur==0 ) return SQLITE_NOMEM;
5688 memset(pCur, 0, sizeof(*pCur));
5689 pCur->db = ((completion_vtab*)p)->db;
5690 *ppCursor = &pCur->base;
5691 return SQLITE_OK;
5692 }
5693
5694 /*
5695 ** Reset the completion_cursor.
5696 */
5697 static void completionCursorReset(completion_cursor *pCur){
5698 sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0;
5699 sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0;
5700 sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
5701 pCur->j = 0;
5702 }
5703
5704 /*
5705 ** Destructor for a completion_cursor.
5706 */
5707 static int completionClose(sqlite3_vtab_cursor *cur){
5708 completionCursorReset((completion_cursor*)cur);
5709 sqlite3_free(cur);
5710 return SQLITE_OK;
5711 }
5712
5713 /*
5714 ** Advance a completion_cursor to its next row of output.
5715 **
5716 ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
5717 ** record the current state of the scan. This routine sets ->zCurrentRow
5718 ** to the current row of output and then returns. If no more rows remain,
5719 ** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
5720 ** table that has reached the end of its scan.
5721 **
5722 ** The current implementation just lists potential identifiers and
5723 ** keywords and filters them by zPrefix. Future enhancements should
5724 ** take zLine into account to try to restrict the set of identifiers and
5725 ** keywords based on what would be legal at the current point of input.
5726 */
5727 static int completionNext(sqlite3_vtab_cursor *cur){
5728 completion_cursor *pCur = (completion_cursor*)cur;
5729 int eNextPhase = 0; /* Next phase to try if current phase reaches end */
5730 int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
5731 pCur->iRowid++;
5732 while( pCur->ePhase!=COMPLETION_EOF ){
5733 switch( pCur->ePhase ){
5734 case COMPLETION_KEYWORDS: {
5735 if( pCur->j >= sqlite3_keyword_count() ){
5736 pCur->zCurrentRow = 0;
5737 pCur->ePhase = COMPLETION_DATABASES;
5738 }else{
5739 sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
5740 }
5741 iCol = -1;
5742 break;
5743 }
5744 case COMPLETION_DATABASES: {
5745 if( pCur->pStmt==0 ){
5746 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
5747 &pCur->pStmt, 0);
5748 }
5749 iCol = 1;
5750 eNextPhase = COMPLETION_TABLES;
5751 break;
5752 }
5753 case COMPLETION_TABLES: {
5754 if( pCur->pStmt==0 ){
5755 sqlite3_stmt *pS2;
5756 char *zSql = 0;
5757 const char *zSep = "";
5758 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
5759 while( sqlite3_step(pS2)==SQLITE_ROW ){
5760 const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
5761 zSql = sqlite3_mprintf(
5762 "%z%s"
5763 "SELECT name FROM \"%w\".sqlite_schema",
5764 zSql, zSep, zDb
5765 );
5766 if( zSql==0 ) return SQLITE_NOMEM;
5767 zSep = " UNION ";
5768 }
5769 sqlite3_finalize(pS2);
5770 sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
5771 sqlite3_free(zSql);
5772 }
5773 iCol = 0;
5774 eNextPhase = COMPLETION_COLUMNS;
5775 break;
5776 }
5777 case COMPLETION_COLUMNS: {
5778 if( pCur->pStmt==0 ){
5779 sqlite3_stmt *pS2;
5780 char *zSql = 0;
5781 const char *zSep = "";
5782 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
5783 while( sqlite3_step(pS2)==SQLITE_ROW ){
5784 const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
5785 zSql = sqlite3_mprintf(
5786 "%z%s"
5787 "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
5788 " JOIN pragma_table_info(sm.name,%Q) AS pti"
5789 " WHERE sm.type='table'",
5790 zSql, zSep, zDb, zDb
5791 );
5792 if( zSql==0 ) return SQLITE_NOMEM;
5793 zSep = " UNION ";
5794 }
5795 sqlite3_finalize(pS2);
5796 sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
5797 sqlite3_free(zSql);
5798 }
5799 iCol = 0;
5800 eNextPhase = COMPLETION_EOF;
5801 break;
5802 }
5803 }
5804 if( iCol<0 ){
5805 /* This case is when the phase presets zCurrentRow */
5806 if( pCur->zCurrentRow==0 ) continue;
5807 }else{
5808 if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
5809 /* Extract the next row of content */
5810 pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
5811 pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
5812 }else{
5813 /* When all rows are finished, advance to the next phase */
5814 sqlite3_finalize(pCur->pStmt);
5815 pCur->pStmt = 0;
5816 pCur->ePhase = eNextPhase;
5817 continue;
5818 }
5819 }
5820 if( pCur->nPrefix==0 ) break;
5821 if( pCur->nPrefix<=pCur->szRow
5822 && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
5823 ){
5824 break;
5825 }
5826 }
5827
5828 return SQLITE_OK;
5829 }
5830
5831 /*
5832 ** Return values of columns for the row at which the completion_cursor
5833 ** is currently pointing.
5834 */
5835 static int completionColumn(
5836 sqlite3_vtab_cursor *cur, /* The cursor */
5837 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
5838 int i /* Which column to return */
5839 ){
5840 completion_cursor *pCur = (completion_cursor*)cur;
5841 switch( i ){
5842 case COMPLETION_COLUMN_CANDIDATE: {
5843 sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
5844 break;
5845 }
5846 case COMPLETION_COLUMN_PREFIX: {
5847 sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
5848 break;
5849 }
5850 case COMPLETION_COLUMN_WHOLELINE: {
5851 sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
5852 break;
5853 }
5854 case COMPLETION_COLUMN_PHASE: {
5855 sqlite3_result_int(ctx, pCur->ePhase);
5856 break;
5857 }
5858 }
5859 return SQLITE_OK;
5860 }
5861
5862 /*
5863 ** Return the rowid for the current row. In this implementation, the
5864 ** rowid is the same as the output value.
5865 */
5866 static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
5867 completion_cursor *pCur = (completion_cursor*)cur;
5868 *pRowid = pCur->iRowid;
5869 return SQLITE_OK;
5870 }
5871
5872 /*
5873 ** Return TRUE if the cursor has been moved off of the last
5874 ** row of output.
5875 */
5876 static int completionEof(sqlite3_vtab_cursor *cur){
5877 completion_cursor *pCur = (completion_cursor*)cur;
5878 return pCur->ePhase >= COMPLETION_EOF;
5879 }
5880
5881 /*
5882 ** This method is called to "rewind" the completion_cursor object back
5883 ** to the first row of output. This method is always called at least
5884 ** once prior to any call to completionColumn() or completionRowid() or
5885 ** completionEof().
5886 */
5887 static int completionFilter(
5888 sqlite3_vtab_cursor *pVtabCursor,
5889 int idxNum, const char *idxStr,
5890 int argc, sqlite3_value **argv
5891 ){
5892 completion_cursor *pCur = (completion_cursor *)pVtabCursor;
5893 int iArg = 0;
5894 (void)(idxStr); /* Unused parameter */
5895 (void)(argc); /* Unused parameter */
5896 completionCursorReset(pCur);
5897 if( idxNum & 1 ){
5898 pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
5899 if( pCur->nPrefix>0 ){
5900 pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
5901 if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
5902 }
5903 iArg = 1;
5904 }
5905 if( idxNum & 2 ){
5906 pCur->nLine = sqlite3_value_bytes(argv[iArg]);
5907 if( pCur->nLine>0 ){
5908 pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
5909 if( pCur->zLine==0 ) return SQLITE_NOMEM;
5910 }
5911 }
5912 if( pCur->zLine!=0 && pCur->zPrefix==0 ){
5913 int i = pCur->nLine;
5914 while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
5915 i--;
5916 }
5917 pCur->nPrefix = pCur->nLine - i;
5918 if( pCur->nPrefix>0 ){
5919 pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
5920 if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
5921 }
5922 }
5923 pCur->iRowid = 0;
5924 pCur->ePhase = COMPLETION_FIRST_PHASE;
5925 return completionNext(pVtabCursor);
5926 }
5927
5928 /*
5929 ** SQLite will invoke this method one or more times while planning a query
5930 ** that uses the completion virtual table. This routine needs to create
5931 ** a query plan for each invocation and compute an estimated cost for that
5932 ** plan.
5933 **
5934 ** There are two hidden parameters that act as arguments to the table-valued
5935 ** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix"
5936 ** is available and bit 1 is set if "wholeline" is available.
5937 */
5938 static int completionBestIndex(
5939 sqlite3_vtab *tab,
5940 sqlite3_index_info *pIdxInfo
5941 ){
5942 int i; /* Loop over constraints */
5943 int idxNum = 0; /* The query plan bitmask */
5944 int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */
5945 int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
5946 int nArg = 0; /* Number of arguments that completeFilter() expects */
5947 const struct sqlite3_index_constraint *pConstraint;
5948
5949 (void)(tab); /* Unused parameter */
5950 pConstraint = pIdxInfo->aConstraint;
5951 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
5952 if( pConstraint->usable==0 ) continue;
5953 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
5954 switch( pConstraint->iColumn ){
5955 case COMPLETION_COLUMN_PREFIX:
5956 prefixIdx = i;
5957 idxNum |= 1;
5958 break;
5959 case COMPLETION_COLUMN_WHOLELINE:
5960 wholelineIdx = i;
5961 idxNum |= 2;
5962 break;
5963 }
5964 }
5965 if( prefixIdx>=0 ){
5966 pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
5967 pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
5968 }
5969 if( wholelineIdx>=0 ){
5970 pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
5971 pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
5972 }
5973 pIdxInfo->idxNum = idxNum;
5974 pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
5975 pIdxInfo->estimatedRows = 500 - 100*nArg;
5976 return SQLITE_OK;
5977 }
5978
5979 /*
5980 ** This following structure defines all the methods for the
5981 ** completion virtual table.
5982 */
5983 static sqlite3_module completionModule = {
5984 0, /* iVersion */
5985 0, /* xCreate */
5986 completionConnect, /* xConnect */
5987 completionBestIndex, /* xBestIndex */
5988 completionDisconnect, /* xDisconnect */
5989 0, /* xDestroy */
5990 completionOpen, /* xOpen - open a cursor */
5991 completionClose, /* xClose - close a cursor */
5992 completionFilter, /* xFilter - configure scan constraints */
5993 completionNext, /* xNext - advance a cursor */
5994 completionEof, /* xEof - check for end of scan */
5995 completionColumn, /* xColumn - read data */
5996 completionRowid, /* xRowid - read data */
5997 0, /* xUpdate */
5998 0, /* xBegin */
5999 0, /* xSync */
6000 0, /* xCommit */
6001 0, /* xRollback */
6002 0, /* xFindMethod */
6003 0, /* xRename */
6004 0, /* xSavepoint */
6005 0, /* xRelease */
6006 0, /* xRollbackTo */
6007 0 /* xShadowName */
6008 };
6009
6010 #endif /* SQLITE_OMIT_VIRTUALTABLE */
6011
6012 int sqlite3CompletionVtabInit(sqlite3 *db){
6013 int rc = SQLITE_OK;
6014 #ifndef SQLITE_OMIT_VIRTUALTABLE
6015 rc = sqlite3_create_module(db, "completion", &completionModule, 0);
6016 #endif
6017 return rc;
6018 }
6019
6020 #ifdef _WIN32
6021
6022 #endif
6023 int sqlite3_completion_init(
6024 sqlite3 *db,
6025 char **pzErrMsg,
6026 const sqlite3_api_routines *pApi
6027 ){
6028 int rc = SQLITE_OK;
6029 SQLITE_EXTENSION_INIT2(pApi);
6030 (void)(pzErrMsg); /* Unused parameter */
6031 #ifndef SQLITE_OMIT_VIRTUALTABLE
6032 rc = sqlite3CompletionVtabInit(db);
6033 #endif
6034 return rc;
6035 }
6036
6037 /************************* End ../ext/misc/completion.c ********************/
6038 /************************* Begin ../ext/misc/appendvfs.c ******************/
6039 /*
6040 ** 2017-10-20
6041 **
6042 ** The author disclaims copyright to this source code. In place of
6043 ** a legal notice, here is a blessing:
6044 **
6045 ** May you do good and not evil.
6046 ** May you find forgiveness for yourself and forgive others.
6047 ** May you share freely, never taking more than you give.
6048 **
6049 ******************************************************************************
6050 **
6051 ** This file implements a VFS shim that allows an SQLite database to be
6052 ** appended onto the end of some other file, such as an executable.
6053 **
6054 ** A special record must appear at the end of the file that identifies the
6055 ** file as an appended database and provides the offset to the first page
6056 ** of the exposed content. (Or, it is the length of the content prefix.)
6057 ** For best performance page 1 should be located at a disk page boundary,
6058 ** though that is not required.
6059 **
6060 ** When opening a database using this VFS, the connection might treat
6061 ** the file as an ordinary SQLite database, or it might treat it as a
6062 ** database appended onto some other file. The decision is made by
6063 ** applying the following rules in order:
6064 **
6065 ** (1) An empty file is an ordinary database.
6066 **
6067 ** (2) If the file ends with the appendvfs trailer string
6068 ** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
6069 **
6070 ** (3) If the file begins with the standard SQLite prefix string
6071 ** "SQLite format 3", that file is an ordinary database.
6072 **
6073 ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
6074 ** set, then a new database is appended to the already existing file.
6075 **
6076 ** (5) Otherwise, SQLITE_CANTOPEN is returned.
6077 **
6078 ** To avoid unnecessary complications with the PENDING_BYTE, the size of
6079 ** the file containing the database is limited to 1GiB. (1073741824 bytes)
6080 ** This VFS will not read or write past the 1GiB mark. This restriction
6081 ** might be lifted in future versions. For now, if you need a larger
6082 ** database, then keep it in a separate file.
6083 **
6084 ** If the file being opened is a plain database (not an appended one), then
6085 ** this shim is a pass-through into the default underlying VFS. (rule 3)
6086 **/
6087 /* #include "sqlite3ext.h" */
6088 SQLITE_EXTENSION_INIT1
6089 #include <string.h>
6090 #include <assert.h>
6091
6092 /* The append mark at the end of the database is:
6093 **
6094 ** Start-Of-SQLite3-NNNNNNNN
6095 ** 123456789 123456789 12345
6096 **
6097 ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
6098 ** the offset to page 1, and also the length of the prefix content.
6099 */
6100 #define APND_MARK_PREFIX "Start-Of-SQLite3-"
6101 #define APND_MARK_PREFIX_SZ 17
6102 #define APND_MARK_FOS_SZ 8
6103 #define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
6104
6105 /*
6106 ** Maximum size of the combined prefix + database + append-mark. This
6107 ** must be less than 0x40000000 to avoid locking issues on Windows.
6108 */
6109 #define APND_MAX_SIZE (0x40000000)
6110
6111 /*
6112 ** Try to align the database to an even multiple of APND_ROUNDUP bytes.
6113 */
6114 #ifndef APND_ROUNDUP
6115 #define APND_ROUNDUP 4096
6116 #endif
6117 #define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1))
6118 #define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
6119
6120 /*
6121 ** Forward declaration of objects used by this utility
6122 */
6123 typedef struct sqlite3_vfs ApndVfs;
6124 typedef struct ApndFile ApndFile;
6125
6126 /* Access to a lower-level VFS that (might) implement dynamic loading,
6127 ** access to randomness, etc.
6128 */
6129 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
6130 #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
6131
6132 /* An open appendvfs file
6133 **
6134 ** An instance of this structure describes the appended database file.
6135 ** A separate sqlite3_file object is always appended. The appended
6136 ** sqlite3_file object (which can be accessed using ORIGFILE()) describes
6137 ** the entire file, including the prefix, the database, and the
6138 ** append-mark.
6139 **
6140 ** The structure of an AppendVFS database is like this:
6141 **
6142 ** +-------------+---------+----------+-------------+
6143 ** | prefix-file | padding | database | append-mark |
6144 ** +-------------+---------+----------+-------------+
6145 ** ^ ^
6146 ** | |
6147 ** iPgOne iMark
6148 **
6149 **
6150 ** "prefix file" - file onto which the database has been appended.
6151 ** "padding" - zero or more bytes inserted so that "database"
6152 ** starts on an APND_ROUNDUP boundary
6153 ** "database" - The SQLite database file
6154 ** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
6155 ** the offset from the start of prefix-file to the start
6156 ** of "database".
6157 **
6158 ** The size of the database is iMark - iPgOne.
6159 **
6160 ** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
6161 ** of iPgOne stored as a big-ending 64-bit integer.
6162 **
6163 ** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
6164 ** Or, iMark is -1 to indicate that it has not yet been written.
6165 */
6166 struct ApndFile {
6167 sqlite3_file base; /* Subclass. MUST BE FIRST! */
6168 sqlite3_int64 iPgOne; /* Offset to the start of the database */
6169 sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */
6170 /* Always followed by another sqlite3_file that describes the whole file */
6171 };
6172
6173 /*
6174 ** Methods for ApndFile
6175 */
6176 static int apndClose(sqlite3_file*);
6177 static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
6178 static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
6179 static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
6180 static int apndSync(sqlite3_file*, int flags);
6181 static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
6182 static int apndLock(sqlite3_file*, int);
6183 static int apndUnlock(sqlite3_file*, int);
6184 static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
6185 static int apndFileControl(sqlite3_file*, int op, void *pArg);
6186 static int apndSectorSize(sqlite3_file*);
6187 static int apndDeviceCharacteristics(sqlite3_file*);
6188 static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
6189 static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
6190 static void apndShmBarrier(sqlite3_file*);
6191 static int apndShmUnmap(sqlite3_file*, int deleteFlag);
6192 static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
6193 static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
6194
6195 /*
6196 ** Methods for ApndVfs
6197 */
6198 static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
6199 static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
6200 static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
6201 static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
6202 static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
6203 static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
6204 static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
6205 static void apndDlClose(sqlite3_vfs*, void*);
6206 static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
6207 static int apndSleep(sqlite3_vfs*, int microseconds);
6208 static int apndCurrentTime(sqlite3_vfs*, double*);
6209 static int apndGetLastError(sqlite3_vfs*, int, char *);
6210 static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
6211 static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
6212 static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
6213 static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
6214
6215 static sqlite3_vfs apnd_vfs = {
6216 3, /* iVersion (set when registered) */
6217 0, /* szOsFile (set when registered) */
6218 1024, /* mxPathname */
6219 0, /* pNext */
6220 "apndvfs", /* zName */
6221 0, /* pAppData (set when registered) */
6222 apndOpen, /* xOpen */
6223 apndDelete, /* xDelete */
6224 apndAccess, /* xAccess */
6225 apndFullPathname, /* xFullPathname */
6226 apndDlOpen, /* xDlOpen */
6227 apndDlError, /* xDlError */
6228 apndDlSym, /* xDlSym */
6229 apndDlClose, /* xDlClose */
6230 apndRandomness, /* xRandomness */
6231 apndSleep, /* xSleep */
6232 apndCurrentTime, /* xCurrentTime */
6233 apndGetLastError, /* xGetLastError */
6234 apndCurrentTimeInt64, /* xCurrentTimeInt64 */
6235 apndSetSystemCall, /* xSetSystemCall */
6236 apndGetSystemCall, /* xGetSystemCall */
6237 apndNextSystemCall /* xNextSystemCall */
6238 };
6239
6240 static const sqlite3_io_methods apnd_io_methods = {
6241 3, /* iVersion */
6242 apndClose, /* xClose */
6243 apndRead, /* xRead */
6244 apndWrite, /* xWrite */
6245 apndTruncate, /* xTruncate */
6246 apndSync, /* xSync */
6247 apndFileSize, /* xFileSize */
6248 apndLock, /* xLock */
6249 apndUnlock, /* xUnlock */
6250 apndCheckReservedLock, /* xCheckReservedLock */
6251 apndFileControl, /* xFileControl */
6252 apndSectorSize, /* xSectorSize */
6253 apndDeviceCharacteristics, /* xDeviceCharacteristics */
6254 apndShmMap, /* xShmMap */
6255 apndShmLock, /* xShmLock */
6256 apndShmBarrier, /* xShmBarrier */
6257 apndShmUnmap, /* xShmUnmap */
6258 apndFetch, /* xFetch */
6259 apndUnfetch /* xUnfetch */
6260 };
6261
6262 /*
6263 ** Close an apnd-file.
6264 */
6265 static int apndClose(sqlite3_file *pFile){
6266 pFile = ORIGFILE(pFile);
6267 return pFile->pMethods->xClose(pFile);
6268 }
6269
6270 /*
6271 ** Read data from an apnd-file.
6272 */
6273 static int apndRead(
6274 sqlite3_file *pFile,
6275 void *zBuf,
6276 int iAmt,
6277 sqlite_int64 iOfst
6278 ){
6279 ApndFile *paf = (ApndFile *)pFile;
6280 pFile = ORIGFILE(pFile);
6281 return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
6282 }
6283
6284 /*
6285 ** Add the append-mark onto what should become the end of the file.
6286 * If and only if this succeeds, internal ApndFile.iMark is updated.
6287 * Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
6288 */
6289 static int apndWriteMark(
6290 ApndFile *paf,
6291 sqlite3_file *pFile,
6292 sqlite_int64 iWriteEnd
6293 ){
6294 sqlite_int64 iPgOne = paf->iPgOne;
6295 unsigned char a[APND_MARK_SIZE];
6296 int i = APND_MARK_FOS_SZ;
6297 int rc;
6298 assert(pFile == ORIGFILE(paf));
6299 memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
6300 while( --i >= 0 ){
6301 a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
6302 iPgOne >>= 8;
6303 }
6304 iWriteEnd += paf->iPgOne;
6305 if( SQLITE_OK==(rc = pFile->pMethods->xWrite
6306 (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
6307 paf->iMark = iWriteEnd;
6308 }
6309 return rc;
6310 }
6311
6312 /*
6313 ** Write data to an apnd-file.
6314 */
6315 static int apndWrite(
6316 sqlite3_file *pFile,
6317 const void *zBuf,
6318 int iAmt,
6319 sqlite_int64 iOfst
6320 ){
6321 ApndFile *paf = (ApndFile *)pFile;
6322 sqlite_int64 iWriteEnd = iOfst + iAmt;
6323 if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
6324 pFile = ORIGFILE(pFile);
6325 /* If append-mark is absent or will be overwritten, write it. */
6326 if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
6327 int rc = apndWriteMark(paf, pFile, iWriteEnd);
6328 if( SQLITE_OK!=rc ) return rc;
6329 }
6330 return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
6331 }
6332
6333 /*
6334 ** Truncate an apnd-file.
6335 */
6336 static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
6337 ApndFile *paf = (ApndFile *)pFile;
6338 pFile = ORIGFILE(pFile);
6339 /* The append mark goes out first so truncate failure does not lose it. */
6340 if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
6341 /* Truncate underlying file just past append mark */
6342 return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
6343 }
6344
6345 /*
6346 ** Sync an apnd-file.
6347 */
6348 static int apndSync(sqlite3_file *pFile, int flags){
6349 pFile = ORIGFILE(pFile);
6350 return pFile->pMethods->xSync(pFile, flags);
6351 }
6352
6353 /*
6354 ** Return the current file-size of an apnd-file.
6355 ** If the append mark is not yet there, the file-size is 0.
6356 */
6357 static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
6358 ApndFile *paf = (ApndFile *)pFile;
6359 *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
6360 return SQLITE_OK;
6361 }
6362
6363 /*
6364 ** Lock an apnd-file.
6365 */
6366 static int apndLock(sqlite3_file *pFile, int eLock){
6367 pFile = ORIGFILE(pFile);
6368 return pFile->pMethods->xLock(pFile, eLock);
6369 }
6370
6371 /*
6372 ** Unlock an apnd-file.
6373 */
6374 static int apndUnlock(sqlite3_file *pFile, int eLock){
6375 pFile = ORIGFILE(pFile);
6376 return pFile->pMethods->xUnlock(pFile, eLock);
6377 }
6378
6379 /*
6380 ** Check if another file-handle holds a RESERVED lock on an apnd-file.
6381 */
6382 static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
6383 pFile = ORIGFILE(pFile);
6384 return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
6385 }
6386
6387 /*
6388 ** File control method. For custom operations on an apnd-file.
6389 */
6390 static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
6391 ApndFile *paf = (ApndFile *)pFile;
6392 int rc;
6393 pFile = ORIGFILE(pFile);
6394 if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
6395 rc = pFile->pMethods->xFileControl(pFile, op, pArg);
6396 if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
6397 *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
6398 }
6399 return rc;
6400 }
6401
6402 /*
6403 ** Return the sector-size in bytes for an apnd-file.
6404 */
6405 static int apndSectorSize(sqlite3_file *pFile){
6406 pFile = ORIGFILE(pFile);
6407 return pFile->pMethods->xSectorSize(pFile);
6408 }
6409
6410 /*
6411 ** Return the device characteristic flags supported by an apnd-file.
6412 */
6413 static int apndDeviceCharacteristics(sqlite3_file *pFile){
6414 pFile = ORIGFILE(pFile);
6415 return pFile->pMethods->xDeviceCharacteristics(pFile);
6416 }
6417
6418 /* Create a shared memory file mapping */
6419 static int apndShmMap(
6420 sqlite3_file *pFile,
6421 int iPg,
6422 int pgsz,
6423 int bExtend,
6424 void volatile **pp
6425 ){
6426 pFile = ORIGFILE(pFile);
6427 return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
6428 }
6429
6430 /* Perform locking on a shared-memory segment */
6431 static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
6432 pFile = ORIGFILE(pFile);
6433 return pFile->pMethods->xShmLock(pFile,offset,n,flags);
6434 }
6435
6436 /* Memory barrier operation on shared memory */
6437 static void apndShmBarrier(sqlite3_file *pFile){
6438 pFile = ORIGFILE(pFile);
6439 pFile->pMethods->xShmBarrier(pFile);
6440 }
6441
6442 /* Unmap a shared memory segment */
6443 static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
6444 pFile = ORIGFILE(pFile);
6445 return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
6446 }
6447
6448 /* Fetch a page of a memory-mapped file */
6449 static int apndFetch(
6450 sqlite3_file *pFile,
6451 sqlite3_int64 iOfst,
6452 int iAmt,
6453 void **pp
6454 ){
6455 ApndFile *p = (ApndFile *)pFile;
6456 if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
6457 return SQLITE_IOERR; /* Cannot read what is not yet there. */
6458 }
6459 pFile = ORIGFILE(pFile);
6460 return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
6461 }
6462
6463 /* Release a memory-mapped page */
6464 static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
6465 ApndFile *p = (ApndFile *)pFile;
6466 pFile = ORIGFILE(pFile);
6467 return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
6468 }
6469
6470 /*
6471 ** Try to read the append-mark off the end of a file. Return the
6472 ** start of the appended database if the append-mark is present.
6473 ** If there is no valid append-mark, return -1;
6474 **
6475 ** An append-mark is only valid if the NNNNNNNN start-of-database offset
6476 ** indicates that the appended database contains at least one page. The
6477 ** start-of-database value must be a multiple of 512.
6478 */
6479 static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
6480 int rc, i;
6481 sqlite3_int64 iMark;
6482 int msbs = 8 * (APND_MARK_FOS_SZ-1);
6483 unsigned char a[APND_MARK_SIZE];
6484
6485 if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
6486 rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
6487 if( rc ) return -1;
6488 if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
6489 iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
6490 for(i=1; i<8; i++){
6491 msbs -= 8;
6492 iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
6493 }
6494 if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
6495 if( iMark & 0x1ff ) return -1;
6496 return iMark;
6497 }
6498
6499 static const char apvfsSqliteHdr[] = "SQLite format 3";
6500 /*
6501 ** Check to see if the file is an appendvfs SQLite database file.
6502 ** Return true iff it is such. Parameter sz is the file's size.
6503 */
6504 static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
6505 int rc;
6506 char zHdr[16];
6507 sqlite3_int64 iMark = apndReadMark(sz, pFile);
6508 if( iMark>=0 ){
6509 /* If file has the correct end-marker, the expected odd size, and the
6510 ** SQLite DB type marker where the end-marker puts it, then it
6511 ** is an appendvfs database.
6512 */
6513 rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
6514 if( SQLITE_OK==rc
6515 && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
6516 && (sz & 0x1ff) == APND_MARK_SIZE
6517 && sz>=512+APND_MARK_SIZE
6518 ){
6519 return 1; /* It's an appendvfs database */
6520 }
6521 }
6522 return 0;
6523 }
6524
6525 /*
6526 ** Check to see if the file is an ordinary SQLite database file.
6527 ** Return true iff so. Parameter sz is the file's size.
6528 */
6529 static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
6530 char zHdr[16];
6531 if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
6532 || (sz & 0x1ff) != 0
6533 || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
6534 || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
6535 ){
6536 return 0;
6537 }else{
6538 return 1;
6539 }
6540 }
6541
6542 /*
6543 ** Open an apnd file handle.
6544 */
6545 static int apndOpen(
6546 sqlite3_vfs *pApndVfs,
6547 const char *zName,
6548 sqlite3_file *pFile,
6549 int flags,
6550 int *pOutFlags
6551 ){
6552 ApndFile *pApndFile = (ApndFile*)pFile;
6553 sqlite3_file *pBaseFile = ORIGFILE(pFile);
6554 sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
6555 int rc;
6556 sqlite3_int64 sz = 0;
6557 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
6558 /* The appendvfs is not to be used for transient or temporary databases.
6559 ** Just use the base VFS open to initialize the given file object and
6560 ** open the underlying file. (Appendvfs is then unused for this file.)
6561 */
6562 return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
6563 }
6564 memset(pApndFile, 0, sizeof(ApndFile));
6565 pFile->pMethods = &apnd_io_methods;
6566 pApndFile->iMark = -1; /* Append mark not yet written */
6567
6568 rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
6569 if( rc==SQLITE_OK ){
6570 rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
6571 if( rc ){
6572 pBaseFile->pMethods->xClose(pBaseFile);
6573 }
6574 }
6575 if( rc ){
6576 pFile->pMethods = 0;
6577 return rc;
6578 }
6579 if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
6580 /* The file being opened appears to be just an ordinary DB. Copy
6581 ** the base dispatch-table so this instance mimics the base VFS.
6582 */
6583 memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
6584 return SQLITE_OK;
6585 }
6586 pApndFile->iPgOne = apndReadMark(sz, pFile);
6587 if( pApndFile->iPgOne>=0 ){
6588 pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
6589 return SQLITE_OK;
6590 }
6591 if( (flags & SQLITE_OPEN_CREATE)==0 ){
6592 pBaseFile->pMethods->xClose(pBaseFile);
6593 rc = SQLITE_CANTOPEN;
6594 pFile->pMethods = 0;
6595 }else{
6596 /* Round newly added appendvfs location to #define'd page boundary.
6597 ** Note that nothing has yet been written to the underlying file.
6598 ** The append mark will be written along with first content write.
6599 ** Until then, paf->iMark value indicates it is not yet written.
6600 */
6601 pApndFile->iPgOne = APND_START_ROUNDUP(sz);
6602 }
6603 return rc;
6604 }
6605
6606 /*
6607 ** Delete an apnd file.
6608 ** For an appendvfs, this could mean delete the appendvfs portion,
6609 ** leaving the appendee as it was before it gained an appendvfs.
6610 ** For now, this code deletes the underlying file too.
6611 */
6612 static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
6613 return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
6614 }
6615
6616 /*
6617 ** All other VFS methods are pass-thrus.
6618 */
6619 static int apndAccess(
6620 sqlite3_vfs *pVfs,
6621 const char *zPath,
6622 int flags,
6623 int *pResOut
6624 ){
6625 return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
6626 }
6627 static int apndFullPathname(
6628 sqlite3_vfs *pVfs,
6629 const char *zPath,
6630 int nOut,
6631 char *zOut
6632 ){
6633 return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
6634 }
6635 static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
6636 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
6637 }
6638 static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
6639 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
6640 }
6641 static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
6642 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
6643 }
6644 static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
6645 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
6646 }
6647 static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
6648 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
6649 }
6650 static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
6651 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
6652 }
6653 static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
6654 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
6655 }
6656 static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
6657 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
6658 }
6659 static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
6660 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
6661 }
6662 static int apndSetSystemCall(
6663 sqlite3_vfs *pVfs,
6664 const char *zName,
6665 sqlite3_syscall_ptr pCall
6666 ){
6667 return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
6668 }
6669 static sqlite3_syscall_ptr apndGetSystemCall(
6670 sqlite3_vfs *pVfs,
6671 const char *zName
6672 ){
6673 return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
6674 }
6675 static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
6676 return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
6677 }
6678
6679
6680 #ifdef _WIN32
6681
6682 #endif
6683 /*
6684 ** This routine is called when the extension is loaded.
6685 ** Register the new VFS.
6686 */
6687 int sqlite3_appendvfs_init(
6688 sqlite3 *db,
6689 char **pzErrMsg,
6690 const sqlite3_api_routines *pApi
6691 ){
6692 int rc = SQLITE_OK;
6693 sqlite3_vfs *pOrig;
6694 SQLITE_EXTENSION_INIT2(pApi);
6695 (void)pzErrMsg;
6696 (void)db;
6697 pOrig = sqlite3_vfs_find(0);
6698 if( pOrig==0 ) return SQLITE_ERROR;
6699 apnd_vfs.iVersion = pOrig->iVersion;
6700 apnd_vfs.pAppData = pOrig;
6701 apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
6702 rc = sqlite3_vfs_register(&apnd_vfs, 0);
6703 #ifdef APPENDVFS_TEST
6704 if( rc==SQLITE_OK ){
6705 rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
6706 }
6707 #endif
6708 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
6709 return rc;
6710 }
6711
6712 /************************* End ../ext/misc/appendvfs.c ********************/
6713 #endif
6714 #ifdef SQLITE_HAVE_ZLIB
6715 /************************* Begin ../ext/misc/zipfile.c ******************/
6716 /*
6717 ** 2017-12-26
6718 **
@@ -12235,11 +12248,21 @@
12248 int nIndent; /* Size of array aiIndent[] */
12249 int iIndent; /* Index of current op in aiIndent[] */
12250 char *zNonce; /* Nonce for temporary safe-mode excapes */
12251 EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
12252 ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
12253 #ifdef SQLITE_SHELL_WASM_MODE
12254 struct {
12255 const char * zInput; /* Input string from wasm/JS proxy */
12256 const char * zPos; /* Cursor pos into zInput */
12257 } wasm;
12258 #endif
12259 };
12260
12261 #ifdef SQLITE_SHELL_WASM_MODE
12262 static ShellState shellState;
12263 #endif
12264
12265
12266 /* Allowed values for ShellState.autoEQP
12267 */
12268 #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
@@ -12277,11 +12300,11 @@
12300 #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
12301 #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
12302 #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
12303 #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
12304 #define SHFLG_CountChanges 0x00000020 /* .changes setting */
12305 #define SHFLG_Echo 0x00000040 /* .echo on/off, or --echo setting */
12306 #define SHFLG_HeaderSet 0x00000080 /* showHeader has been specified */
12307 #define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
12308 #define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
12309
12310 /*
@@ -12901,11 +12924,15 @@
12924 UNUSED_PARAMETER(zA2);
12925 UNUSED_PARAMETER(zA3);
12926 UNUSED_PARAMETER(zA4);
12927 switch( op ){
12928 case SQLITE_ATTACH: {
12929 #ifndef SQLITE_SHELL_WASM_MODE
12930 /* In WASM builds the filesystem is a virtual sandbox, so
12931 ** there's no harm in using ATTACH. */
12932 failIfSafeMode(p, "cannot run ATTACH in safe mode");
12933 #endif
12934 break;
12935 }
12936 case SQLITE_FUNCTION: {
12937 int i;
12938 for(i=0; i<ArraySize(azProhibitedFunctions); i++){
@@ -14906,15 +14933,10 @@
14933 if( pArg ){
14934 pArg->pStmt = pStmt;
14935 pArg->cnt = 0;
14936 }
14937
 
 
 
 
 
14938 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
14939 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
14940 sqlite3_stmt *pExplain;
14941 char *zEQP;
14942 int triggerEQP = 0;
@@ -15309,17 +15331,18 @@
15331
15332 /*
15333 ** Text of help messages.
15334 **
15335 ** The help text for each individual command begins with a line that starts
15336 ** with ".". Subsequent lines are supplemental information.
15337 **
15338 ** There must be two or more spaces between the end of the command and the
15339 ** start of the description of what that command does.
15340 */
15341 static const char *(azHelp[]) = {
15342 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) \
15343 && !defined(SQLITE_SHELL_WASM_MODE)
15344 ".archive ... Manage SQL archives",
15345 " Each command must have exactly one of the following options:",
15346 " -c, --create Create a new archive",
15347 " -u, --update Add or update files with changed mtime",
15348 " -i, --insert Like -u but always add even if unchanged",
@@ -15341,24 +15364,32 @@
15364 " http://sqlite.org/cli.html#sqlite_archive_support",
15365 #endif
15366 #ifndef SQLITE_OMIT_AUTHORIZATION
15367 ".auth ON|OFF Show authorizer callbacks",
15368 #endif
15369 #ifndef SQLITE_SHELL_WASM_MODE
15370 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
15371 " Options:",
15372 " --append Use the appendvfs",
15373 " --async Write to FILE without journal and fsync()",
15374 #endif
15375 ".bail on|off Stop after hitting an error. Default OFF",
15376 ".binary on|off Turn binary output on or off. Default OFF",
15377 #ifndef SQLITE_SHELL_WASM_MODE
15378 ".cd DIRECTORY Change the working directory to DIRECTORY",
15379 #endif
15380 ".changes on|off Show number of rows changed by SQL",
15381 #ifndef SQLITE_SHELL_WASM_MODE
15382 ".check GLOB Fail if output since .testcase does not match",
15383 ".clone NEWDB Clone data into NEWDB from the existing database",
15384 #endif
15385 ".connection [close] [#] Open or close an auxiliary database connection",
15386 ".databases List names and files of attached databases",
15387 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
15388 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
15389 ".dbinfo ?DB? Show status information about the database",
15390 #endif
15391 ".dump ?OBJECTS? Render database content as SQL",
15392 " Options:",
15393 " --data-only Output only INSERT statements",
15394 " --newlines Allow unescaped newline characters in output",
15395 " --nosys Omit system tables (ex: \"sqlite_stat1\")",
@@ -15371,21 +15402,26 @@
15402 #ifdef SQLITE_DEBUG
15403 " test Show raw EXPLAIN QUERY PLAN output",
15404 " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
15405 #endif
15406 " trigger Like \"full\" but also show trigger bytecode",
15407 #ifndef SQLITE_SHELL_WASM_MODE
15408 ".excel Display the output of next command in spreadsheet",
15409 " --bom Put a UTF8 byte-order mark on intermediate file",
15410 #endif
15411 #ifndef SQLITE_SHELL_WASM_MODE
15412 ".exit ?CODE? Exit this program with return-code CODE",
15413 #endif
15414 ".expert EXPERIMENTAL. Suggest indexes for queries",
15415 ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
15416 ".filectrl CMD ... Run various sqlite3_file_control() operations",
15417 " --schema SCHEMA Use SCHEMA instead of \"main\"",
15418 " --help Show CMD details",
15419 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
15420 ".headers on|off Turn display of headers on or off",
15421 ".help ?-all? ?PATTERN? Show help text for PATTERN",
15422 #ifndef SQLITE_SHELL_WASM_MODE
15423 ".import FILE TABLE Import data from FILE into TABLE",
15424 " Options:",
15425 " --ascii Use \\037 and \\036 as column and row separators",
15426 " --csv Use , and \\n as column and row separators",
15427 " --skip N Skip the first N rows of input",
@@ -15396,10 +15432,11 @@
15432 " determines the column names.",
15433 " * If neither --csv or --ascii are used, the input mode is derived",
15434 " from the \".mode\" output mode",
15435 " * If FILE begins with \"|\" then it is a command that generates the",
15436 " input text.",
15437 #endif
15438 #ifndef SQLITE_OMIT_TEST_CONTROL
15439 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
15440 #endif
15441 ".indexes ?TABLE? Show names of indexes",
15442 " If TABLE is specified, only show indexes for",
@@ -15409,14 +15446,16 @@
15446 #endif
15447 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
15448 ".lint OPTIONS Report potential schema issues.",
15449 " Options:",
15450 " fkey-indexes Find missing foreign key indexes",
15451 #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_WASM_MODE)
15452 ".load FILE ?ENTRY? Load an extension library",
15453 #endif
15454 #ifndef SQLITE_SHELL_WASM_MODE
15455 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15456 #endif
15457 ".mode MODE ?OPTIONS? Set output mode",
15458 " MODE is one of:",
15459 " ascii Columns/rows delimited by 0x1F and 0x1E",
15460 " box Tables using unicode box-drawing characters",
15461 " csv Comma-separated values",
@@ -15437,35 +15476,44 @@
15476 " --wordwrap B Wrap or not at word boundaries per B (on/off)",
15477 " --ww Shorthand for \"--wordwrap 1\"",
15478 " --quote Quote output text as SQL literals",
15479 " --noquote Do not quote output text",
15480 " TABLE The name of SQL table used for \"insert\" mode",
15481 #ifndef SQLITE_SHELL_WASM_MODE
15482 ".nonce STRING Suspend safe mode for one command if nonce matches",
15483 #endif
15484 ".nullvalue STRING Use STRING in place of NULL values",
15485 #ifndef SQLITE_SHELL_WASM_MODE
15486 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
15487 " If FILE begins with '|' then open as a pipe",
15488 " --bom Put a UTF8 byte-order mark at the beginning",
15489 " -e Send output to the system text editor",
15490 " -x Send output as CSV to a spreadsheet (same as \".excel\")",
15491 /* Note that .open is (partially) available in WASM builds but is
15492 ** currently only intended to be used by the fiddle tool, not
15493 ** end users, so is "undocumented." */
15494 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
15495 " Options:",
15496 " --append Use appendvfs to append database to the end of FILE",
15497 #endif
15498 #ifndef SQLITE_OMIT_DESERIALIZE
15499 " --deserialize Load into memory using sqlite3_deserialize()",
15500 " --hexdb Load the output of \"dbtotxt\" as an in-memory db",
15501 " --maxsize N Maximum size for --hexdb or --deserialized database",
15502 #endif
15503 " --new Initialize FILE to an empty database",
15504 " --nofollow Do not follow symbolic links",
15505 " --readonly Open FILE readonly",
15506 " --zip FILE is a ZIP archive",
15507 #ifndef SQLITE_SHELL_WASM_MODE
15508 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
15509 " If FILE begins with '|' then open it as a pipe.",
15510 " Options:",
15511 " --bom Prefix output with a UTF8 byte-order mark",
15512 " -e Send output to the system text editor",
15513 " -x Send output as CSV to a spreadsheet",
15514 #endif
15515 ".parameter CMD ... Manage SQL parameter bindings",
15516 " clear Erase all bindings",
15517 " init Initialize the TEMP table that holds bindings",
15518 " list List the current parameter bindings",
15519 " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
@@ -15478,23 +15526,27 @@
15526 " --once Do no more than one progress interrupt",
15527 " --quiet|-q No output except at interrupts",
15528 " --reset Reset the count for each input and interrupt",
15529 #endif
15530 ".prompt MAIN CONTINUE Replace the standard prompts",
15531 #ifndef SQLITE_SHELL_WASM_MODE
15532 ".quit Exit this program",
15533 ".read FILE Read input from FILE or command output",
15534 " If FILE begins with \"|\", it is a command that generates the input.",
15535 #endif
15536 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
15537 ".recover Recover as much data as possible from corrupt db.",
15538 " --freelist-corrupt Assume the freelist is corrupt",
15539 " --recovery-db NAME Store recovery metadata in database file NAME",
15540 " --lost-and-found TABLE Alternative name for the lost-and-found table",
15541 " --no-rowids Do not attempt to recover rowid values",
15542 " that are not also INTEGER PRIMARY KEYs",
15543 #endif
15544 #ifndef SQLITE_SHELL_WASM_MODE
15545 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15546 ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
15547 #endif
15548 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
15549 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
15550 " Options:",
15551 " --indent Try to pretty-print the schema",
15552 " --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15524,24 +15576,26 @@
15576 " --sha3-224 Use the sha3-224 algorithm",
15577 " --sha3-256 Use the sha3-256 algorithm (default)",
15578 " --sha3-384 Use the sha3-384 algorithm",
15579 " --sha3-512 Use the sha3-512 algorithm",
15580 " Any other argument is a LIKE pattern for tables to hash",
15581 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
15582 ".shell CMD ARGS... Run CMD ARGS... in a system shell",
15583 #endif
15584 ".show Show the current values for various settings",
15585 ".stats ?ARG? Show stats or turn stats on or off",
15586 " off Turn off automatic stat display",
15587 " on Turn on automatic stat display",
15588 " stmt Show statement stats",
15589 " vmstep Show the virtual machine step count only",
15590 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
15591 ".system CMD ARGS... Run CMD ARGS... in a system shell",
15592 #endif
15593 ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
15594 #ifndef SQLITE_SHELL_WASM_MODE
15595 ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
15596 #endif
15597 ".testctrl CMD ... Run various sqlite3_test_control() operations",
15598 " Run \".testctrl\" with no arguments for details",
15599 ".timeout MS Try opening locked tables for MS milliseconds",
15600 ".timer on|off Turn SQL timer on or off",
15601 #ifndef SQLITE_OMIT_TRACE
@@ -16082,18 +16136,20 @@
16136 exit(1);
16137 }
16138 #ifndef SQLITE_OMIT_LOAD_EXTENSION
16139 sqlite3_enable_load_extension(p->db, 1);
16140 #endif
 
16141 sqlite3_shathree_init(p->db, 0, 0);
 
16142 sqlite3_uint_init(p->db, 0, 0);
16143 sqlite3_decimal_init(p->db, 0, 0);
16144 sqlite3_regexp_init(p->db, 0, 0);
16145 sqlite3_ieee_init(p->db, 0, 0);
16146 sqlite3_series_init(p->db, 0, 0);
16147 #ifndef SQLITE_SHELL_WASM_MODE
16148 sqlite3_fileio_init(p->db, 0, 0);
16149 sqlite3_completion_init(p->db, 0, 0);
16150 #endif
16151 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
16152 sqlite3_dbdata_init(p->db, 0, 0);
16153 #endif
16154 #ifdef SQLITE_HAVE_ZLIB
16155 if( !p->bSafeModePersist ){
@@ -16867,10 +16923,11 @@
16923 }
16924 sqlite3_finalize(pStmt);
16925 return res;
16926 }
16927
16928 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
16929 /*
16930 ** Convert a 2-byte or 4-byte big-endian integer into a native integer
16931 */
16932 static unsigned int get2byteInt(unsigned char *a){
16933 return (a[0]<<8) + a[1];
@@ -16973,10 +17030,12 @@
17030 sqlite3_free(zSchemaTab);
17031 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
17032 utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
17033 return 0;
17034 }
17035 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE)
17036 && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
17037
17038 /*
17039 ** Print the current sqlite3_errmsg() value to stderr and return 1.
17040 */
17041 static int shellDatabaseError(sqlite3 *db){
@@ -19212,18 +19271,20 @@
19271 sqlite3_set_authorizer(p->db, 0, 0);
19272 }
19273 }else
19274 #endif
19275
19276 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) \
19277 && !defined(SQLITE_SHELL_WASM_MODE)
19278 if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
19279 open_db(p, 0);
19280 failIfSafeMode(p, "cannot run .archive in safe mode");
19281 rc = arDotCommand(p, 0, azArg, nArg);
19282 }else
19283 #endif
19284
19285 #ifndef SQLITE_SHELL_WASM_MODE
19286 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
19287 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
19288 ){
19289 const char *zDestFile = 0;
19290 const char *zDb = 0;
@@ -19288,10 +19349,11 @@
19349 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
19350 rc = 1;
19351 }
19352 close_db(pDest);
19353 }else
19354 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
19355
19356 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
19357 if( nArg==2 ){
19358 bail_on_error = booleanValue(azArg[1]);
19359 }else{
@@ -19318,10 +19380,11 @@
19380 */
19381 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
19382 test_breakpoint();
19383 }else
19384
19385 #ifndef SQLITE_SHELL_WASM_MODE
19386 if( c=='c' && strcmp(azArg[0],"cd")==0 ){
19387 failIfSafeMode(p, "cannot run .cd in safe mode");
19388 if( nArg==2 ){
19389 #if defined(_WIN32) || defined(WIN32)
19390 wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
@@ -19337,10 +19400,11 @@
19400 }else{
19401 raw_printf(stderr, "Usage: .cd DIRECTORY\n");
19402 rc = 1;
19403 }
19404 }else
19405 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
19406
19407 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
19408 if( nArg==2 ){
19409 setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
19410 }else{
@@ -19347,10 +19411,11 @@
19411 raw_printf(stderr, "Usage: .changes on|off\n");
19412 rc = 1;
19413 }
19414 }else
19415
19416 #ifndef SQLITE_SHELL_WASM_MODE
19417 /* Cancel output redirection, if it is currently set (by .testcase)
19418 ** Then read the content of the testcase-out.txt file and compare against
19419 ** azArg[1]. If there are differences, report an error and exit.
19420 */
19421 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
@@ -19371,20 +19436,23 @@
19436 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
19437 p->nCheck++;
19438 }
19439 sqlite3_free(zRes);
19440 }else
19441 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
19442
19443 #ifndef SQLITE_SHELL_WASM_MODE
19444 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
19445 failIfSafeMode(p, "cannot run .clone in safe mode");
19446 if( nArg==2 ){
19447 tryToClone(p, azArg[1]);
19448 }else{
19449 raw_printf(stderr, "Usage: .clone FILENAME\n");
19450 rc = 1;
19451 }
19452 }else
19453 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
19454
19455 if( c=='c' && strncmp(azArg[0], "connection", n)==0 ){
19456 if( nArg==1 ){
19457 /* List available connections */
19458 int i;
@@ -19506,15 +19574,15 @@
19574 utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
19575 utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
19576 }
19577 }else
19578
19579 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
19580 if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
19581 rc = shell_dbinfo_command(p, nArg, azArg);
19582 }else
19583
 
19584 if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
19585 open_db(p, 0);
19586 rc = recoverDatabaseCmd(p, nArg, azArg);
19587 }else
19588 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
@@ -19523,11 +19591,11 @@
19591 char *zLike = 0;
19592 char *zSql;
19593 int i;
19594 int savedShowHeader = p->showHeader;
19595 int savedShellFlags = p->shellFlgs;
19596 ShellClearFlag(p,
19597 SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
19598 |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
19599 for(i=1; i<nArg; i++){
19600 if( azArg[i][0]=='-' ){
19601 const char *z = azArg[i]+1;
@@ -19669,14 +19737,16 @@
19737 raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
19738 rc = 1;
19739 }
19740 }else
19741
19742 #ifndef SQLITE_SHELL_WASM_MODE
19743 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
19744 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
19745 rc = 2;
19746 }else
19747 #endif
19748
19749 /* The ".explain" command is automatic now. It is largely pointless. It
19750 ** retained purely for backwards compatibility */
19751 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
19752 int val = 1;
@@ -19927,10 +19997,11 @@
19997 }else{
19998 showHelp(p->out, 0);
19999 }
20000 }else
20001
20002 #ifndef SQLITE_SHELL_WASM_MODE
20003 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
20004 char *zTable = 0; /* Insert data into this table */
20005 char *zSchema = 0; /* within this schema (may default to "main") */
20006 char *zFile = 0; /* Name of file to extra content from */
20007 sqlite3_stmt *pStmt = NULL; /* A statement */
@@ -19948,20 +20019,16 @@
20019 int useOutputMode = 1; /* Use output mode to determine separators */
20020 char *zCreate = 0; /* CREATE TABLE statement text */
20021
20022 failIfSafeMode(p, "cannot run .import in safe mode");
20023 memset(&sCtx, 0, sizeof(sCtx));
 
 
 
 
 
20024 if( p->mode==MODE_Ascii ){
20025 xRead = ascii_read_one_field;
20026 }else{
20027 xRead = csv_read_one_field;
20028 }
20029 rc = 1;
20030 for(i=1; i<nArg; i++){
20031 char *z = azArg[i];
20032 if( z[0]=='-' && z[1]=='-' ) z++;
20033 if( z[0]!='-' ){
20034 if( zFile==0 ){
@@ -19969,11 +20036,10 @@
20036 }else if( zTable==0 ){
20037 zTable = z;
20038 }else{
20039 utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
20040 showHelp(p->out, "import");
 
20041 goto meta_command_exit;
20042 }
20043 }else if( strcmp(z,"-v")==0 ){
20044 eVerbose++;
20045 }else if( strcmp(z,"-schema")==0 && i<nArg-1 ){
@@ -19991,19 +20057,17 @@
20057 xRead = csv_read_one_field;
20058 useOutputMode = 0;
20059 }else{
20060 utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
20061 showHelp(p->out, "import");
 
20062 goto meta_command_exit;
20063 }
20064 }
20065 if( zTable==0 ){
20066 utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
20067 zFile==0 ? "FILE" : "TABLE");
20068 showHelp(p->out, "import");
 
20069 goto meta_command_exit;
20070 }
20071 seenInterrupt = 0;
20072 open_db(p, 0);
20073 if( useOutputMode ){
@@ -20011,25 +20075,22 @@
20075 ** the column and row separator characters from the output mode. */
20076 nSep = strlen30(p->colSeparator);
20077 if( nSep==0 ){
20078 raw_printf(stderr,
20079 "Error: non-null column separator required for import\n");
 
20080 goto meta_command_exit;
20081 }
20082 if( nSep>1 ){
20083 raw_printf(stderr,
20084 "Error: multi-character column separators not allowed"
20085 " for import\n");
 
20086 goto meta_command_exit;
20087 }
20088 nSep = strlen30(p->rowSeparator);
20089 if( nSep==0 ){
20090 raw_printf(stderr,
20091 "Error: non-null row separator required for import\n");
 
20092 goto meta_command_exit;
20093 }
20094 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
20095 /* When importing CSV (only), if the row separator is set to the
20096 ** default output row separator, change it to the default input
@@ -20039,11 +20100,10 @@
20100 nSep = strlen30(p->rowSeparator);
20101 }
20102 if( nSep>1 ){
20103 raw_printf(stderr, "Error: multi-character row separators not allowed"
20104 " for import\n");
 
20105 goto meta_command_exit;
20106 }
20107 sCtx.cColSep = p->colSeparator[0];
20108 sCtx.cRowSep = p->rowSeparator[0];
20109 }
@@ -20050,11 +20110,10 @@
20110 sCtx.zFile = zFile;
20111 sCtx.nLine = 1;
20112 if( sCtx.zFile[0]=='|' ){
20113 #ifdef SQLITE_OMIT_POPEN
20114 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
 
20115 goto meta_command_exit;
20116 #else
20117 sCtx.in = popen(sCtx.zFile+1, "r");
20118 sCtx.zFile = "<pipe>";
20119 sCtx.xCloser = pclose;
@@ -20063,12 +20122,10 @@
20122 sCtx.in = fopen(sCtx.zFile, "rb");
20123 sCtx.xCloser = fclose;
20124 }
20125 if( sCtx.in==0 ){
20126 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
 
 
20127 goto meta_command_exit;
20128 }
20129 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
20130 char zSep[2];
20131 zSep[1] = 0;
@@ -20077,10 +20134,15 @@
20134 output_c_string(p->out, zSep);
20135 utf8_printf(p->out, ", row separator ");
20136 zSep[0] = sCtx.cRowSep;
20137 output_c_string(p->out, zSep);
20138 utf8_printf(p->out, "\n");
20139 }
20140 sCtx.z = sqlite3_malloc64(120);
20141 if( sCtx.z==0 ){
20142 import_cleanup(&sCtx);
20143 shell_out_of_memory();
20144 }
20145 /* Below, resources must be freed before exit. */
20146 while( (nSkip--)>0 ){
20147 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
20148 }
@@ -20226,10 +20288,11 @@
20288 utf8_printf(p->out,
20289 "Added %d rows with %d errors using %d lines of input\n",
20290 sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
20291 }
20292 }else
20293 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
20294
20295 #ifndef SQLITE_UNTESTABLE
20296 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
20297 char *zSql;
20298 char *zCollist = 0;
@@ -20415,11 +20478,11 @@
20478 if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
20479 open_db(p, 0);
20480 lintDotCommand(p, azArg, nArg);
20481 }else
20482
20483 #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_WASM_MODE)
20484 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
20485 const char *zFile, *zProc;
20486 char *zErrMsg = 0;
20487 failIfSafeMode(p, "cannot run .load in safe mode");
20488 if( nArg<2 ){
@@ -20437,10 +20500,11 @@
20500 rc = 1;
20501 }
20502 }else
20503 #endif
20504
20505 #ifndef SQLITE_SHELL_WASM_MODE
20506 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
20507 failIfSafeMode(p, "cannot run .log in safe mode");
20508 if( nArg!=2 ){
20509 raw_printf(stderr, "Usage: .log FILENAME\n");
20510 rc = 1;
@@ -20448,10 +20512,11 @@
20512 const char *zFile = azArg[1];
20513 output_file_close(p->pLog);
20514 p->pLog = output_file_open(zFile, 0);
20515 }
20516 }else
20517 #endif
20518
20519 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
20520 const char *zMode = 0;
20521 const char *zTabname = 0;
20522 int i, n2;
@@ -20572,10 +20637,11 @@
20637 rc = 1;
20638 }
20639 p->cMode = p->mode;
20640 }else
20641
20642 #ifndef SQLITE_SHELL_WASM_MODE
20643 if( c=='n' && strcmp(azArg[0], "nonce")==0 ){
20644 if( nArg!=2 ){
20645 raw_printf(stderr, "Usage: .nonce NONCE\n");
20646 rc = 1;
20647 }else if( p->zNonce==0 || strcmp(azArg[1],p->zNonce)!=0 ){
@@ -20586,10 +20652,11 @@
20652 p->bSafeMode = 0;
20653 return 0; /* Return immediately to bypass the safe mode reset
20654 ** at the end of this procedure */
20655 }
20656 }else
20657 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
20658
20659 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
20660 if( nArg==2 ){
20661 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
20662 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
@@ -20607,10 +20674,11 @@
20674 int openMode = SHELL_OPEN_UNSPEC;
20675
20676 /* Check for command-line arguments */
20677 for(iName=1; iName<nArg; iName++){
20678 const char *z = azArg[iName];
20679 #ifndef SQLITE_SHELL_WASM_MODE
20680 if( optionMatch(z,"new") ){
20681 newFlag = 1;
20682 #ifdef SQLITE_HAVE_ZLIB
20683 }else if( optionMatch(z, "zip") ){
20684 openMode = SHELL_OPEN_ZIPFILE;
@@ -20627,11 +20695,13 @@
20695 }else if( optionMatch(z, "hexdb") ){
20696 openMode = SHELL_OPEN_HEXDB;
20697 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
20698 p->szMax = integerValue(azArg[++iName]);
20699 #endif /* SQLITE_OMIT_DESERIALIZE */
20700 }else
20701 #endif /* !SQLITE_SHELL_WASM_MODE */
20702 if( z[0]=='-' ){
20703 utf8_printf(stderr, "unknown option: %s\n", z);
20704 rc = 1;
20705 goto meta_command_exit;
20706 }else if( zFN ){
20707 utf8_printf(stderr, "extra argument: \"%s\"\n", z);
@@ -20654,17 +20724,21 @@
20724 p->szMax = 0;
20725
20726 /* If a filename is specified, try to open it first */
20727 if( zFN || p->openMode==SHELL_OPEN_HEXDB ){
20728 if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN);
20729 #ifndef SQLITE_SHELL_WASM_MODE
20730 if( p->bSafeMode
20731 && p->openMode!=SHELL_OPEN_HEXDB
20732 && zFN
20733 && strcmp(zFN,":memory:")!=0
20734 ){
20735 failIfSafeMode(p, "cannot open disk-based database files in safe mode");
20736 }
20737 #else
20738 /* WASM mode has its own sandboxed pseudo-filesystem. */
20739 #endif
20740 if( zFN ){
20741 zNewFilename = sqlite3_mprintf("%s", zFN);
20742 shell_check_oom(zNewFilename);
20743 }else{
20744 zNewFilename = 0;
@@ -20683,10 +20757,11 @@
20757 p->pAuxDb->zDbFilename = 0;
20758 open_db(p, 0);
20759 }
20760 }else
20761
20762 #ifndef SQLITE_SHELL_WASM_MODE
20763 if( (c=='o'
20764 && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
20765 || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
20766 ){
20767 char *zFile = 0;
@@ -20798,10 +20873,11 @@
20873 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20874 }
20875 }
20876 sqlite3_free(zFile);
20877 }else
20878 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
20879
20880 if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
20881 open_db(p,0);
20882 if( nArg<=1 ) goto parameter_syntax_error;
20883
@@ -20967,14 +21043,17 @@
21043 if( nArg >= 3) {
21044 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
21045 }
21046 }else
21047
21048 #ifndef SQLITE_SHELL_WASM_MODE
21049 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
21050 rc = 2;
21051 }else
21052 #endif
21053
21054 #ifndef SQLITE_SHELL_WASM_MODE
21055 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
21056 FILE *inSaved = p->in;
21057 int savedLineno = p->lineno;
21058 failIfSafeMode(p, "cannot run .read in safe mode");
21059 if( nArg!=2 ){
@@ -21005,11 +21084,13 @@
21084 fclose(p->in);
21085 }
21086 p->in = inSaved;
21087 p->lineno = savedLineno;
21088 }else
21089 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
21090
21091 #ifndef SQLITE_SHELL_WASM_MODE
21092 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
21093 const char *zSrcFile;
21094 const char *zDb;
21095 sqlite3 *pSrc;
21096 sqlite3_backup *pBackup;
@@ -21057,10 +21138,11 @@
21138 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
21139 rc = 1;
21140 }
21141 close_db(pSrc);
21142 }else
21143 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
21144
21145 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
21146 if( nArg==2 ){
21147 p->scanstatsOn = (u8)booleanValue(azArg[1]);
21148 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
@@ -21682,11 +21764,11 @@
21764 shell_exec(p, zSql, 0);
21765 }
21766 sqlite3_free(zSql);
21767 }else
21768
21769 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
21770 if( c=='s'
21771 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
21772 ){
21773 char *zCmd;
21774 int i, x;
@@ -21703,11 +21785,11 @@
21785 }
21786 x = zCmd!=0 ? system(zCmd) : 1;
21787 sqlite3_free(zCmd);
21788 if( x ) raw_printf(stderr, "System command returns %d\n", x);
21789 }else
21790 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE) */
21791
21792 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
21793 static const char *azBool[] = { "off", "on", "trigger", "full"};
21794 const char *zOut;
21795 int i;
@@ -21715,11 +21797,11 @@
21797 raw_printf(stderr, "Usage: .show\n");
21798 rc = 1;
21799 goto meta_command_exit;
21800 }
21801 utf8_printf(p->out, "%12.12s: %s\n","echo",
21802 azBool[ShellHasFlag(p, SHFLG_Echo)]);
21803 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
21804 utf8_printf(p->out, "%12.12s: %s\n","explain",
21805 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
21806 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21807 if( p->mode==MODE_Column
@@ -21883,10 +21965,11 @@
21965
21966 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
21967 sqlite3_free(azResult);
21968 }else
21969
21970 #ifndef SQLITE_SHELL_WASM_MODE
21971 /* Begin redirecting output to the file "testcase-out.txt" */
21972 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
21973 output_reset(p);
21974 p->out = output_file_open("testcase-out.txt", 0);
21975 if( p->out==0 ){
@@ -21896,10 +21979,11 @@
21979 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
21980 }else{
21981 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
21982 }
21983 }else
21984 #endif /* !defined(SQLITE_SHELL_WASM_MODE) */
21985
21986 #ifndef SQLITE_UNTESTABLE
21987 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
21988 static const struct {
21989 const char *zCtrlName; /* Name of a test-control option */
@@ -22465,11 +22549,11 @@
22549 /* fall thru */
22550 case ']':
22551 cWait = 0;
22552 qss = QSS_SETV(qss, 0);
22553 goto PlainScan;
22554 default: assert(0);
22555 }
22556 }
22557 }
22558 }
22559 return qss;
@@ -22486,11 +22570,11 @@
22570 zLine += 1; /* Oracle */
22571 else if ( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' )
22572 zLine += 2; /* SQL Server */
22573 else
22574 return 0;
22575 return quickscan(zLine, QSS_Start)==QSS_Start;
22576 }
22577
22578 /*
22579 ** We need a default sqlite3_complete() implementation to use in case
22580 ** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
@@ -22563,10 +22647,46 @@
22647 raw_printf(p->out, "%s\n", zLineBuf);
22648 }
22649 return 0;
22650 }
22651
22652 static void echo_group_input(ShellState *p, const char *zDo){
22653 if( ShellHasFlag(p, SHFLG_Echo) ) utf8_printf(p->out, "%s\n", zDo);
22654 }
22655
22656 #ifdef SQLITE_SHELL_WASM_MODE
22657 /*
22658 ** Alternate one_input_line() impl for wasm mode. This is not in the primary impl
22659 ** because we need the global shellState and cannot access it from that function
22660 ** without moving lots of code around (creating a larger/messier diff).
22661 */
22662 static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
22663 /* Parse the next line from shellState.wasm.zInput. */
22664 const char *zBegin = shellState.wasm.zPos;
22665 const char *z = zBegin;
22666 char *zLine = 0;
22667 int nZ = 0;
22668
22669 UNUSED_PARAMETER(in);
22670 UNUSED_PARAMETER(isContinuation);
22671 if(!z || !*z){
22672 return 0;
22673 }
22674 while(*z && isspace(*z)) ++z;
22675 zBegin = z;
22676 for(; *z && '\n'!=*z; ++nZ, ++z){}
22677 if(nZ>0 && '\r'==zBegin[nZ-1]){
22678 --nZ;
22679 }
22680 shellState.wasm.zPos = z;
22681 zLine = realloc(zPrior, nZ+1);
22682 shell_check_oom(zLine);
22683 memcpy(zLine, zBegin, (size_t)nZ);
22684 zLine[nZ] = 0;
22685 return zLine;
22686 }
22687 #endif /* SQLITE_SHELL_WASM_MODE */
22688
22689 /*
22690 ** Read input from *in and process it. If *in==0 then input
22691 ** is interactive - the user is typing it it. Otherwise, input
22692 ** is coming from a file or device. A prompt is issued and history
@@ -22612,18 +22732,17 @@
22732 && line_is_complete(zSql, nSql) ){
22733 memcpy(zLine,";",2);
22734 }
22735 qss = quickscan(zLine, qss);
22736 if( QSS_PLAINWHITE(qss) && nSql==0 ){
 
 
22737 /* Just swallow single-line whitespace */
22738 echo_group_input(p, zLine);
22739 qss = QSS_Start;
22740 continue;
22741 }
22742 if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
22743 echo_group_input(p, zLine);
22744 if( zLine[0]=='.' ){
22745 rc = do_meta_command(zLine, p);
22746 if( rc==2 ){ /* exit requested */
22747 break;
22748 }else if( rc ){
@@ -22652,10 +22771,11 @@
22771 zSql[nSql++] = '\n';
22772 memcpy(zSql+nSql, zLine, nLine+1);
22773 nSql += nLine;
22774 }
22775 if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
22776 echo_group_input(p, zSql);
22777 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22778 nSql = 0;
22779 if( p->outCount ){
22780 output_reset(p);
22781 p->outCount = 0;
@@ -22663,17 +22783,18 @@
22783 clearTempFile(p);
22784 }
22785 p->bSafeMode = p->bSafeModePersist;
22786 qss = QSS_Start;
22787 }else if( nSql && QSS_PLAINWHITE(qss) ){
22788 echo_group_input(p, zSql);
22789 nSql = 0;
22790 qss = QSS_Start;
22791 }
22792 }
22793 if( nSql ){
22794 /* This may be incomplete. Let the SQL parser deal with that. */
22795 echo_group_input(p, zSql);
22796 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22797 }
22798 free(zSql);
22799 free(zLine);
22800 --p->inputNesting;
@@ -22808,11 +22929,11 @@
22929 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
22930 " -csv set output mode to 'csv'\n"
22931 #if !defined(SQLITE_OMIT_DESERIALIZE)
22932 " -deserialize open the database using sqlite3_deserialize()\n"
22933 #endif
22934 " -echo print inputs before execution\n"
22935 " -init FILENAME read/process named file\n"
22936 " -[no]header turn headers on or off\n"
22937 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
22938 " -heap SIZE Size of heap for memsys3 or memsys5\n"
22939 #endif
@@ -22943,19 +23064,30 @@
23064 # define SQLITE_SHELL_IS_UTF8 (0)
23065 # else
23066 # define SQLITE_SHELL_IS_UTF8 (1)
23067 # endif
23068 #endif
23069
23070 #ifdef SQLITE_SHELL_WASM_MODE
23071 # define main fiddle_main
23072 #endif
23073
23074 #if SQLITE_SHELL_IS_UTF8
23075 int SQLITE_CDECL main(int argc, char **argv){
23076 #else
23077 int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
23078 char **argv;
23079 #endif
23080 #ifdef SQLITE_DEBUG
23081 sqlite3_uint64 mem_main_enter = sqlite3_memory_used();
23082 #endif
23083 char *zErrMsg = 0;
23084 #ifdef SQLITE_SHELL_WASM_MODE
23085 # define data shellState
23086 #else
23087 ShellState data;
23088 #endif
23089 const char *zInitFile = 0;
23090 int i;
23091 int rc = 0;
23092 int warnInmemoryDb = 0;
23093 int readStdin = 1;
@@ -22967,12 +23099,17 @@
23099 int argcToFree = 0;
23100 #endif
23101
23102 setBinaryMode(stdin, 0);
23103 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
23104 #ifdef SQLITE_SHELL_WASM_MODE
23105 stdin_is_interactive = 0;
23106 stdout_is_console = 1;
23107 #else
23108 stdin_is_interactive = isatty(0);
23109 stdout_is_console = isatty(1);
23110 #endif
23111
23112 #if !defined(_WIN32_WCE)
23113 if( getenv("SQLITE_DEBUG_BREAK") ){
23114 if( isatty(0) && isatty(2) ){
23115 fprintf(stderr,
@@ -23224,11 +23361,13 @@
23361 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
23362 return 1;
23363 #endif
23364 }
23365 data.out = stdout;
23366 #ifndef SQLITE_SHELL_WASM_MODE
23367 sqlite3_appendvfs_init(0,0,0);
23368 #endif
23369
23370 /* Go ahead and open the database file if it already exists. If the
23371 ** file does not exist, delay opening it. This prevents empty database
23372 ** files from being created if a user mistypes the database name argument
23373 ** to the sqlite command-line tool.
@@ -23490,10 +23629,13 @@
23629 }else{
23630 data.in = stdin;
23631 rc = process_input(&data);
23632 }
23633 }
23634 #ifndef SQLITE_SHELL_WASM_MODE
23635 /* In WASM mode we have to leave the db state in place so that
23636 ** client code can "push" SQL into it after this call returns. */
23637 free(azCmd);
23638 set_table_name(&data, 0);
23639 if( data.db ){
23640 session_close_all(&data, -1);
23641 close_db(data.db);
@@ -23516,7 +23658,138 @@
23658 free(data.colWidth);
23659 free(data.zNonce);
23660 /* Clear the global data structure so that valgrind will detect memory
23661 ** leaks */
23662 memset(&data, 0, sizeof(data));
23663 #ifdef SQLITE_DEBUG
23664 if( sqlite3_memory_used()>mem_main_enter ){
23665 utf8_printf(stderr, "Memory leaked: %u bytes\n",
23666 (unsigned int)(sqlite3_memory_used()-mem_main_enter));
23667 }
23668 #endif
23669 #endif /* !SQLITE_SHELL_WASM_MODE */
23670 return rc;
23671 }
23672
23673
23674 #ifdef SQLITE_SHELL_WASM_MODE
23675 /* Only for emcc experimentation purposes. */
23676 int fiddle_experiment(int a,int b){
23677 return a + b;
23678 }
23679
23680 /* Only for emcc experimentation purposes.
23681
23682 Define this function in JS using:
23683
23684 emcc ... --js-library somefile.js
23685
23686 containing:
23687
23688 mergeInto(LibraryManager.library, {
23689 my_foo: function(){
23690 console.debug("my_foo()",arguments);
23691 }
23692 });
23693 */
23694 /*extern void my_foo(sqlite3 *);*/
23695 /* Only for emcc experimentation purposes. */
23696 sqlite3 * fiddle_the_db(){
23697 printf("fiddle_the_db(%p)\n", (const void*)globalDb);
23698 /*my_foo(globalDb);*/
23699 return globalDb;
23700 }
23701 /* Only for emcc experimentation purposes. */
23702 sqlite3 * fiddle_db_arg(sqlite3 *arg){
23703 printf("fiddle_db_arg(%p)\n", (const void*)arg);
23704 return arg;
23705 }
23706
23707 /*
23708 ** Intended to be called via a SharedWorker() while a separate
23709 ** SharedWorker() (which manages the wasm module) is performing work
23710 ** which should be interrupted. Unfortunately, SharedWorker is not
23711 ** portable enough to make real use of.
23712 */
23713 void fiddle_interrupt(void){
23714 if(globalDb) sqlite3_interrupt(globalDb);
23715 }
23716
23717 /*
23718 ** Returns the filename of the given db name, assuming "main" if
23719 ** zDbName is NULL. Returns NULL if globalDb is not opened.
23720 */
23721 const char * fiddle_db_filename(const char * zDbName){
23722 return globalDb
23723 ? sqlite3_db_filename(globalDb, zDbName ? zDbName : "main")
23724 : NULL;
23725 }
23726
23727 /*
23728 ** Closes, unlinks, and reopens the db using its current filename (or
23729 ** the default if the db is currently closed). It is assumed, for
23730 ** purposes of the fiddle build, that the file is in a transient
23731 ** virtual filesystem within the browser.
23732 */
23733 void fiddle_reset_db(void){
23734 char *zFilename = 0;
23735 if(0==globalDb){
23736 shellState.pAuxDb->zDbFilename = "/fiddle.sqlite3";
23737 }else{
23738 zFilename =
23739 sqlite3_mprintf("%s", sqlite3_db_filename(globalDb, "main"));
23740 shell_check_oom(zFilename);
23741 close_db(globalDb);
23742 shellDeleteFile(zFilename);
23743 shellState.db = 0;
23744 shellState.pAuxDb->zDbFilename = zFilename;
23745 }
23746 open_db(&shellState, 0);
23747 sqlite3_free(zFilename);
23748 }
23749
23750 /*
23751 ** Trivial exportable function for emscripten. Needs to be exported using:
23752 **
23753 ** emcc ..flags... -sEXPORTED_FUNCTIONS=_fiddle_exec -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
23754 **
23755 ** (Note the underscore before the function name.) It processes zSql
23756 ** as if it were input to the sqlite3 shell and redirects all output
23757 ** to the wasm binding.
23758 */
23759 void fiddle_exec(const char * zSql){
23760 static int once = 0;
23761 int rc = 0;
23762 if(!once){
23763 /* Simulate an argv array for main() */
23764 static char * argv[] = {"fiddle",
23765 "-bail",
23766 "-safe"};
23767 rc = fiddle_main((int)(sizeof(argv)/sizeof(argv[0])), argv);
23768 once = rc ? -1 : 1;
23769 memset(&shellState.wasm, 0, sizeof(shellState.wasm));
23770 printf(
23771 "SQLite version %s %.19s\n" /*extra-version-info*/,
23772 sqlite3_libversion(), sqlite3_sourceid()
23773 );
23774 puts("WASM shell");
23775 puts("Enter \".help\" for usage hints.");
23776 if(once>0){
23777 fiddle_reset_db();
23778 }
23779 if(shellState.db){
23780 printf("Connected to %s.\n", fiddle_db_filename(NULL));
23781 }else{
23782 fprintf(stderr,"ERROR initializing db!\n");
23783 return;
23784 }
23785 }
23786 if(once<0){
23787 puts("DB init failed. Not executing SQL.");
23788 }else if(zSql && *zSql){
23789 shellState.wasm.zInput = zSql;
23790 shellState.wasm.zPos = zSql;
23791 process_input(&shellState);
23792 memset(&shellState.wasm, 0, sizeof(shellState.wasm));
23793 }
23794 }
23795 #endif /* SQLITE_SHELL_WASM_MODE */
23796
+1868 -1588
--- 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-05-10 00:24:01 c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527"
457
+#define SQLITE_SOURCE_ID "2022-06-15 16:26:37 56c60a35ea457f06db58ec3f694a1ae16fd03e6625da1d7879d63d72bbcb1c62"
458458
459459
/*
460460
** CAPI3REF: Run-Time Library Version Numbers
461461
** KEYWORDS: sqlite3_version sqlite3_sourceid
462462
**
@@ -6580,10 +6580,32 @@
65806580
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
65816581
** create the statement in the first place.
65826582
*/
65836583
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
65846584
6585
+/*
6586
+** CAPI3REF: Return The Schema Name For A Database Connection
6587
+** METHOD: sqlite3
6588
+**
6589
+** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
6590
+** for the N-th database on database connection D, or a NULL pointer of N is
6591
+** out of range. An N alue of 0 means the main database file. An N of 1 is
6592
+** the "temp" schema. Larger values of N correspond to various ATTACH-ed
6593
+** databases.
6594
+**
6595
+** Space to hold the string that is returned by sqlite3_db_name() is managed
6596
+** by SQLite itself. The string might be deallocated by any operation that
6597
+** changes the schema, including [ATTACH] or [DETACH] or calls to
6598
+** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that
6599
+** occur on a different thread. Applications that need to
6600
+** remember the string long-term should make their own copy. Applications that
6601
+** are accessing the same database connection simultaneously on multiple
6602
+** threads should mutex-protect calls to this API and should make their own
6603
+** private copy of the result prior to releasing the mutex.
6604
+*/
6605
+SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N);
6606
+
65856607
/*
65866608
** CAPI3REF: Return The Filename For A Database Connection
65876609
** METHOD: sqlite3
65886610
**
65896611
** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
@@ -15702,17 +15724,18 @@
1570215724
#define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */
1570315725
#define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */
1570415726
#define OP_VRename 176
1570515727
#define OP_Pagecount 177
1570615728
#define OP_MaxPgcnt 178
15707
-#define OP_FilterAdd 179 /* synopsis: filter(P1) += key(P3@P4) */
15708
-#define OP_Trace 180
15709
-#define OP_CursorHint 181
15710
-#define OP_ReleaseReg 182 /* synopsis: release r[P1@P2] mask P3 */
15711
-#define OP_Noop 183
15712
-#define OP_Explain 184
15713
-#define OP_Abortable 185
15729
+#define OP_ClrSubtype 179 /* synopsis: r[P1].subtype = 0 */
15730
+#define OP_FilterAdd 180 /* synopsis: filter(P1) += key(P3@P4) */
15731
+#define OP_Trace 181
15732
+#define OP_CursorHint 182
15733
+#define OP_ReleaseReg 183 /* synopsis: release r[P1@P2] mask P3 */
15734
+#define OP_Noop 184
15735
+#define OP_Explain 185
15736
+#define OP_Abortable 186
1571415737
1571515738
/* Properties such as "out2" or "jump" that are specified in
1571615739
** comments following the "case" for each opcode in the vdbe.c
1571715740
** are encoded into bitvectors as follows:
1571815741
*/
@@ -15743,12 +15766,12 @@
1574315766
/* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
1574415767
/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
1574515768
/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
1574615769
/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
1574715770
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15748
-/* 176 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15749
-/* 184 */ 0x00, 0x00,}
15771
+/* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\
15772
+/* 184 */ 0x00, 0x00, 0x00,}
1575015773
1575115774
/* The resolve3P2Values() routine is able to run faster if it knows
1575215775
** the value of the largest JUMP opcode. The smaller the maximum
1575315776
** JUMP opcode the better, so the mkopcodeh.tcl script that
1575415777
** generated this include file strives to group all JUMP opcodes
@@ -16285,10 +16308,17 @@
1628516308
/* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h
1628616309
*/
1628716310
#ifndef SQLITE_MAX_PATHLEN
1628816311
# define SQLITE_MAX_PATHLEN FILENAME_MAX
1628916312
#endif
16313
+
16314
+/* Maximum number of symlinks that will be resolved while trying to
16315
+** expand a filename in xFullPathname() in the VFS.
16316
+*/
16317
+#ifndef SQLITE_MAX_SYMLINK
16318
+# define SQLITE_MAX_SYMLINK 200
16319
+#endif
1629016320
1629116321
/*
1629216322
** The default size of a disk sector
1629316323
*/
1629416324
#ifndef SQLITE_DEFAULT_SECTOR_SIZE
@@ -17157,11 +17187,11 @@
1715717187
#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
1715817188
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
1715917189
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
1716017190
** single query - might change over time */
1716117191
#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
17162
-#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
17192
+/* 0x8000 -- available for reuse */
1716317193
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
1716417194
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
1716517195
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
1716617196
#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
1716717197
#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
@@ -17174,10 +17204,11 @@
1717417204
#define INLINEFUNC_implies_nonnull_row 1
1717517205
#define INLINEFUNC_expr_implies_expr 2
1717617206
#define INLINEFUNC_expr_compare 3
1717717207
#define INLINEFUNC_affinity 4
1717817208
#define INLINEFUNC_iif 5
17209
+#define INLINEFUNC_sqlite_offset 6
1717917210
#define INLINEFUNC_unlikely 99 /* Default case */
1718017211
1718117212
/*
1718217213
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
1718317214
** used to create the initializers for the FuncDef structures.
@@ -18120,11 +18151,11 @@
1812018151
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
1812118152
** TK_VARIABLE: variable number (always >= 1).
1812218153
** TK_SELECT_COLUMN: column of the result vector */
1812318154
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
1812418155
union {
18125
- int iJoin; /* If EP_FromJoin, the right table of the join */
18156
+ int iJoin; /* If EP_OuterON or EP_InnerON, the right table */
1812618157
int iOfst; /* else: start of token from start of statement */
1812718158
} w;
1812818159
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
1812918160
union {
1813018161
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@@ -18141,33 +18172,33 @@
1814118172
** Value restrictions:
1814218173
**
1814318174
** EP_Agg == NC_HasAgg == SF_HasAgg
1814418175
** EP_Win == NC_HasWin
1814518176
*/
18146
-#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
18147
-#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
18148
-#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
18149
-#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
18177
+#define EP_OuterON 0x000001 /* Originates in ON/USING clause of outer join */
18178
+#define EP_InnerON 0x000002 /* Originates in ON/USING of an inner join */
18179
+#define EP_Distinct 0x000004 /* Aggregate function with DISTINCT keyword */
18180
+#define EP_HasFunc 0x000008 /* Contains one or more functions of any kind */
1815018181
#define EP_Agg 0x000010 /* Contains one or more aggregate functions */
18151
-#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
18152
-#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
18153
-#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
18154
-#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
18155
-#define EP_Commuted 0x000200 /* Comparison operator has been commuted */
18156
-#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
18157
-#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
18158
-#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
18159
-#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
18160
-#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
18182
+#define EP_FixedCol 0x000020 /* TK_Column with a known fixed value */
18183
+#define EP_VarSelect 0x000040 /* pSelect is correlated, not constant */
18184
+#define EP_DblQuoted 0x000080 /* token.z was originally in "..." */
18185
+#define EP_InfixFunc 0x000100 /* True for an infix function: LIKE, GLOB, etc */
18186
+#define EP_Collate 0x000200 /* Tree contains a TK_COLLATE operator */
18187
+#define EP_Commuted 0x000400 /* Comparison operator has been commuted */
18188
+#define EP_IntValue 0x000800 /* Integer value contained in u.iValue */
18189
+#define EP_xIsSelect 0x001000 /* x.pSelect is valid (otherwise x.pList is) */
18190
+#define EP_Skip 0x002000 /* Operator does not contribute to affinity */
18191
+#define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
1816118192
#define EP_Win 0x008000 /* Contains window functions */
18162
-#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
18163
-#define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */
18164
-#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
18165
-#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
18166
-#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
18167
-#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
18168
-#define EP_InnerJoin 0x400000 /* Originates in ON/USING of an inner join */
18193
+#define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
18194
+#define EP_MemToken 0x020000 /* Need to sqlite3DbFree() Expr.zToken */
18195
+#define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */
18196
+#define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */
18197
+#define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
18198
+#define EP_CanBeNull 0x200000 /* Can be null despite NOT NULL constraint */
18199
+#define EP_Subquery 0x400000 /* Tree contains a TK_SELECT operator */
1816918200
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
1817018201
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
1817118202
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
1817218203
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
1817318204
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
@@ -18186,12 +18217,12 @@
1818618217
*/
1818718218
#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
1818818219
#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
1818918220
#define ExprSetProperty(E,P) (E)->flags|=(P)
1819018221
#define ExprClearProperty(E,P) (E)->flags&=~(P)
18191
-#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
18192
-#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
18222
+#define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue)
18223
+#define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse)
1819318224
1819418225
/* Macros used to ensure that the correct members of unions are accessed
1819518226
** in Expr.
1819618227
*/
1819718228
#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
@@ -18366,16 +18397,18 @@
1836618397
u8 jointype; /* Type of join between this table and the previous */
1836718398
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
1836818399
unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
1836918400
unsigned isTabFunc :1; /* True if table-valued-function syntax */
1837018401
unsigned isCorrelated :1; /* True if sub-query is correlated */
18402
+ unsigned isMaterialized:1; /* This is a materialized view */
1837118403
unsigned viaCoroutine :1; /* Implemented as a co-routine */
1837218404
unsigned isRecursive :1; /* True for recursive reference in WITH */
1837318405
unsigned fromDDL :1; /* Comes from sqlite_schema */
1837418406
unsigned isCte :1; /* This is a CTE */
1837518407
unsigned notCte :1; /* This item may not match a CTE */
1837618408
unsigned isUsing :1; /* u3.pUsing is valid */
18409
+ unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
1837718410
unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */
1837818411
unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
1837918412
} fg;
1838018413
int iCursor; /* The VDBE cursor number used to access this table */
1838118414
union {
@@ -20595,11 +20628,10 @@
2059520628
** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
2059620629
*/
2059720630
#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */
2059820631
#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */
2059920632
#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
20600
-#define IN_INDEX_REUSE_CUR 0x0008 /* Reuse prior table cursor */
2060120633
SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);
2060220634
2060320635
SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
2060420636
SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
2060520637
#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
@@ -22224,11 +22256,11 @@
2222422256
u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
2222522257
#endif
2222622258
Bool isEphemeral:1; /* True for an ephemeral table */
2222722259
Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
2222822260
Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
22229
- Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */
22261
+ Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */
2223022262
u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
2223122263
union { /* pBtx for isEphermeral. pAltMap otherwise */
2223222264
Btree *pBtx; /* Separate file holding temporary table */
2223322265
u32 *aAltMap; /* Mapping from table to index column numbers */
2223422266
} ub;
@@ -30545,11 +30577,13 @@
3054530577
/*
3054630578
** If pExpr has a byte offset for the start of a token, record that as
3054730579
** as the error offset.
3054830580
*/
3054930581
SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
30550
- while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
30582
+ while( pExpr
30583
+ && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0)
30584
+ ){
3055130585
pExpr = pExpr->pLeft;
3055230586
}
3055330587
if( pExpr==0 ) return;
3055430588
db->errByteOffset = pExpr->w.iOfst;
3055530589
}
@@ -31196,10 +31230,13 @@
3119631230
sqlite3_str_appendf(&x, " DDL");
3119731231
}
3119831232
if( pItem->fg.isCte ){
3119931233
sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
3120031234
}
31235
+ if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
31236
+ sqlite3_str_appendf(&x, " ON");
31237
+ }
3120131238
sqlite3StrAccumFinish(&x);
3120231239
sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
3120331240
n = 0;
3120431241
if( pItem->pSelect ) n++;
3120531242
if( pItem->fg.isTabFunc ) n++;
@@ -31470,12 +31507,15 @@
3147031507
if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
3147131508
StrAccum x;
3147231509
sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
3147331510
sqlite3_str_appendf(&x, " fg.af=%x.%c",
3147431511
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
31475
- if( ExprHasProperty(pExpr, EP_FromJoin) ){
31476
- sqlite3_str_appendf(&x, " iJoin=%d", pExpr->w.iJoin);
31512
+ if( ExprHasProperty(pExpr, EP_OuterON) ){
31513
+ sqlite3_str_appendf(&x, " outer.iJoin=%d", pExpr->w.iJoin);
31514
+ }
31515
+ if( ExprHasProperty(pExpr, EP_InnerON) ){
31516
+ sqlite3_str_appendf(&x, " inner.iJoin=%d", pExpr->w.iJoin);
3147731517
}
3147831518
if( ExprHasProperty(pExpr, EP_FromDDL) ){
3147931519
sqlite3_str_appendf(&x, " DDL");
3148031520
}
3148131521
if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -35398,17 +35438,18 @@
3539835438
/* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
3539935439
/* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
3540035440
/* 176 */ "VRename" OpHelp(""),
3540135441
/* 177 */ "Pagecount" OpHelp(""),
3540235442
/* 178 */ "MaxPgcnt" OpHelp(""),
35403
- /* 179 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
35404
- /* 180 */ "Trace" OpHelp(""),
35405
- /* 181 */ "CursorHint" OpHelp(""),
35406
- /* 182 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
35407
- /* 183 */ "Noop" OpHelp(""),
35408
- /* 184 */ "Explain" OpHelp(""),
35409
- /* 185 */ "Abortable" OpHelp(""),
35443
+ /* 179 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"),
35444
+ /* 180 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
35445
+ /* 181 */ "Trace" OpHelp(""),
35446
+ /* 182 */ "CursorHint" OpHelp(""),
35447
+ /* 183 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
35448
+ /* 184 */ "Noop" OpHelp(""),
35449
+ /* 185 */ "Explain" OpHelp(""),
35450
+ /* 186 */ "Abortable" OpHelp(""),
3541035451
};
3541135452
return azName[i];
3541235453
}
3541335454
#endif
3541435455
@@ -41837,90 +41878,103 @@
4183741878
}
4183841879
return SQLITE_OK;
4183941880
}
4184041881
4184141882
/*
41842
-** If the last component of the pathname in z[0]..z[j-1] is something
41843
-** other than ".." then back it out and return true. If the last
41844
-** component is empty or if it is ".." then return false.
41845
-*/
41846
-static int unixBackupDir(const char *z, int *pJ){
41847
- int j = *pJ;
41848
- int i;
41849
- if( j<=0 ) return 0;
41850
- for(i=j-1; i>0 && z[i-1]!='/'; i--){}
41851
- if( i==0 ) return 0;
41852
- if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0;
41853
- *pJ = i-1;
41854
- return 1;
41855
-}
41856
-
41857
-/*
41858
-** Convert a relative pathname into a full pathname. Also
41859
-** simplify the pathname as follows:
41860
-**
41861
-** Remove all instances of /./
41862
-** Remove all isntances of /X/../ for any X
41863
-*/
41864
-static int mkFullPathname(
41865
- const char *zPath, /* Input path */
41866
- char *zOut, /* Output buffer */
41867
- int nOut /* Allocated size of buffer zOut */
41868
-){
41869
- int nPath = sqlite3Strlen30(zPath);
41870
- int iOff = 0;
41871
- int i, j;
41872
- if( zPath[0]!='/' ){
41873
- if( osGetcwd(zOut, nOut-2)==0 ){
41874
- return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
41875
- }
41876
- iOff = sqlite3Strlen30(zOut);
41877
- zOut[iOff++] = '/';
41878
- }
41879
- if( (iOff+nPath+1)>nOut ){
41880
- /* SQLite assumes that xFullPathname() nul-terminates the output buffer
41881
- ** even if it returns an error. */
41882
- zOut[iOff] = '\0';
41883
- return SQLITE_CANTOPEN_BKPT;
41884
- }
41885
- sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
41886
-
41887
- /* Remove duplicate '/' characters. Except, two // at the beginning
41888
- ** of a pathname is allowed since this is important on windows. */
41889
- for(i=j=1; zOut[i]; i++){
41890
- zOut[j++] = zOut[i];
41891
- while( zOut[i]=='/' && zOut[i+1]=='/' ) i++;
41892
- }
41893
- zOut[j] = 0;
41894
-
41895
- assert( zOut[0]=='/' );
41896
- for(i=j=0; zOut[i]; i++){
41897
- if( zOut[i]=='/' ){
41898
- /* Skip over internal "/." directory components */
41899
- if( zOut[i+1]=='.' && zOut[i+2]=='/' ){
41900
- i += 1;
41901
- continue;
41902
- }
41903
-
41904
- /* If this is a "/.." directory component then back out the
41905
- ** previous term of the directory if it is something other than "..".
41906
- */
41907
- if( zOut[i+1]=='.'
41908
- && zOut[i+2]=='.'
41909
- && zOut[i+3]=='/'
41910
- && unixBackupDir(zOut, &j)
41911
- ){
41912
- i += 2;
41913
- continue;
41914
- }
41915
- }
41916
- if( ALWAYS(j>=0) ) zOut[j] = zOut[i];
41917
- j++;
41918
- }
41919
- if( NEVER(j==0) ) zOut[j++] = '/';
41920
- zOut[j] = 0;
41921
- return SQLITE_OK;
41883
+** A pathname under construction
41884
+*/
41885
+typedef struct DbPath DbPath;
41886
+struct DbPath {
41887
+ int rc; /* Non-zero following any error */
41888
+ int nSymlink; /* Number of symlinks resolved */
41889
+ char *zOut; /* Write the pathname here */
41890
+ int nOut; /* Bytes of space available to zOut[] */
41891
+ int nUsed; /* Bytes of zOut[] currently being used */
41892
+};
41893
+
41894
+/* Forward reference */
41895
+static void appendAllPathElements(DbPath*,const char*);
41896
+
41897
+/*
41898
+** Append a single path element to the DbPath under construction
41899
+*/
41900
+static void appendOnePathElement(
41901
+ DbPath *pPath, /* Path under construction, to which to append zName */
41902
+ const char *zName, /* Name to append to pPath. Not zero-terminated */
41903
+ int nName /* Number of significant bytes in zName */
41904
+){
41905
+ assert( nName>0 );
41906
+ assert( zName!=0 );
41907
+ if( zName[0]=='.' ){
41908
+ if( nName==1 ) return;
41909
+ if( zName[1]=='.' && nName==2 ){
41910
+ if( pPath->nUsed<=1 ){
41911
+ pPath->rc = SQLITE_ERROR;
41912
+ return;
41913
+ }
41914
+ assert( pPath->zOut[0]=='/' );
41915
+ while( pPath->zOut[--pPath->nUsed]!='/' ){}
41916
+ return;
41917
+ }
41918
+ }
41919
+ if( pPath->nUsed + nName + 2 >= pPath->nOut ){
41920
+ pPath->rc = SQLITE_ERROR;
41921
+ return;
41922
+ }
41923
+ pPath->zOut[pPath->nUsed++] = '/';
41924
+ memcpy(&pPath->zOut[pPath->nUsed], zName, nName);
41925
+ pPath->nUsed += nName;
41926
+#if defined(HAVE_READLINK) && defined(HAVE_LSTAT)
41927
+ if( pPath->rc==SQLITE_OK ){
41928
+ const char *zIn;
41929
+ struct stat buf;
41930
+ pPath->zOut[pPath->nUsed] = 0;
41931
+ zIn = pPath->zOut;
41932
+ if( osLstat(zIn, &buf)!=0 ){
41933
+ if( errno!=ENOENT ){
41934
+ pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
41935
+ }
41936
+ }else if( S_ISLNK(buf.st_mode) ){
41937
+ ssize_t got;
41938
+ char zLnk[SQLITE_MAX_PATHLEN+2];
41939
+ if( pPath->nSymlink++ > SQLITE_MAX_SYMLINK ){
41940
+ pPath->rc = SQLITE_CANTOPEN_BKPT;
41941
+ return;
41942
+ }
41943
+ got = osReadlink(zIn, zLnk, sizeof(zLnk)-2);
41944
+ if( got<=0 || got>=(ssize_t)sizeof(zLnk)-2 ){
41945
+ pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
41946
+ return;
41947
+ }
41948
+ zLnk[got] = 0;
41949
+ if( zLnk[0]=='/' ){
41950
+ pPath->nUsed = 0;
41951
+ }else{
41952
+ pPath->nUsed -= nName + 1;
41953
+ }
41954
+ appendAllPathElements(pPath, zLnk);
41955
+ }
41956
+ }
41957
+#endif
41958
+}
41959
+
41960
+/*
41961
+** Append all path elements in zPath to the DbPath under construction.
41962
+*/
41963
+static void appendAllPathElements(
41964
+ DbPath *pPath, /* Path under construction, to which to append zName */
41965
+ const char *zPath /* Path to append to pPath. Is zero-terminated */
41966
+){
41967
+ int i = 0;
41968
+ int j = 0;
41969
+ do{
41970
+ while( zPath[i] && zPath[i]!='/' ){ i++; }
41971
+ if( i>j ){
41972
+ appendOnePathElement(pPath, &zPath[j], i-j);
41973
+ }
41974
+ j = i+1;
41975
+ }while( zPath[i++] );
4192241976
}
4192341977
4192441978
/*
4192541979
** Turn a relative pathname into a full pathname. The relative path
4192641980
** is stored as a nul-terminated string in the buffer pointed to by
@@ -41934,89 +41988,30 @@
4193441988
sqlite3_vfs *pVfs, /* Pointer to vfs object */
4193541989
const char *zPath, /* Possibly relative input path */
4193641990
int nOut, /* Size of output buffer in bytes */
4193741991
char *zOut /* Output buffer */
4193841992
){
41939
-#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
41940
- return mkFullPathname(zPath, zOut, nOut);
41941
-#else
41942
- int rc = SQLITE_OK;
41943
- int nByte;
41944
- int nLink = 0; /* Number of symbolic links followed so far */
41945
- const char *zIn = zPath; /* Input path for each iteration of loop */
41946
- char *zDel = 0;
41947
-
41948
- assert( pVfs->mxPathname==MAX_PATHNAME );
41993
+ DbPath path;
4194941994
UNUSED_PARAMETER(pVfs);
41950
-
41951
- /* It's odd to simulate an io-error here, but really this is just
41952
- ** using the io-error infrastructure to test that SQLite handles this
41953
- ** function failing. This function could fail if, for example, the
41954
- ** current working directory has been unlinked.
41955
- */
41956
- SimulateIOError( return SQLITE_ERROR );
41957
-
41958
- do {
41959
-
41960
- /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
41961
- ** link, or false otherwise. */
41962
- int bLink = 0;
41963
- struct stat buf;
41964
- if( osLstat(zIn, &buf)!=0 ){
41965
- if( errno!=ENOENT ){
41966
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
41967
- }
41968
- }else{
41969
- bLink = S_ISLNK(buf.st_mode);
41970
- }
41971
-
41972
- if( bLink ){
41973
- nLink++;
41974
- if( zDel==0 ){
41975
- zDel = sqlite3_malloc(nOut);
41976
- if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
41977
- }else if( nLink>=SQLITE_MAX_SYMLINKS ){
41978
- rc = SQLITE_CANTOPEN_BKPT;
41979
- }
41980
-
41981
- if( rc==SQLITE_OK ){
41982
- nByte = osReadlink(zIn, zDel, nOut-1);
41983
- if( nByte<0 ){
41984
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
41985
- }else{
41986
- if( zDel[0]!='/' ){
41987
- int n;
41988
- for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
41989
- if( nByte+n+1>nOut ){
41990
- rc = SQLITE_CANTOPEN_BKPT;
41991
- }else{
41992
- memmove(&zDel[n], zDel, nByte+1);
41993
- memcpy(zDel, zIn, n);
41994
- nByte += n;
41995
- }
41996
- }
41997
- zDel[nByte] = '\0';
41998
- }
41999
- }
42000
-
42001
- zIn = zDel;
42002
- }
42003
-
42004
- assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
42005
- if( rc==SQLITE_OK && zIn!=zOut ){
42006
- rc = mkFullPathname(zIn, zOut, nOut);
42007
- }
42008
- if( bLink==0 ) break;
42009
- zIn = zOut;
42010
- }while( rc==SQLITE_OK );
42011
-
42012
- sqlite3_free(zDel);
42013
- if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
42014
- return rc;
42015
-#endif /* HAVE_READLINK && HAVE_LSTAT */
42016
-}
42017
-
41995
+ path.rc = 0;
41996
+ path.nUsed = 0;
41997
+ path.nSymlink = 0;
41998
+ path.nOut = nOut;
41999
+ path.zOut = zOut;
42000
+ if( zPath[0]!='/' ){
42001
+ char zPwd[SQLITE_MAX_PATHLEN+2];
42002
+ if( osGetcwd(zPwd, sizeof(zPwd)-2)==0 ){
42003
+ return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
42004
+ }
42005
+ appendAllPathElements(&path, zPwd);
42006
+ }
42007
+ appendAllPathElements(&path, zPath);
42008
+ zOut[path.nUsed] = 0;
42009
+ if( path.rc || path.nUsed<2 ) return SQLITE_CANTOPEN_BKPT;
42010
+ if( path.nSymlink ) return SQLITE_OK_SYMLINK;
42011
+ return SQLITE_OK;
42012
+}
4201842013
4201942014
#ifndef SQLITE_OMIT_LOAD_EXTENSION
4202042015
/*
4202142016
** Interfaces for opening a shared library, finding entry points
4202242017
** within the shared library, and closing the shared library.
@@ -56473,10 +56468,11 @@
5647356468
}else if( (currentSize+szPage)<=newSize ){
5647456469
char *pTmp = pPager->pTmpSpace;
5647556470
memset(pTmp, 0, szPage);
5647656471
testcase( (newSize-szPage) == currentSize );
5647756472
testcase( (newSize-szPage) > currentSize );
56473
+ sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &newSize);
5647856474
rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
5647956475
}
5648056476
if( rc==SQLITE_OK ){
5648156477
pPager->dbFileSize = nPage;
5648256478
}
@@ -70725,16 +70721,21 @@
7072570721
eMode = BTALLOC_LE;
7072670722
iNear = nFin;
7072770723
}
7072870724
do {
7072970725
MemPage *pFreePg;
70726
+ Pgno dbSize = btreePagecount(pBt);
7073070727
rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
7073170728
if( rc!=SQLITE_OK ){
7073270729
releasePage(pLastPg);
7073370730
return rc;
7073470731
}
7073570732
releasePage(pFreePg);
70733
+ if( iFreePg>dbSize ){
70734
+ releasePage(pLastPg);
70735
+ return SQLITE_CORRUPT_BKPT;
70736
+ }
7073670737
}while( bCommit && iFreePg>nFin );
7073770738
assert( iFreePg<iLastPg );
7073870739
7073970740
rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, bCommit);
7074070741
releasePage(pLastPg);
@@ -75957,11 +75958,11 @@
7595775958
}
7595875959
7595975960
TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
7596075961
pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
7596175962
loc==0 ? "overwrite" : "new entry"));
75962
- assert( pPage->isInit );
75963
+ assert( pPage->isInit || CORRUPT_DB );
7596375964
newCell = pBt->pTmpSpace;
7596475965
assert( newCell!=0 );
7596575966
if( flags & BTREE_PREFORMAT ){
7596675967
rc = SQLITE_OK;
7596775968
szNew = pBt->nPreformatSize;
@@ -80239,12 +80240,12 @@
8023980240
assert( !ExprHasProperty(pExpr, EP_IntValue) );
8024080241
aff = sqlite3AffinityType(pExpr->u.zToken,0);
8024180242
rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
8024280243
testcase( rc!=SQLITE_OK );
8024380244
if( *ppVal ){
80244
- sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
80245
- sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
80245
+ sqlite3VdbeMemCast(*ppVal, aff, enc);
80246
+ sqlite3ValueApplyAffinity(*ppVal, affinity, enc);
8024680247
}
8024780248
return rc;
8024880249
}
8024980250
8025080251
/* Handle negative integers in a single step. This is needed in the
@@ -82215,15 +82216,13 @@
8221582216
if( c=='4' ){
8221682217
sqlite3_str_appendall(&x, zP4);
8221782218
}else if( c=='X' ){
8221882219
if( pOp->zComment && pOp->zComment[0] ){
8221982220
sqlite3_str_appendall(&x, pOp->zComment);
82220
- }else{
82221
- sqlite3_str_appendall(&x, zSynopsis+1);
82221
+ seenCom = 1;
82222
+ break;
8222282223
}
82223
- seenCom = 1;
82224
- break;
8222582224
}else{
8222682225
int v1 = translateP(c, pOp);
8222782226
int v2;
8222882227
if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
8222982228
ii += 3;
@@ -89770,14 +89769,19 @@
8977089769
pOut++;
8977189770
}while( --n );
8977289771
break;
8977389772
}
8977489773
89775
-/* Opcode: Copy P1 P2 P3 * *
89774
+/* Opcode: Copy P1 P2 P3 * P5
8977689775
** Synopsis: r[P2@P3+1]=r[P1@P3+1]
8977789776
**
8977889777
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
89778
+**
89779
+** If the 0x0002 bit of P5 is set then also clear the MEM_Subtype flag in the
89780
+** destination. The 0x0001 bit of P5 indicates that this Copy opcode cannot
89781
+** be merged. The 0x0001 bit is used by the query planner and does not
89782
+** come into play during query execution.
8977989783
**
8978089784
** This instruction makes a deep copy of the value. A duplicate
8978189785
** is made of any string or blob constant. See also OP_SCopy.
8978289786
*/
8978389787
case OP_Copy: {
@@ -89789,10 +89793,13 @@
8978989793
assert( pOut!=pIn1 );
8979089794
while( 1 ){
8979189795
memAboutToChange(p, pOut);
8979289796
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
8979389797
Deephemeralize(pOut);
89798
+ if( (pOut->flags & MEM_Subtype)!=0 && (pOp->p5 & 0x0002)!=0 ){
89799
+ pOut->flags &= ~MEM_Subtype;
89800
+ }
8979489801
#ifdef SQLITE_DEBUG
8979589802
pOut->pScopyFrom = 0;
8979689803
#endif
8979789804
REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
8979889805
if( (n--)==0 ) break;
@@ -92171,10 +92178,15 @@
9217192178
if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
9217292179
sqlite3ResetOneSchema(db, pOp->p1);
9217392180
}
9217492181
p->expired = 1;
9217592182
rc = SQLITE_SCHEMA;
92183
+
92184
+ /* Set changeCntOn to 0 to prevent the value returned by sqlite3_changes()
92185
+ ** from being modified in sqlite3VdbeHalt(). If this statement is
92186
+ ** reprepared, changeCntOn will be set again. */
92187
+ p->changeCntOn = 0;
9217692188
}
9217792189
if( rc ) goto abort_due_to_error;
9217892190
break;
9217992191
}
9218092192
@@ -92470,12 +92482,12 @@
9247092482
pCx->pKeyInfo = pOrig->pKeyInfo;
9247192483
pCx->isTable = pOrig->isTable;
9247292484
pCx->pgnoRoot = pOrig->pgnoRoot;
9247392485
pCx->isOrdered = pOrig->isOrdered;
9247492486
pCx->ub.pBtx = pOrig->ub.pBtx;
92475
- pCx->hasBeenDuped = 1;
92476
- pOrig->hasBeenDuped = 1;
92487
+ pCx->noReuse = 1;
92488
+ pOrig->noReuse = 1;
9247792489
rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR,
9247892490
pCx->pKeyInfo, pCx->uc.pCursor);
9247992491
/* The sqlite3BtreeCursor() routine can only fail for the first cursor
9248092492
** opened for a database. Since there is already an open cursor when this
9248192493
** opcode is run, the sqlite3BtreeCursor() cannot fail */
@@ -92538,11 +92550,11 @@
9253892550
assert( aMem[pOp->p3].flags & MEM_Null );
9253992551
aMem[pOp->p3].n = 0;
9254092552
aMem[pOp->p3].z = "";
9254192553
}
9254292554
pCx = p->apCsr[pOp->p1];
92543
- if( pCx && !pCx->hasBeenDuped && ALWAYS(pOp->p2<=pCx->nField) ){
92555
+ if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){
9254492556
/* If the ephermeral table is already open and has no duplicates from
9254592557
** OP_OpenDup, then erase all existing content so that the table is
9254692558
** empty again, rather than creating a new table. */
9254792559
assert( pCx->isEphemeral );
9254892560
pCx->seqCount = 0;
@@ -94125,10 +94137,11 @@
9412594137
** pseudo-cursor that always gives null rows. */
9412694138
pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO);
9412794139
if( pC==0 ) goto no_mem;
9412894140
pC->seekResult = 0;
9412994141
pC->isTable = 1;
94142
+ pC->noReuse = 1;
9413094143
pC->uc.pCursor = sqlite3BtreeFakeValidCursor();
9413194144
}
9413294145
pC->nullRow = 1;
9413394146
pC->cacheStatus = CACHE_STALE;
9413494147
if( pC->eCurType==CURTYPE_BTREE ){
@@ -96257,18 +96270,18 @@
9625796270
Mem *pDest;
9625896271
sqlite3_context sContext;
9625996272
9626096273
VdbeCursor *pCur = p->apCsr[pOp->p1];
9626196274
assert( pCur!=0 );
96262
- assert( pCur->eCurType==CURTYPE_VTAB );
9626396275
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
9626496276
pDest = &aMem[pOp->p3];
9626596277
memAboutToChange(p, pDest);
9626696278
if( pCur->nullRow ){
9626796279
sqlite3VdbeMemSetNull(pDest);
9626896280
break;
9626996281
}
96282
+ assert( pCur->eCurType==CURTYPE_VTAB );
9627096283
pVtab = pCur->uc.pVCur->pVtab;
9627196284
pModule = pVtab->pModule;
9627296285
assert( pModule->xColumn );
9627396286
memset(&sContext, 0, sizeof(sContext));
9627496287
sContext.pOut = pDest;
@@ -96591,10 +96604,21 @@
9659196604
9659296605
REGISTER_TRACE(pOp->p3, pOut);
9659396606
UPDATE_MAX_BLOBSIZE(pOut);
9659496607
break;
9659596608
}
96609
+
96610
+/* Opcode: ClrSubtype P1 * * * *
96611
+** Synopsis: r[P1].subtype = 0
96612
+**
96613
+** Clear the subtype from register P1.
96614
+*/
96615
+case OP_ClrSubtype: { /* in1 */
96616
+ pIn1 = &aMem[pOp->p1];
96617
+ pIn1->flags &= ~MEM_Subtype;
96618
+ break;
96619
+}
9659696620
9659796621
/* Opcode: FilterAdd P1 * P3 P4 *
9659896622
** Synopsis: filter(P1) += key(P3@P4)
9659996623
**
9660096624
** Compute a hash on the P4 registers starting with r[P3] and
@@ -102345,11 +102369,11 @@
102345102369
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
102346102370
anRef[i] = p->nRef;
102347102371
}
102348102372
sqlite3WalkExpr(pWalker, pExpr->pLeft);
102349102373
if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
102350
- testcase( ExprHasProperty(pExpr, EP_FromJoin) );
102374
+ testcase( ExprHasProperty(pExpr, EP_OuterON) );
102351102375
assert( !ExprHasProperty(pExpr, EP_IntValue) );
102352102376
if( pExpr->op==TK_NOTNULL ){
102353102377
pExpr->u.zToken = "true";
102354102378
ExprSetProperty(pExpr, EP_IsTrue);
102355102379
}else{
@@ -104636,10 +104660,11 @@
104636104660
pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
104637104661
if( pNew==0 ){
104638104662
sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
104639104663
return 0;
104640104664
}
104665
+ assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) );
104641104666
pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
104642104667
if( pList
104643104668
&& pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
104644104669
&& !pParse->nested
104645104670
){
@@ -104914,11 +104939,11 @@
104914104939
#endif
104915104940
){
104916104941
nSize = EXPR_FULLSIZE;
104917104942
}else{
104918104943
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
104919
- assert( !ExprHasProperty(p, EP_FromJoin) );
104944
+ assert( !ExprHasProperty(p, EP_OuterON) );
104920104945
assert( !ExprHasProperty(p, EP_MemToken) );
104921104946
assert( !ExprHasVVAProperty(p, EP_NoReduce) );
104922104947
if( p->pLeft || p->x.pList ){
104923104948
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
104924104949
}else{
@@ -105740,11 +105765,11 @@
105740105765
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
105741105766
105742105767
/* If pWalker->eCode is 2 then any term of the expression that comes from
105743105768
** the ON or USING clauses of an outer join disqualifies the expression
105744105769
** from being considered constant. */
105745
- if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
105770
+ if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){
105746105771
pWalker->eCode = 0;
105747105772
return WRC_Abort;
105748105773
}
105749105774
105750105775
switch( pExpr->op ){
@@ -105887,14 +105912,14 @@
105887105912
SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){
105888105913
if( pSrc->fg.jointype & JT_LTORJ ){
105889105914
return 0; /* rule (3) */
105890105915
}
105891105916
if( pSrc->fg.jointype & JT_LEFT ){
105892
- if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */
105917
+ if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */
105893105918
if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */
105894105919
}else{
105895
- if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */
105920
+ if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */
105896105921
}
105897105922
return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
105898105923
}
105899105924
105900105925
@@ -106312,15 +106337,11 @@
106312106337
int mustBeUnique; /* True if RHS must be unique */
106313106338
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
106314106339
106315106340
assert( pX->op==TK_IN );
106316106341
mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
106317
- if( pX->iTable && (inFlags & IN_INDEX_REUSE_CUR)!=0 ){
106318
- iTab = pX->iTable;
106319
- }else{
106320
- iTab = pParse->nTab++;
106321
- }
106342
+ iTab = pParse->nTab++;
106322106343
106323106344
/* If the RHS of this IN(...) operator is a SELECT, and if it matters
106324106345
** whether or not the SELECT result contains NULL values, check whether
106325106346
** or not NULL is actually possible (it may not be, for example, due
106326106347
** to NOT NULL constraints in the schema). If no NULL values are possible,
@@ -106650,13 +106671,12 @@
106650106671
pExpr->x.pSelect->selId));
106651106672
}
106652106673
assert( ExprUseYSub(pExpr) );
106653106674
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
106654106675
pExpr->y.sub.iAddr);
106655
- if( iTab!=pExpr->iTable ){
106656
- sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
106657
- }
106676
+ assert( iTab!=pExpr->iTable );
106677
+ sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
106658106678
sqlite3VdbeJumpHere(v, addrOnce);
106659106679
return;
106660106680
}
106661106681
106662106682
/* Begin coding the subroutine */
@@ -107526,11 +107546,21 @@
107526107546
memset(&caseExpr, 0, sizeof(caseExpr));
107527107547
caseExpr.op = TK_CASE;
107528107548
caseExpr.x.pList = pFarg;
107529107549
return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
107530107550
}
107531
-
107551
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
107552
+ case INLINEFUNC_sqlite_offset: {
107553
+ Expr *pArg = pFarg->a[0].pExpr;
107554
+ if( pArg->op==TK_COLUMN && pArg->iTable>=0 ){
107555
+ sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
107556
+ }else{
107557
+ sqlite3VdbeAddOp2(v, OP_Null, 0, target);
107558
+ }
107559
+ break;
107560
+ }
107561
+#endif
107532107562
default: {
107533107563
/* The UNLIKELY() function is a no-op. The result is the value
107534107564
** of the first argument.
107535107565
*/
107536107566
assert( nFarg==1 || nFarg==2 );
@@ -108065,24 +108095,12 @@
108065108095
#endif
108066108096
if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
108067108097
if( !pColl ) pColl = db->pDfltColl;
108068108098
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
108069108099
}
108070
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
108071
- if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){
108072
- Expr *pArg = pFarg->a[0].pExpr;
108073
- if( pArg->op==TK_COLUMN ){
108074
- sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
108075
- }else{
108076
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
108077
- }
108078
- }else
108079
-#endif
108080
- {
108081
- sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
108082
- pDef, pExpr->op2);
108083
- }
108100
+ sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
108101
+ pDef, pExpr->op2);
108084108102
if( nFarg ){
108085108103
if( constMask==0 ){
108086108104
sqlite3ReleaseTempRange(pParse, r1, nFarg);
108087108105
}else{
108088108106
sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
@@ -108149,13 +108167,29 @@
108149108167
** Z is stored in pExpr->pList->a[1].pExpr.
108150108168
*/
108151108169
case TK_BETWEEN: {
108152108170
exprCodeBetween(pParse, pExpr, target, 0, 0);
108153108171
return target;
108172
+ }
108173
+ case TK_COLLATE: {
108174
+ if( !ExprHasProperty(pExpr, EP_Collate)
108175
+ && ALWAYS(pExpr->pLeft)
108176
+ && pExpr->pLeft->op==TK_FUNCTION
108177
+ ){
108178
+ inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
108179
+ if( inReg!=target ){
108180
+ sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
108181
+ inReg = target;
108182
+ }
108183
+ sqlite3VdbeAddOp1(v, OP_ClrSubtype, inReg);
108184
+ return inReg;
108185
+ }else{
108186
+ pExpr = pExpr->pLeft;
108187
+ goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */
108188
+ }
108154108189
}
108155108190
case TK_SPAN:
108156
- case TK_COLLATE:
108157108191
case TK_UPLUS: {
108158108192
pExpr = pExpr->pLeft;
108159108193
goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */
108160108194
}
108161108195
@@ -108645,12 +108679,12 @@
108645108679
}else{
108646108680
/* Mark the expression is being from the ON or USING clause of a join
108647108681
** so that the sqlite3ExprCodeTarget() routine will not attempt to move
108648108682
** it into the Parse.pConstExpr list. We should use a new bit for this,
108649108683
** for clarity, but we are out of bits in the Expr.flags field so we
108650
- ** have to reuse the EP_FromJoin bit. Bummer. */
108651
- pDel->flags |= EP_FromJoin;
108684
+ ** have to reuse the EP_OuterON bit. Bummer. */
108685
+ pDel->flags |= EP_OuterON;
108652108686
sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
108653108687
}
108654108688
sqlite3ReleaseTempReg(pParse, regFree1);
108655108689
}
108656108690
sqlite3ExprDelete(db, pDel);
@@ -109331,11 +109365,11 @@
109331109365
** (never setting pWalker->eCode) is a harmless missed optimization.
109332109366
*/
109333109367
static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
109334109368
testcase( pExpr->op==TK_AGG_COLUMN );
109335109369
testcase( pExpr->op==TK_AGG_FUNCTION );
109336
- if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
109370
+ if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune;
109337109371
switch( pExpr->op ){
109338109372
case TK_ISNOT:
109339109373
case TK_ISNULL:
109340109374
case TK_NOTNULL:
109341109375
case TK_IS:
@@ -109428,11 +109462,11 @@
109428109462
** is NULL. A false negative is merely a missed optimization opportunity.
109429109463
**
109430109464
** False positives are not allowed, however. A false positive may result
109431109465
** in an incorrect answer.
109432109466
**
109433
-** Terms of p that are marked with EP_FromJoin (and hence that come from
109467
+** Terms of p that are marked with EP_OuterON (and hence that come from
109434109468
** the ON or USING clauses of OUTER JOINS) are excluded from the analysis.
109435109469
**
109436109470
** This routine is used to check if a LEFT JOIN can be converted into
109437109471
** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
109438109472
** clause requires that some column of the right table of the LEFT JOIN
@@ -111302,31 +111336,37 @@
111302111336
if( pParse->nErr ) rc = pParse->rc;
111303111337
}
111304111338
if( rc==SQLITE_OK && pStep->zTarget ){
111305111339
SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep);
111306111340
if( pSrc ){
111307
- int i;
111308
- for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){
111309
- SrcItem *p = &pSrc->a[i];
111310
- p->iCursor = pParse->nTab++;
111311
- if( p->pSelect ){
111312
- sqlite3SelectPrep(pParse, p->pSelect, 0);
111313
- sqlite3ExpandSubquery(pParse, p);
111314
- assert( i>0 );
111315
- assert( pStep->pFrom->a[i-1].pSelect );
111316
- sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0);
111317
- }else{
111318
- p->pTab = sqlite3LocateTableItem(pParse, 0, p);
111319
- if( p->pTab==0 ){
111320
- rc = SQLITE_ERROR;
111321
- }else{
111322
- p->pTab->nTabRef++;
111323
- rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
111341
+ Select *pSel = sqlite3SelectNew(
111342
+ pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0
111343
+ );
111344
+ if( pSel==0 ){
111345
+ pStep->pExprList = 0;
111346
+ pSrc = 0;
111347
+ rc = SQLITE_NOMEM;
111348
+ }else{
111349
+ sqlite3SelectPrep(pParse, pSel, 0);
111350
+ rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
111351
+ assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList );
111352
+ assert( pSrc==pSel->pSrc );
111353
+ if( pStep->pExprList ) pSel->pEList = 0;
111354
+ pSel->pSrc = 0;
111355
+ sqlite3SelectDelete(db, pSel);
111356
+ }
111357
+ if( pStep->pFrom ){
111358
+ int i;
111359
+ for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){
111360
+ SrcItem *p = &pStep->pFrom->a[i];
111361
+ if( p->pSelect ){
111362
+ sqlite3SelectPrep(pParse, p->pSelect, 0);
111324111363
}
111325111364
}
111326111365
}
111327
- if( rc==SQLITE_OK && db->mallocFailed ){
111366
+
111367
+ if( db->mallocFailed ){
111328111368
rc = SQLITE_NOMEM;
111329111369
}
111330111370
sNC.pSrcList = pSrc;
111331111371
if( rc==SQLITE_OK && pStep->pWhere ){
111332111372
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
@@ -111773,10 +111813,19 @@
111773111813
if( rc==SQLITE_OK ){
111774111814
renameWalkTrigger(&sWalker, pTrigger);
111775111815
for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
111776111816
if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
111777111817
renameTokenFind(&sParse, &sCtx, pStep->zTarget);
111818
+ }
111819
+ if( pStep->pFrom ){
111820
+ int i;
111821
+ for(i=0; i<pStep->pFrom->nSrc; i++){
111822
+ SrcItem *pItem = &pStep->pFrom->a[i];
111823
+ if( 0==sqlite3_stricmp(pItem->zName, zOld) ){
111824
+ renameTokenFind(&sParse, &sCtx, pItem->zName);
111825
+ }
111826
+ }
111778111827
}
111779111828
}
111780111829
}
111781111830
}
111782111831
}
@@ -124372,15 +124421,15 @@
124372124421
}else{
124373124422
ans = log(x);
124374124423
switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){
124375124424
case 1:
124376124425
/* Convert from natural logarithm to log base 10 */
124377
- ans *= 1.0/M_LN10;
124426
+ ans /= M_LN10;
124378124427
break;
124379124428
case 2:
124380124429
/* Convert from natural logarithm to log base 2 */
124381
- ans *= 1.0/M_LN2;
124430
+ ans /= M_LN2;
124382124431
break;
124383124432
default:
124384124433
break;
124385124434
}
124386124435
}
@@ -124515,12 +124564,11 @@
124515124564
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
124516124565
INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124517124566
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124518124567
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124519124568
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
124520
- {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
124521
- 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
124569
+ INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
124522124570
#endif
124523124571
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
124524124572
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
124525124573
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
124526124574
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -129800,10 +129848,11 @@
129800129848
/* Version 3.39.0 and later */
129801129849
int (*deserialize)(sqlite3*,const char*,unsigned char*,
129802129850
sqlite3_int64,sqlite3_int64,unsigned);
129803129851
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
129804129852
unsigned int);
129853
+ const char *(*db_name)(sqlite3*,int);
129805129854
};
129806129855
129807129856
/*
129808129857
** This is the function signature used for all extension entry points. It
129809129858
** is also defined in the file "loadext.c".
@@ -130118,14 +130167,16 @@
130118130167
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
130119130168
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
130120130169
#define sqlite3_vtab_in sqlite3_api->vtab_in
130121130170
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
130122130171
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
130172
+/* Version 3.39.0 and later */
130123130173
#ifndef SQLITE_OMIT_DESERIALIZE
130124130174
#define sqlite3_deserialize sqlite3_api->deserialize
130125130175
#define sqlite3_serialize sqlite3_api->serialize
130126130176
#endif
130177
+#define sqlite3_db_name sqlite3_api->db_name
130127130178
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
130128130179
130129130180
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
130130130181
/* This case when the file really is being compiled as a loadable
130131130182
** extension */
@@ -130629,15 +130680,16 @@
130629130680
0,
130630130681
#endif
130631130682
/* Version 3.39.0 and later */
130632130683
#ifndef SQLITE_OMIT_DESERIALIZE
130633130684
sqlite3_deserialize,
130634
- sqlite3_serialize
130685
+ sqlite3_serialize,
130635130686
#else
130687
+ 0,
130636130688
0,
130637
- 0
130638130689
#endif
130690
+ sqlite3_db_name
130639130691
};
130640130692
130641130693
/* True if x is the directory separator character
130642130694
*/
130643130695
#if SQLITE_OS_WIN
@@ -135849,15 +135901,15 @@
135849135901
}
135850135902
return 0;
135851135903
}
135852135904
135853135905
/*
135854
-** Set the EP_FromJoin property on all terms of the given expression.
135906
+** Set the EP_OuterON property on all terms of the given expression.
135855135907
** And set the Expr.w.iJoin to iTable for every term in the
135856135908
** expression.
135857135909
**
135858
-** The EP_FromJoin property is used on terms of an expression to tell
135910
+** The EP_OuterON property is used on terms of an expression to tell
135859135911
** the OUTER JOIN processing logic that this term is part of the
135860135912
** join restriction specified in the ON or USING clause and not a part
135861135913
** of the more general WHERE clause. These terms are moved over to the
135862135914
** WHERE clause during join processing but we need to remember that they
135863135915
** originated in the ON or USING clause.
@@ -135875,11 +135927,11 @@
135875135927
** defer the handling of t1.x=5, it will be processed immediately
135876135928
** after the t1 loop and rows with t1.x!=5 will never appear in
135877135929
** the output, which is incorrect.
135878135930
*/
135879135931
SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){
135880
- assert( joinFlag==EP_FromJoin || joinFlag==EP_InnerJoin );
135932
+ assert( joinFlag==EP_OuterON || joinFlag==EP_InnerON );
135881135933
while( p ){
135882135934
ExprSetProperty(p, joinFlag);
135883135935
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
135884135936
ExprSetVVAProperty(p, EP_NoReduce);
135885135937
p->w.iJoin = iTable;
@@ -135896,35 +135948,41 @@
135896135948
p = p->pRight;
135897135949
}
135898135950
}
135899135951
135900135952
/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
135901
-** term that is marked with EP_FromJoin and w.iJoin==iTable into
135902
-** an ordinary term that omits the EP_FromJoin mark.
135953
+** term that is marked with EP_OuterON and w.iJoin==iTable into
135954
+** an ordinary term that omits the EP_OuterON mark.
135903135955
**
135904135956
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
135957
+**
135958
+** If nullable is true, that means that Expr p might evaluate to NULL even
135959
+** if it is a reference to a NOT NULL column. This can happen, for example,
135960
+** if the table that p references is on the left side of a RIGHT JOIN.
135961
+** If nullable is true, then take care to not remove the EP_CanBeNull bit.
135962
+** See forum thread https://sqlite.org/forum/forumpost/b40696f50145d21c
135905135963
*/
135906
-static void unsetJoinExpr(Expr *p, int iTable){
135964
+static void unsetJoinExpr(Expr *p, int iTable, int nullable){
135907135965
while( p ){
135908
- if( ExprHasProperty(p, EP_FromJoin)
135966
+ if( ExprHasProperty(p, EP_OuterON)
135909135967
&& (iTable<0 || p->w.iJoin==iTable) ){
135910
- ExprClearProperty(p, EP_FromJoin);
135911
- ExprSetProperty(p, EP_InnerJoin);
135968
+ ExprClearProperty(p, EP_OuterON);
135969
+ ExprSetProperty(p, EP_InnerON);
135912135970
}
135913
- if( p->op==TK_COLUMN && p->iTable==iTable ){
135971
+ if( p->op==TK_COLUMN && p->iTable==iTable && !nullable ){
135914135972
ExprClearProperty(p, EP_CanBeNull);
135915135973
}
135916135974
if( p->op==TK_FUNCTION ){
135917135975
assert( ExprUseXList(p) );
135918135976
if( p->x.pList ){
135919135977
int i;
135920135978
for(i=0; i<p->x.pList->nExpr; i++){
135921
- unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
135979
+ unsetJoinExpr(p->x.pList->a[i].pExpr, iTable, nullable);
135922135980
}
135923135981
}
135924135982
}
135925
- unsetJoinExpr(p->pLeft, iTable);
135983
+ unsetJoinExpr(p->pLeft, iTable, nullable);
135926135984
p = p->pRight;
135927135985
}
135928135986
}
135929135987
135930135988
/*
@@ -135934,12 +135992,12 @@
135934135992
** do not need to be concerned with NATURAL joins and we only have
135935135993
** think about USING joins.
135936135994
**
135937135995
** * ON and USING clauses result in extra terms being added to the
135938135996
** WHERE clause to enforce the specified constraints. The extra
135939
-** WHERE clause terms will be tagged with EP_FromJoin or
135940
-** EP_InnerJoin so that we know that they originated in ON/USING.
135997
+** WHERE clause terms will be tagged with EP_OuterON or
135998
+** EP_InnerON so that we know that they originated in ON/USING.
135941135999
**
135942136000
** The terms of a FROM clause are contained in the Select.pSrc structure.
135943136001
** The left most table is the first entry in Select.pSrc. The right-most
135944136002
** table is the last entry. The join operator is held in the entry to
135945136003
** the right. Thus entry 1 contains the join operator for the join between
@@ -135960,11 +136018,11 @@
135960136018
for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
135961136019
Table *pRightTab = pRight->pTab;
135962136020
u32 joinType;
135963136021
135964136022
if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
135965
- joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_FromJoin : EP_InnerJoin;
136023
+ joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON;
135966136024
135967136025
/* If this is a NATURAL join, synthesize an approprate USING clause
135968136026
** to specify which columns should be joined.
135969136027
*/
135970136028
if( pRight->fg.jointype & JT_NATURAL ){
@@ -136081,10 +136139,11 @@
136081136139
*/
136082136140
else if( pRight->u3.pOn ){
136083136141
sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
136084136142
p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
136085136143
pRight->u3.pOn = 0;
136144
+ pRight->fg.isOn = 1;
136086136145
}
136087136146
}
136088136147
return 0;
136089136148
}
136090136149
@@ -137664,14 +137723,15 @@
137664137723
pColExpr = pColExpr->pRight;
137665137724
assert( pColExpr!=0 );
137666137725
}
137667137726
if( pColExpr->op==TK_COLUMN
137668137727
&& ALWAYS( ExprUseYTab(pColExpr) )
137669
- && (pTab = pColExpr->y.pTab)!=0
137728
+ && ALWAYS( pColExpr->y.pTab!=0 )
137670137729
){
137671137730
/* For columns use the column name name */
137672137731
int iCol = pColExpr->iColumn;
137732
+ pTab = pColExpr->y.pTab;
137673137733
if( iCol<0 ) iCol = pTab->iPKey;
137674137734
zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
137675137735
}else if( pColExpr->op==TK_ID ){
137676137736
assert( !ExprHasProperty(pColExpr, EP_IntValue) );
137677137737
zName = pColExpr->u.zToken;
@@ -139233,13 +139293,14 @@
139233139293
static Expr *substExpr(
139234139294
SubstContext *pSubst, /* Description of the substitution */
139235139295
Expr *pExpr /* Expr in which substitution occurs */
139236139296
){
139237139297
if( pExpr==0 ) return 0;
139238
- if( ExprHasProperty(pExpr, EP_FromJoin)
139298
+ if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON)
139239139299
&& pExpr->w.iJoin==pSubst->iTable
139240139300
){
139301
+ testcase( ExprHasProperty(pExpr, EP_InnerON) );
139241139302
pExpr->w.iJoin = pSubst->iNewTable;
139242139303
}
139243139304
if( pExpr->op==TK_COLUMN
139244139305
&& pExpr->iTable==pSubst->iTable
139245139306
&& !ExprHasProperty(pExpr, EP_FixedCol)
@@ -139274,16 +139335,21 @@
139274139335
return pExpr;
139275139336
}
139276139337
if( pSubst->isOuterJoin ){
139277139338
ExprSetProperty(pNew, EP_CanBeNull);
139278139339
}
139279
- if( ExprHasProperty(pExpr,EP_FromJoin|EP_InnerJoin) ){
139340
+ if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
139280139341
sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
139281
- pExpr->flags & (EP_FromJoin|EP_InnerJoin));
139342
+ pExpr->flags & (EP_OuterON|EP_InnerON));
139282139343
}
139283139344
sqlite3ExprDelete(db, pExpr);
139284139345
pExpr = pNew;
139346
+ if( pExpr->op==TK_TRUEFALSE ){
139347
+ pExpr->u.iValue = sqlite3ExprTruthValue(pExpr);
139348
+ pExpr->op = TK_INTEGER;
139349
+ ExprSetProperty(pExpr, EP_IntValue);
139350
+ }
139285139351
139286139352
/* Ensure that the expression now has an implicit collation sequence,
139287139353
** just as it did when it was a column of a view or sub-query. */
139288139354
if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){
139289139355
CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
@@ -139440,11 +139506,11 @@
139440139506
static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){
139441139507
int op = pExpr->op;
139442139508
if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
139443139509
renumberCursorDoMapping(pWalker, &pExpr->iTable);
139444139510
}
139445
- if( ExprHasProperty(pExpr, EP_FromJoin) ){
139511
+ if( ExprHasProperty(pExpr, EP_OuterON) ){
139446139512
renumberCursorDoMapping(pWalker, &pExpr->w.iJoin);
139447139513
}
139448139514
return WRC_Continue;
139449139515
}
139450139516
@@ -139633,10 +139699,15 @@
139633139699
** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
139634139700
** is the first element of the parent query.
139635139701
**
139636139702
** (28) The subquery is not a MATERIALIZED CTE.
139637139703
**
139704
+** (29) Either the subquery is not the right-hand operand of a join with an
139705
+** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or
139706
+** the right-most table within the FROM clause of the subquery
139707
+** is not part of an outer join.
139708
+**
139638139709
**
139639139710
** In this routine, the "p" parameter is a pointer to the outer query.
139640139711
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
139641139712
** uses aggregates.
139642139713
**
@@ -139759,10 +139830,39 @@
139759139830
return 0; /* Restriction (27) */
139760139831
}
139761139832
if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
139762139833
return 0; /* (28) */
139763139834
}
139835
+
139836
+ /* Restriction (29):
139837
+ **
139838
+ ** We do not want two constraints on the same term of the flattened
139839
+ ** query where one constraint has EP_InnerON and the other is EP_OuterON.
139840
+ ** To prevent this, one or the other of the following conditions must be
139841
+ ** false:
139842
+ **
139843
+ ** (29a) The right-most entry in the FROM clause of the subquery
139844
+ ** must not be part of an outer join.
139845
+ **
139846
+ ** (29b) The subquery itself must not be the right operand of a
139847
+ ** NATURAL join or a join that as an ON or USING clause.
139848
+ **
139849
+ ** These conditions are sufficient to keep an EP_OuterON from being
139850
+ ** flattened into an EP_InnerON. Restrictions (3a) and (27) prevent
139851
+ ** an EP_InnerON from being flattened into an EP_OuterON.
139852
+ */
139853
+ if( pSubSrc->nSrc>=2
139854
+ && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0
139855
+ ){
139856
+ if( (pSubitem->fg.jointype & JT_NATURAL)!=0
139857
+ || pSubitem->fg.isUsing
139858
+ || NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */
139859
+ || pSubitem->fg.isOn
139860
+ ){
139861
+ return 0;
139862
+ }
139863
+ }
139764139864
139765139865
/* Restriction (17): If the sub-query is a compound SELECT, then it must
139766139866
** use only the UNION ALL operator. And none of the simple select queries
139767139867
** that make up the compound SELECT are allowed to be aggregate or distinct
139768139868
** queries.
@@ -140018,11 +140118,11 @@
140018140118
pSub->pOrderBy = 0;
140019140119
}
140020140120
pWhere = pSub->pWhere;
140021140121
pSub->pWhere = 0;
140022140122
if( isOuterJoin>0 ){
140023
- sqlite3SetJoinExpr(pWhere, iNewParent, EP_FromJoin);
140123
+ sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON);
140024140124
}
140025140125
if( pWhere ){
140026140126
if( pParent->pWhere ){
140027140127
pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
140028140128
}else{
@@ -140151,11 +140251,15 @@
140151140251
** found, add it to the pConst structure.
140152140252
*/
140153140253
static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
140154140254
Expr *pRight, *pLeft;
140155140255
if( NEVER(pExpr==0) ) return;
140156
- if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
140256
+ if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){
140257
+ testcase( ExprHasProperty(pExpr, EP_OuterON) );
140258
+ testcase( ExprHasProperty(pExpr, EP_InnerON) );
140259
+ return;
140260
+ }
140157140261
if( pExpr->op==TK_AND ){
140158140262
findConstInWhere(pConst, pExpr->pRight);
140159140263
findConstInWhere(pConst, pExpr->pLeft);
140160140264
return;
140161140265
}
@@ -140187,13 +140291,13 @@
140187140291
int bIgnoreAffBlob
140188140292
){
140189140293
int i;
140190140294
if( pConst->pOomFault[0] ) return WRC_Prune;
140191140295
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
140192
- if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
140296
+ if( ExprHasProperty(pExpr, EP_FixedCol|EP_OuterON) ){
140193140297
testcase( ExprHasProperty(pExpr, EP_FixedCol) );
140194
- testcase( ExprHasProperty(pExpr, EP_FromJoin) );
140298
+ testcase( ExprHasProperty(pExpr, EP_OuterON) );
140195140299
return WRC_Continue;
140196140300
}
140197140301
for(i=0; i<pConst->nConst; i++){
140198140302
Expr *pColumn = pConst->apExpr[i*2];
140199140303
if( pColumn==pExpr ) continue;
@@ -140474,16 +140578,16 @@
140474140578
pWhere = pWhere->pLeft;
140475140579
}
140476140580
140477140581
#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */
140478140582
if( isLeftJoin
140479
- && (ExprHasProperty(pWhere,EP_FromJoin)==0
140583
+ && (ExprHasProperty(pWhere,EP_OuterON)==0
140480140584
|| pWhere->w.iJoin!=iCursor)
140481140585
){
140482140586
return 0; /* restriction (4) */
140483140587
}
140484
- if( ExprHasProperty(pWhere,EP_FromJoin)
140588
+ if( ExprHasProperty(pWhere,EP_OuterON)
140485140589
&& pWhere->w.iJoin!=iCursor
140486140590
){
140487140591
return 0; /* restriction (5) */
140488140592
}
140489140593
#endif
@@ -140492,11 +140596,11 @@
140492140596
nChng++;
140493140597
pSubq->selFlags |= SF_PushDown;
140494140598
while( pSubq ){
140495140599
SubstContext x;
140496140600
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
140497
- unsetJoinExpr(pNew, -1);
140601
+ unsetJoinExpr(pNew, -1, 1);
140498140602
x.pParse = pParse;
140499140603
x.iTable = pSrc->iCursor;
140500140604
x.iNewTable = pSrc->iCursor;
140501140605
x.isOuterJoin = 0;
140502140606
x.pEList = pSubq->pEList;
@@ -141988,10 +142092,33 @@
141988142092
}
141989142093
#endif
141990142094
return 1;
141991142095
}
141992142096
#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
142097
+
142098
+/*
142099
+** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same
142100
+** as pSrcItem but has the same alias as p0, then return true.
142101
+** Otherwise return false.
142102
+*/
142103
+static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
142104
+ int i;
142105
+ for(i=0; i<pSrc->nSrc; i++){
142106
+ SrcItem *p1 = &pSrc->a[i];
142107
+ if( p1==p0 ) continue;
142108
+ if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
142109
+ return 1;
142110
+ }
142111
+ if( p1->pSelect
142112
+ && (p1->pSelect->selFlags & SF_NestedFrom)!=0
142113
+ && sameSrcAlias(p0, p1->pSelect->pSrc)
142114
+ ){
142115
+ return 1;
142116
+ }
142117
+ }
142118
+ return 0;
142119
+}
141993142120
141994142121
/*
141995142122
** Generate code for the SELECT statement given in the p argument.
141996142123
**
141997142124
** The results are returned according to the SelectDest structure.
@@ -142093,19 +142220,16 @@
142093142220
** systems handle this case differently, and not all the same way,
142094142221
** which is just confusing. To avoid this, we follow PG's lead and
142095142222
** disallow it altogether. */
142096142223
if( p->selFlags & SF_UFSrcCheck ){
142097142224
SrcItem *p0 = &p->pSrc->a[0];
142098
- for(i=1; i<p->pSrc->nSrc; i++){
142099
- SrcItem *p1 = &p->pSrc->a[i];
142100
- if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
142101
- sqlite3ErrorMsg(pParse,
142102
- "target object/alias may not appear in FROM clause: %s",
142103
- p0->zAlias ? p0->zAlias : p0->pTab->zName
142104
- );
142105
- goto select_end;
142106
- }
142225
+ if( sameSrcAlias(p0, p->pSrc) ){
142226
+ sqlite3ErrorMsg(pParse,
142227
+ "target object/alias may not appear in FROM clause: %s",
142228
+ p0->zAlias ? p0->zAlias : p0->pTab->zName
142229
+ );
142230
+ goto select_end;
142107142231
}
142108142232
142109142233
/* Clear the SF_UFSrcCheck flag. The check has already been performed,
142110142234
** and leaving this flag set can cause errors if a compound sub-query
142111142235
** in p->pSrc is flattened into this query and this function called
@@ -142156,11 +142280,12 @@
142156142280
&& OptimizationEnabled(db, SQLITE_SimplifyJoin)
142157142281
){
142158142282
SELECTTRACE(0x100,pParse,p,
142159142283
("LEFT-JOIN simplifies to JOIN on term %d\n",i));
142160142284
pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
142161
- unsetJoinExpr(p->pWhere, pItem->iCursor);
142285
+ unsetJoinExpr(p->pWhere, pItem->iCursor,
142286
+ pTabList->a[0].fg.jointype & JT_LTORJ);
142162142287
}
142163142288
142164142289
/* No futher action if this term of the FROM clause is no a subquery */
142165142290
if( pSub==0 ) continue;
142166142291
@@ -142376,11 +142501,11 @@
142376142501
zSavedAuthContext = pParse->zAuthContext;
142377142502
pParse->zAuthContext = pItem->zName;
142378142503
142379142504
/* Generate code to implement the subquery
142380142505
**
142381
- ** The subquery is implemented as a co-routine all of the following are
142506
+ ** The subquery is implemented as a co-routine all if the following are
142382142507
** true:
142383142508
**
142384142509
** (1) the subquery is guaranteed to be the outer loop (so that
142385142510
** it does not need to be computed more than once), and
142386142511
** (2) the subquery is not a CTE that should be materialized
@@ -142434,15 +142559,15 @@
142434142559
/* Materialize the view. If the view is not correlated, generate a
142435142560
** subroutine to do the materialization so that subsequent uses of
142436142561
** the same view can reuse the materialization. */
142437142562
int topAddr;
142438142563
int onceAddr = 0;
142439
- int retAddr;
142440142564
142441142565
pItem->regReturn = ++pParse->nMem;
142442
- topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
142566
+ topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
142443142567
pItem->addrFillSub = topAddr+1;
142568
+ pItem->fg.isMaterialized = 1;
142444142569
if( pItem->fg.isCorrelated==0 ){
142445142570
/* If the subquery is not correlated and if we are not inside of
142446142571
** a trigger, then we only need to compute the value of the subquery
142447142572
** once. */
142448142573
onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
@@ -142453,13 +142578,13 @@
142453142578
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
142454142579
ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem));
142455142580
sqlite3Select(pParse, pSub, &dest);
142456142581
pItem->pTab->nRowLogEst = pSub->nSelectRow;
142457142582
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
142458
- retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
142583
+ sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
142459142584
VdbeComment((v, "end %!S", pItem));
142460
- sqlite3VdbeChangeP1(v, topAddr, retAddr);
142585
+ sqlite3VdbeJumpHere(v, topAddr);
142461142586
sqlite3ClearTempRegCache(pParse);
142462142587
if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
142463142588
CteUse *pCteUse = pItem->u2.pCteUse;
142464142589
pCteUse->addrM9e = pItem->addrFillSub;
142465142590
pCteUse->regRtn = pItem->regReturn;
@@ -143178,11 +143303,11 @@
143178143303
}
143179143304
SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
143180143305
eDist = sqlite3WhereIsDistinct(pWInfo);
143181143306
updateAccumulator(pParse, regAcc, pAggInfo, eDist);
143182143307
if( eDist!=WHERE_DISTINCT_NOOP ){
143183
- struct AggInfo_func *pF = &pAggInfo->aFunc[0];
143308
+ struct AggInfo_func *pF = pAggInfo->aFunc;
143184143309
if( pF ){
143185143310
fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
143186143311
}
143187143312
}
143188143313
@@ -143977,11 +144102,11 @@
143977144102
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
143978144103
*/
143979144104
SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
143980144105
Parse *pParse, /* Parser */
143981144106
Token *pTableName, /* Name of the table to be updated */
143982
- SrcList *pFrom,
144107
+ SrcList *pFrom, /* FROM clause for an UPDATE-FROM, or NULL */
143983144108
ExprList *pEList, /* The SET clause: list of column and new values */
143984144109
Expr *pWhere, /* The WHERE clause */
143985144110
u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
143986144111
const char *zStart, /* Start of SQL text */
143987144112
const char *zEnd /* End of SQL text */
@@ -144313,10 +144438,18 @@
144313144438
if( pSchema!=db->aDb[1].pSchema ){
144314144439
pSrc->a[0].pSchema = pSchema;
144315144440
}
144316144441
if( pStep->pFrom ){
144317144442
SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
144443
+ if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){
144444
+ Select *pSubquery;
144445
+ Token as;
144446
+ pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0);
144447
+ as.n = 0;
144448
+ as.z = 0;
144449
+ pDup = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
144450
+ }
144318144451
pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup);
144319144452
}
144320144453
}else{
144321144454
sqlite3DbFree(db, zName);
144322144455
}
@@ -145944,11 +146077,11 @@
145944146077
if( pPk ){
145945146078
sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
145946146079
}else{
145947146080
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
145948146081
}
145949
- VdbeCoverageNeverTaken(v);
146082
+ VdbeCoverage(v);
145950146083
}
145951146084
145952146085
/* Do FK constraint checks. */
145953146086
if( hasFK ){
145954146087
sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
@@ -148402,11 +148535,11 @@
148402148535
** This object is a header on a block of allocated memory that will be
148403148536
** automatically freed when its WInfo oject is destructed.
148404148537
*/
148405148538
struct WhereMemBlock {
148406148539
WhereMemBlock *pNext; /* Next block in the chain */
148407
- u8 sz; /* Bytes of space */
148540
+ u64 sz; /* Bytes of space */
148408148541
};
148409148542
148410148543
/*
148411148544
** Extra information attached to a WhereLevel that is a RIGHT JOIN.
148412148545
*/
@@ -148973,12 +149106,13 @@
148973149106
#define WO_ISNULL 0x0100
148974149107
#define WO_OR 0x0200 /* Two or more OR-connected terms */
148975149108
#define WO_AND 0x0400 /* Two or more AND-connected terms */
148976149109
#define WO_EQUIV 0x0800 /* Of the form A==B, both columns */
148977149110
#define WO_NOOP 0x1000 /* This term does not restrict search space */
149111
+#define WO_ROWVAL 0x2000 /* A row-value term */
148978149112
148979
-#define WO_ALL 0x1fff /* Mask of all possible WO_* values */
149113
+#define WO_ALL 0x3fff /* Mask of all possible WO_* values */
148980149114
#define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */
148981149115
148982149116
/*
148983149117
** These are definitions of bits in the WhereLoop.wsFlags field.
148984149118
** The particular combination of bits in each WhereLoop help to
@@ -149344,11 +149478,11 @@
149344149478
*/
149345149479
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
149346149480
int nLoop = 0;
149347149481
assert( pTerm!=0 );
149348149482
while( (pTerm->wtFlags & TERM_CODED)==0
149349
- && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
149483
+ && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_OuterON))
149350149484
&& (pLevel->notReady & pTerm->prereqAll)==0
149351149485
){
149352149486
if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
149353149487
pTerm->wtFlags |= TERM_LIKECOND;
149354149488
}else{
@@ -149617,12 +149751,11 @@
149617149751
pExpr->iTable = iTab;
149618149752
}
149619149753
sqlite3ExprDelete(db, pX);
149620149754
}else{
149621149755
aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
149622
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP|IN_INDEX_REUSE_CUR, 0, aiMap,&iTab);
149623
- iTab = pExpr->iTable;
149756
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
149624149757
}
149625149758
pX = pExpr;
149626149759
}
149627149760
149628149761
if( eType==IN_INDEX_INDEX_DESC ){
@@ -150066,20 +150199,20 @@
150066150199
**
150067150200
** are also excluded. See codeCursorHintIsOrFunction() for details.
150068150201
*/
150069150202
if( pTabItem->fg.jointype & JT_LEFT ){
150070150203
Expr *pExpr = pTerm->pExpr;
150071
- if( !ExprHasProperty(pExpr, EP_FromJoin)
150204
+ if( !ExprHasProperty(pExpr, EP_OuterON)
150072150205
|| pExpr->w.iJoin!=pTabItem->iCursor
150073150206
){
150074150207
sWalker.eCode = 0;
150075150208
sWalker.xExprCallback = codeCursorHintIsOrFunction;
150076150209
sqlite3WalkExpr(&sWalker, pTerm->pExpr);
150077150210
if( sWalker.eCode ) continue;
150078150211
}
150079150212
}else{
150080
- if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
150213
+ if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) continue;
150081150214
}
150082150215
150083150216
/* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
150084150217
** the cursor. These terms are not needed as hints for a pure range
150085150218
** scan (that has no == terms) so omit them. */
@@ -151406,11 +151539,11 @@
151406151539
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
151407151540
Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
151408151541
Expr *pDelete; /* Local copy of OR clause term */
151409151542
int jmp1 = 0; /* Address of jump operation */
151410151543
testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
151411
- && !ExprHasProperty(pOrExpr, EP_FromJoin)
151544
+ && !ExprHasProperty(pOrExpr, EP_OuterON)
151412151545
); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
151413151546
pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0);
151414151547
if( db->mallocFailed ){
151415151548
sqlite3ExprDelete(db, pDelete);
151416151549
continue;
@@ -151614,16 +151747,26 @@
151614151747
pWInfo->untestedTerms = 1;
151615151748
continue;
151616151749
}
151617151750
pE = pTerm->pExpr;
151618151751
assert( pE!=0 );
151619
- if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ))
151620
- && !ExprHasProperty(pE,EP_FromJoin|EP_InnerJoin)
151621
- ){
151622
- continue;
151752
+ if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){
151753
+ if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){
151754
+ /* Defer processing WHERE clause constraints until after outer
151755
+ ** join processing. tag-20220513a */
151756
+ continue;
151757
+ }else if( (pTabItem->fg.jointype & JT_LEFT)==JT_LEFT
151758
+ && !ExprHasProperty(pE,EP_OuterON) ){
151759
+ continue;
151760
+ }else{
151761
+ Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin);
151762
+ if( m & pLevel->notReady ){
151763
+ /* An ON clause that is not ripe */
151764
+ continue;
151765
+ }
151766
+ }
151623151767
}
151624
-
151625151768
if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
151626151769
iNext = 2;
151627151770
continue;
151628151771
}
151629151772
if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){
@@ -151678,19 +151821,19 @@
151678151821
WhereTerm *pAlt;
151679151822
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151680151823
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
151681151824
if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
151682151825
if( pTerm->leftCursor!=iCur ) continue;
151683
- if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue;
151826
+ if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue;
151684151827
pE = pTerm->pExpr;
151685151828
#ifdef WHERETRACE_ENABLED /* 0x800 */
151686151829
if( sqlite3WhereTrace & 0x800 ){
151687151830
sqlite3DebugPrintf("Coding transitive constraint:\n");
151688151831
sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
151689151832
}
151690151833
#endif
151691
- assert( !ExprHasProperty(pE, EP_FromJoin) );
151834
+ assert( !ExprHasProperty(pE, EP_OuterON) );
151692151835
assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
151693151836
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151694151837
pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
151695151838
WO_EQ|WO_IN|WO_IS, 0);
151696151839
if( pAlt==0 ) continue;
@@ -151757,22 +151900,12 @@
151757151900
*/
151758151901
if( pLevel->iLeftJoin ){
151759151902
pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
151760151903
sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
151761151904
VdbeComment((v, "record LEFT JOIN hit"));
151762
- for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
151763
- testcase( pTerm->wtFlags & TERM_VIRTUAL );
151764
- testcase( pTerm->wtFlags & TERM_CODED );
151765
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151766
- if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
151767
- assert( pWInfo->untestedTerms );
151768
- continue;
151769
- }
151770
- if( pTabItem->fg.jointype & JT_LTORJ ) continue;
151771
- assert( pTerm->pExpr );
151772
- sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
151773
- pTerm->wtFlags |= TERM_CODED;
151905
+ if( pLevel->pRJ==0 ){
151906
+ goto code_outer_join_constraints; /* WHERE clause constraints */
151774151907
}
151775151908
}
151776151909
151777151910
if( pLevel->pRJ ){
151778151911
/* Create a subroutine used to process all interior loops and code
@@ -151784,10 +151917,30 @@
151784151917
WhereRightJoin *pRJ = pLevel->pRJ;
151785151918
sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn);
151786151919
pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v);
151787151920
assert( pParse->withinRJSubrtn < 255 );
151788151921
pParse->withinRJSubrtn++;
151922
+
151923
+ /* WHERE clause constraints must be deferred until after outer join
151924
+ ** row elimination has completed, since WHERE clause constraints apply
151925
+ ** to the results of the OUTER JOIN. The following loop generates the
151926
+ ** appropriate WHERE clause constraint checks. tag-20220513a.
151927
+ */
151928
+ code_outer_join_constraints:
151929
+ for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
151930
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
151931
+ testcase( pTerm->wtFlags & TERM_CODED );
151932
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151933
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
151934
+ assert( pWInfo->untestedTerms );
151935
+ continue;
151936
+ }
151937
+ if( pTabItem->fg.jointype & JT_LTORJ ) continue;
151938
+ assert( pTerm->pExpr );
151939
+ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
151940
+ pTerm->wtFlags |= TERM_CODED;
151941
+ }
151789151942
}
151790151943
151791151944
#if WHERETRACE_ENABLED /* 0x20800 */
151792151945
if( sqlite3WhereTrace & 0x20000 ){
151793151946
sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
@@ -151837,13 +151990,17 @@
151837151990
}
151838151991
if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){
151839151992
mAll |= pLoop->maskSelf;
151840151993
for(k=0; k<pWC->nTerm; k++){
151841151994
WhereTerm *pTerm = &pWC->a[k];
151842
- if( pTerm->wtFlags & TERM_VIRTUAL ) break;
151995
+ if( (pTerm->wtFlags & (TERM_VIRTUAL|TERM_SLICE))!=0
151996
+ && pTerm->eOperator!=WO_ROWVAL
151997
+ ){
151998
+ break;
151999
+ }
151843152000
if( pTerm->prereqAll & ~mAll ) continue;
151844
- if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue;
152001
+ if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue;
151845152002
pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
151846152003
sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
151847152004
}
151848152005
}
151849152006
sFrom.nSrc = 1;
@@ -152351,12 +152508,12 @@
152351152508
/*
152352152509
** If the pBase expression originated in the ON or USING clause of
152353152510
** a join, then transfer the appropriate markings over to derived.
152354152511
*/
152355152512
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
152356
- if( pDerived ){
152357
- pDerived->flags |= pBase->flags & EP_FromJoin;
152513
+ if( pDerived && ExprHasProperty(pBase, EP_OuterON|EP_InnerON) ){
152514
+ pDerived->flags |= pBase->flags & (EP_OuterON|EP_InnerON);
152358152515
pDerived->w.iJoin = pBase->w.iJoin;
152359152516
}
152360152517
}
152361152518
152362152519
/*
@@ -152807,11 +152964,11 @@
152807152964
static int termIsEquivalence(Parse *pParse, Expr *pExpr){
152808152965
char aff1, aff2;
152809152966
CollSeq *pColl;
152810152967
if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
152811152968
if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
152812
- if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
152969
+ if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;
152813152970
aff1 = sqlite3ExprAffinity(pExpr->pLeft);
152814152971
aff2 = sqlite3ExprAffinity(pExpr->pRight);
152815152972
if( aff1!=aff2
152816152973
&& (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
152817152974
){
@@ -152995,22 +153152,30 @@
152995153152
152996153153
#ifdef SQLITE_DEBUG
152997153154
if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){
152998153155
printf("\n*** Incorrect prereqAll computed for:\n");
152999153156
sqlite3TreeViewExpr(0,pExpr,0);
153000
- abort();
153157
+ assert( 0 );
153001153158
}
153002153159
#endif
153003153160
153004
- if( ExprHasProperty(pExpr, EP_FromJoin) ){
153161
+ if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){
153005153162
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
153006
- prereqAll |= x;
153007
- extraRight = x-1; /* ON clause terms may not be used with an index
153008
- ** on left table of a LEFT JOIN. Ticket #3015 */
153009
- if( (prereqAll>>1)>=x ){
153010
- sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
153011
- return;
153163
+ if( ExprHasProperty(pExpr, EP_OuterON) ){
153164
+ prereqAll |= x;
153165
+ extraRight = x-1; /* ON clause terms may not be used with an index
153166
+ ** on left table of a LEFT JOIN. Ticket #3015 */
153167
+ if( (prereqAll>>1)>=x ){
153168
+ sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
153169
+ return;
153170
+ }
153171
+ }else if( (prereqAll>>1)>=x ){
153172
+ /* The ON clause of an INNER JOIN references a table to its right.
153173
+ ** Most other SQL database engines raise an error. But all versions
153174
+ ** of SQLite going back to 3.0.0 have just put the ON clause constraint
153175
+ ** into the WHERE clause and carried on. */
153176
+ ExprClearProperty(pExpr, EP_InnerON);
153012153177
}
153013153178
}
153014153179
pTerm->prereqAll = prereqAll;
153015153180
pTerm->leftCursor = -1;
153016153181
pTerm->iParent = -1;
@@ -153074,11 +153239,11 @@
153074153239
pNew->prereqRight = prereqLeft | extraRight;
153075153240
pNew->prereqAll = prereqAll;
153076153241
pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
153077153242
}else
153078153243
if( op==TK_ISNULL
153079
- && !ExprHasProperty(pExpr,EP_FromJoin)
153244
+ && !ExprHasProperty(pExpr,EP_OuterON)
153080153245
&& 0==sqlite3ExprCanBeNull(pLeft)
153081153246
){
153082153247
assert( !ExprHasProperty(pExpr, EP_IntValue) );
153083153248
pExpr->op = TK_TRUEFALSE;
153084153249
pExpr->u.zToken = "false";
@@ -153145,11 +153310,11 @@
153145153310
** The virtual term must be tagged with TERM_VNULL.
153146153311
*/
153147153312
else if( pExpr->op==TK_NOTNULL ){
153148153313
if( pExpr->pLeft->op==TK_COLUMN
153149153314
&& pExpr->pLeft->iColumn>=0
153150
- && !ExprHasProperty(pExpr, EP_FromJoin)
153315
+ && !ExprHasProperty(pExpr, EP_OuterON)
153151153316
){
153152153317
Expr *pNewExpr;
153153153318
Expr *pLeft = pExpr->pLeft;
153154153319
int idxNew;
153155153320
WhereTerm *pNewTerm;
@@ -153293,11 +153458,11 @@
153293153458
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
153294153459
exprAnalyze(pSrc, pWC, idxNew);
153295153460
}
153296153461
pTerm = &pWC->a[idxTerm];
153297153462
pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
153298
- pTerm->eOperator = 0;
153463
+ pTerm->eOperator = WO_ROWVAL;
153299153464
}
153300153465
153301153466
/* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
153302153467
** a virtual term for each vector component. The expression object
153303153468
** used by each such virtual term is pExpr (the full vector IN(...)
@@ -153349,12 +153514,12 @@
153349153514
prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
153350153515
if( (prereqExpr & prereqColumn)==0 ){
153351153516
Expr *pNewExpr;
153352153517
pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
153353153518
0, sqlite3ExprDup(db, pRight, 0));
153354
- if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
153355
- ExprSetProperty(pNewExpr, EP_FromJoin);
153519
+ if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){
153520
+ ExprSetProperty(pNewExpr, EP_OuterON);
153356153521
pNewExpr->w.iJoin = pExpr->w.iJoin;
153357153522
}
153358153523
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
153359153524
testcase( idxNew==0 );
153360153525
pNewTerm = &pWC->a[idxNew];
@@ -153494,11 +153659,11 @@
153494153659
for(ii=0; ii<pWC->nTerm; ii++){
153495153660
if( pWC->a[ii].wtFlags & TERM_CODED ){
153496153661
/* This term is a vector operation that has been decomposed into
153497153662
** other, subsequent terms. It can be ignored. See tag-20220128a */
153498153663
assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
153499
- assert( pWC->a[ii].eOperator==0 );
153664
+ assert( pWC->a[ii].eOperator==WO_ROWVAL );
153500153665
continue;
153501153666
}
153502153667
if( pWC->a[ii].leftCursor!=iCsr ) return;
153503153668
}
153504153669
@@ -153717,13 +153882,13 @@
153717153882
pItem->colUsed |= sqlite3ExprColUsed(pColRef);
153718153883
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
153719153884
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
153720153885
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
153721153886
if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){
153722
- joinType = EP_FromJoin;
153887
+ joinType = EP_OuterON;
153723153888
}else{
153724
- joinType = EP_InnerJoin;
153889
+ joinType = EP_InnerON;
153725153890
}
153726153891
sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType);
153727153892
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
153728153893
}
153729153894
}
@@ -154060,11 +154225,11 @@
154060154225
if( pTerm->leftCursor==iCur
154061154226
&& pTerm->u.x.leftColumn==iColumn
154062154227
&& (iColumn!=XN_EXPR
154063154228
|| sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
154064154229
pScan->pIdxExpr,iCur)==0)
154065
- && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
154230
+ && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_OuterON))
154066154231
){
154067154232
if( (pTerm->eOperator & WO_EQUIV)!=0
154068154233
&& pScan->nEquiv<ArraySize(pScan->aiCur)
154069154234
&& (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0
154070154235
){
@@ -154412,10 +154577,11 @@
154412154577
if( pOp->opcode==OP_Column ){
154413154578
pOp->opcode = OP_Copy;
154414154579
pOp->p1 = pOp->p2 + iRegister;
154415154580
pOp->p2 = pOp->p3;
154416154581
pOp->p3 = 0;
154582
+ pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */
154417154583
}else if( pOp->opcode==OP_Rowid ){
154418154584
pOp->opcode = OP_Sequence;
154419154585
pOp->p1 = iAutoidxCur;
154420154586
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
154421154587
if( iAutoidxCur==0 ){
@@ -154486,18 +154652,21 @@
154486154652
const Bitmask notReady /* Tables in outer loops of the join */
154487154653
){
154488154654
char aff;
154489154655
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
154490154656
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
154491
- if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
154492
- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
154493
- && (pTerm->eOperator & WO_IS)
154494
- ){
154495
- /* Cannot use an IS term from the WHERE clause as an index driver for
154496
- ** the RHS of a LEFT JOIN or for the LHS of a RIGHT JOIN. Such a term
154497
- ** can only be used if it is from the ON clause. */
154498
- return 0;
154657
+ assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
154658
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
154659
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
154660
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
154661
+ testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
154662
+ testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
154663
+ if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
154664
+ || pTerm->pExpr->w.iJoin != pSrc->iCursor
154665
+ ){
154666
+ return 0; /* See tag-20191211-001 */
154667
+ }
154499154668
}
154500154669
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
154501154670
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
154502154671
if( pTerm->u.x.leftColumn<0 ) return 0;
154503154672
aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
@@ -154907,17 +155076,24 @@
154907155076
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
154908155077
assert( pTerm->u.x.leftColumn>=XN_ROWID );
154909155078
assert( pTerm->u.x.leftColumn<pTab->nCol );
154910155079
154911155080
/* tag-20191211-002: WHERE-clause constraints are not useful to the
154912
- ** right-hand table of a LEFT JOIN nor to the left-hand table of a
155081
+ ** right-hand table of a LEFT JOIN nor to the either table of a
154913155082
** RIGHT JOIN. See tag-20191211-001 for the
154914155083
** equivalent restriction for ordinary tables. */
154915
- if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
154916
- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
154917
- ){
154918
- continue;
155084
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
155085
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155086
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
155087
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155088
+ testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) );
155089
+ testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155090
+ if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155091
+ || pTerm->pExpr->w.iJoin != pSrc->iCursor
155092
+ ){
155093
+ continue;
155094
+ }
154919155095
}
154920155096
nTerm++;
154921155097
pTerm->wtFlags |= TERM_OK;
154922155098
}
154923155099
@@ -155789,11 +155965,11 @@
155789155965
char zType[8];
155790155966
char zLeft[50];
155791155967
memcpy(zType, "....", 5);
155792155968
if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
155793155969
if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
155794
- if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
155970
+ if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) zType[2] = 'L';
155795155971
if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
155796155972
if( pTerm->eOperator & WO_SINGLE ){
155797155973
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155798155974
sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
155799155975
pTerm->leftCursor, pTerm->u.x.leftColumn);
@@ -156563,16 +156739,32 @@
156563156739
** to mix with a lower range bound from some other source */
156564156740
if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
156565156741
156566156742
/* tag-20191211-001: Do not allow constraints from the WHERE clause to
156567156743
** be used by the right table of a LEFT JOIN nor by the left table of a
156568
- ** RIGHT JOIN. Only constraints in the
156569
- ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */
156570
- if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
156571
- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin)
156572
- ){
156573
- continue;
156744
+ ** RIGHT JOIN. Only constraints in the ON clause are allowed.
156745
+ ** See tag-20191211-002 for the vtab equivalent.
156746
+ **
156747
+ ** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f
156748
+ ** for an example of a WHERE clause constraints that may not be used on
156749
+ ** the right table of a RIGHT JOIN because the constraint implies a
156750
+ ** not-NULL condition on the left table of the RIGHT JOIN.
156751
+ **
156752
+ ** 2022-06-10: The same condition applies to termCanDriveIndex() above.
156753
+ ** https://sqlite.org/forum/forumpost/51e6959f61
156754
+ */
156755
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
156756
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
156757
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
156758
+ testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
156759
+ testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
156760
+ testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
156761
+ if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
156762
+ || pTerm->pExpr->w.iJoin != pSrc->iCursor
156763
+ ){
156764
+ continue;
156765
+ }
156574156766
}
156575156767
156576156768
if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
156577156769
pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
156578156770
}else{
@@ -156920,27 +157112,30 @@
156920157112
/* Check to see if a partial index with pPartIndexWhere can be used
156921157113
** in the current query. Return true if it can be and false if not.
156922157114
*/
156923157115
static int whereUsablePartialIndex(
156924157116
int iTab, /* The table for which we want an index */
156925
- int isLeft, /* True if iTab is the right table of a LEFT JOIN */
157117
+ u8 jointype, /* The JT_* flags on the join */
156926157118
WhereClause *pWC, /* The WHERE clause of the query */
156927157119
Expr *pWhere /* The WHERE clause from the partial index */
156928157120
){
156929157121
int i;
156930157122
WhereTerm *pTerm;
156931
- Parse *pParse = pWC->pWInfo->pParse;
157123
+ Parse *pParse;
157124
+
157125
+ if( jointype & JT_LTORJ ) return 0;
157126
+ pParse = pWC->pWInfo->pParse;
156932157127
while( pWhere->op==TK_AND ){
156933
- if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0;
157128
+ if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0;
156934157129
pWhere = pWhere->pRight;
156935157130
}
156936157131
if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
156937157132
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
156938157133
Expr *pExpr;
156939157134
pExpr = pTerm->pExpr;
156940
- if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iJoin==iTab)
156941
- && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
157135
+ if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
157136
+ && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
156942157137
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
156943157138
&& (pTerm->wtFlags & TERM_VNULL)==0
156944157139
){
156945157140
return 1;
156946157141
}
@@ -157102,13 +157297,12 @@
157102157297
/* Loop over all indices. If there was an INDEXED BY clause, then only
157103157298
** consider index pProbe. */
157104157299
for(; rc==SQLITE_OK && pProbe;
157105157300
pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++
157106157301
){
157107
- int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0;
157108157302
if( pProbe->pPartIdxWhere!=0
157109
- && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC,
157303
+ && !whereUsablePartialIndex(pSrc->iCursor, pSrc->fg.jointype, pWC,
157110157304
pProbe->pPartIdxWhere)
157111157305
){
157112157306
testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
157113157307
continue; /* Partial index inappropriate for this query */
157114157308
}
@@ -157212,11 +157406,18 @@
157212157406
157213157407
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup);
157214157408
}
157215157409
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
157216157410
whereLoopOutputAdjust(pWC, pNew, rSize);
157217
- rc = whereLoopInsert(pBuilder, pNew);
157411
+ if( (pSrc->fg.jointype & JT_RIGHT)!=0 && pProbe->aColExpr ){
157412
+ /* Do not do an SCAN of a index-on-expression in a RIGHT JOIN
157413
+ ** because the cursor used to access the index might not be
157414
+ ** positioned to the correct row during the right-join no-match
157415
+ ** loop. */
157416
+ }else{
157417
+ rc = whereLoopInsert(pBuilder, pNew);
157418
+ }
157218157419
pNew->nOut = rSize;
157219157420
if( rc ) break;
157220157421
}
157221157422
}
157222157423
@@ -157387,10 +157588,11 @@
157387157588
pIdxInfo->orderByConsumed = 0;
157388157589
pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
157389157590
*pbIn = 1; assert( (mExclude & WO_IN)==0 );
157390157591
}
157391157592
157593
+ assert( pbRetryLimit || !isLimitTerm(pTerm) );
157392157594
if( isLimitTerm(pTerm) && *pbIn ){
157393157595
/* If there is an IN(...) term handled as an == (separate call to
157394157596
** xFilter for each value on the RHS of the IN) and a LIMIT or
157395157597
** OFFSET term handled as well, the plan is unusable. Set output
157396157598
** variable *pbRetryLimit to true to tell the caller to retry with
@@ -157860,11 +158062,13 @@
157860158062
SrcList *pTabList = pWInfo->pTabList;
157861158063
SrcItem *pItem;
157862158064
SrcItem *pEnd = &pTabList->a[pWInfo->nLevel];
157863158065
sqlite3 *db = pWInfo->pParse->db;
157864158066
int rc = SQLITE_OK;
158067
+ int bFirstPastRJ = 0;
157865158068
WhereLoop *pNew;
158069
+
157866158070
157867158071
/* Loop over the tables in the join, from left to right */
157868158072
pNew = pBuilder->pNew;
157869158073
whereLoopInit(pNew);
157870158074
pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
@@ -157871,14 +158075,17 @@
157871158075
for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
157872158076
Bitmask mUnusable = 0;
157873158077
pNew->iTab = iTab;
157874158078
pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
157875158079
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
157876
- if( (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
157877
- /* This condition is true when pItem is the FROM clause term on the
157878
- ** right-hand-side of a OUTER or CROSS JOIN. */
158080
+ if( bFirstPastRJ || (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
158081
+ /* Add prerequisites to prevent reordering of FROM clause terms
158082
+ ** across CROSS joins and outer joins. The bFirstPastRJ boolean
158083
+ ** prevents the right operand of a RIGHT JOIN from being swapped with
158084
+ ** other elements even further to the right. */
157879158085
mPrereq |= mPrior;
158086
+ bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
157880158087
}
157881158088
#ifndef SQLITE_OMIT_VIRTUALTABLE
157882158089
if( IsVirtual(pItem->pTab) ){
157883158090
SrcItem *p;
157884158091
for(p=&pItem[1]; p<pEnd; p++){
@@ -158944,11 +159151,11 @@
158944159151
}
158945159152
if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
158946159153
pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
158947159154
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
158948159155
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
158949
- if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
159156
+ if( !ExprHasProperty(pTerm->pExpr, EP_OuterON)
158950159157
|| pTerm->pExpr->w.iJoin!=pItem->iCursor
158951159158
){
158952159159
break;
158953159160
}
158954159161
}
@@ -159570,10 +159777,11 @@
159570159777
op = OP_ReopenIdx;
159571159778
}else{
159572159779
iIndexCur = pParse->nTab++;
159573159780
}
159574159781
pLevel->iIdxCur = iIndexCur;
159782
+ assert( pIx!=0 );
159575159783
assert( pIx->pSchema==pTab->pSchema );
159576159784
assert( iIndexCur>=0 );
159577159785
if( op ){
159578159786
sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
159579159787
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
@@ -159645,13 +159853,24 @@
159645159853
** program.
159646159854
*/
159647159855
for(ii=0; ii<nTabList; ii++){
159648159856
int addrExplain;
159649159857
int wsFlags;
159858
+ SrcItem *pSrc;
159650159859
if( pParse->nErr ) goto whereBeginError;
159651159860
pLevel = &pWInfo->a[ii];
159652159861
wsFlags = pLevel->pWLoop->wsFlags;
159862
+ pSrc = &pTabList->a[pLevel->iFrom];
159863
+ if( pSrc->fg.isMaterialized ){
159864
+ if( pSrc->fg.isCorrelated ){
159865
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
159866
+ }else{
159867
+ int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
159868
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
159869
+ sqlite3VdbeJumpHere(v, iOnce);
159870
+ }
159871
+ }
159653159872
if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
159654159873
if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
159655159874
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
159656159875
constructAutomaticIndex(pParse, &pWInfo->sWC,
159657159876
&pTabList->a[pLevel->iFrom], notReady, pLevel);
@@ -159739,10 +159958,11 @@
159739159958
WhereLevel *pLevel;
159740159959
WhereLoop *pLoop;
159741159960
SrcList *pTabList = pWInfo->pTabList;
159742159961
sqlite3 *db = pParse->db;
159743159962
int iEnd = sqlite3VdbeCurrentAddr(v);
159963
+ int nRJ = 0;
159744159964
159745159965
/* Generate loop termination code.
159746159966
*/
159747159967
VdbeModuleComment((v, "End WHERE-core"));
159748159968
for(i=pWInfo->nLevel-1; i>=0; i--){
@@ -159755,12 +159975,11 @@
159755159975
sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159756159976
pLevel->addrCont = 0;
159757159977
pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v);
159758159978
sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
159759159979
VdbeCoverage(v);
159760
- assert( pParse->withinRJSubrtn>0 );
159761
- pParse->withinRJSubrtn--;
159980
+ nRJ++;
159762159981
}
159763159982
pLoop = pLevel->pWLoop;
159764159983
if( pLevel->op!=OP_Noop ){
159765159984
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
159766159985
int addrSeek = 0;
@@ -159898,10 +160117,11 @@
159898160117
VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
159899160118
pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
159900160119
}
159901160120
159902160121
assert( pWInfo->nLevel<=pTabList->nSrc );
160122
+ if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
159903160123
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
159904160124
int k, last;
159905160125
VdbeOp *pOp, *pLastOp;
159906160126
Index *pIdx = 0;
159907160127
SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
@@ -160034,13 +160254,13 @@
160034160254
*/
160035160255
sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
160036160256
160037160257
/* Final cleanup
160038160258
*/
160039
- if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
160040160259
pParse->nQueryLoop = pWInfo->savedNQueryLoop;
160041160260
whereInfoFree(db, pWInfo);
160261
+ pParse->withinRJSubrtn -= nRJ;
160042160262
return;
160043160263
}
160044160264
160045160265
/************** End of where.c ***********************************************/
160046160266
/************** Begin file window.c ******************************************/
@@ -163662,22 +163882,22 @@
163662163882
#define sqlite3ParserCTX_PDECL ,Parse *pParse
163663163883
#define sqlite3ParserCTX_PARAM ,pParse
163664163884
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
163665163885
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
163666163886
#define YYFALLBACK 1
163667
-#define YYNSTATE 570
163668
-#define YYNRULE 403
163669
-#define YYNRULE_WITH_ACTION 340
163887
+#define YYNSTATE 576
163888
+#define YYNRULE 405
163889
+#define YYNRULE_WITH_ACTION 342
163670163890
#define YYNTOKEN 185
163671
-#define YY_MAX_SHIFT 569
163672
-#define YY_MIN_SHIFTREDUCE 829
163673
-#define YY_MAX_SHIFTREDUCE 1231
163674
-#define YY_ERROR_ACTION 1232
163675
-#define YY_ACCEPT_ACTION 1233
163676
-#define YY_NO_ACTION 1234
163677
-#define YY_MIN_REDUCE 1235
163678
-#define YY_MAX_REDUCE 1637
163891
+#define YY_MAX_SHIFT 575
163892
+#define YY_MIN_SHIFTREDUCE 835
163893
+#define YY_MAX_SHIFTREDUCE 1239
163894
+#define YY_ERROR_ACTION 1240
163895
+#define YY_ACCEPT_ACTION 1241
163896
+#define YY_NO_ACTION 1242
163897
+#define YY_MIN_REDUCE 1243
163898
+#define YY_MAX_REDUCE 1647
163679163899
/************* End control #defines *******************************************/
163680163900
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
163681163901
163682163902
/* Define the yytestcase() macro to be a no-op if is not already defined
163683163903
** otherwise.
@@ -163740,219 +163960,222 @@
163740163960
** yy_reduce_ofst[] For each state, the offset into yy_action for
163741163961
** shifting non-terminals after a reduce.
163742163962
** yy_default[] Default action for each state.
163743163963
**
163744163964
*********** Begin parsing tables **********************************************/
163745
-#define YY_ACTTAB_COUNT (2064)
163965
+#define YY_ACTTAB_COUNT (2098)
163746163966
static const YYACTIONTYPE yy_action[] = {
163747
- /* 0 */ 562, 204, 562, 116, 112, 225, 562, 116, 112, 225,
163748
- /* 10 */ 562, 1306, 373, 1285, 404, 556, 556, 556, 562, 405,
163749
- /* 20 */ 374, 1306, 1268, 41, 41, 41, 41, 204, 1516, 71,
163750
- /* 30 */ 71, 965, 415, 41, 41, 487, 299, 275, 299, 966,
163751
- /* 40 */ 393, 71, 71, 123, 124, 114, 1209, 1209, 1042, 1045,
163752
- /* 50 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 472, 405,
163753
- /* 60 */ 1233, 1, 1, 569, 2, 1237, 544, 116, 112, 225,
163754
- /* 70 */ 313, 476, 142, 476, 520, 116, 112, 225, 525, 1319,
163755
- /* 80 */ 413, 519, 138, 123, 124, 114, 1209, 1209, 1042, 1045,
163756
- /* 90 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 116, 112,
163757
- /* 100 */ 225, 323, 120, 120, 120, 120, 119, 119, 118, 118,
163758
- /* 110 */ 118, 117, 113, 440, 280, 280, 280, 280, 438, 438,
163759
- /* 120 */ 438, 1557, 372, 1559, 1184, 371, 1155, 559, 1155, 559,
163760
- /* 130 */ 405, 1557, 533, 255, 222, 440, 99, 141, 445, 312,
163761
- /* 140 */ 553, 236, 120, 120, 120, 120, 119, 119, 118, 118,
163762
- /* 150 */ 118, 117, 113, 440, 123, 124, 114, 1209, 1209, 1042,
163763
- /* 160 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 138,
163764
- /* 170 */ 290, 1184, 335, 444, 118, 118, 118, 117, 113, 440,
163765
- /* 180 */ 125, 1184, 1185, 1186, 144, 437, 436, 562, 117, 113,
163766
- /* 190 */ 440, 122, 122, 122, 122, 115, 120, 120, 120, 120,
163767
- /* 200 */ 119, 119, 118, 118, 118, 117, 113, 440, 450, 110,
163768
- /* 210 */ 13, 13, 542, 120, 120, 120, 120, 119, 119, 118,
163769
- /* 220 */ 118, 118, 117, 113, 440, 418, 312, 553, 1184, 1185,
163770
- /* 230 */ 1186, 145, 1216, 405, 1216, 122, 122, 122, 122, 120,
163771
- /* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
163772
- /* 250 */ 440, 461, 338, 1031, 1031, 1043, 1046, 123, 124, 114,
163773
- /* 260 */ 1209, 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122,
163774
- /* 270 */ 122, 122, 1271, 518, 218, 1184, 562, 405, 220, 510,
163775
- /* 280 */ 171, 80, 81, 120, 120, 120, 120, 119, 119, 118,
163776
- /* 290 */ 118, 118, 117, 113, 440, 1001, 16, 16, 1184, 55,
163777
- /* 300 */ 55, 123, 124, 114, 1209, 1209, 1042, 1045, 1034, 1034,
163778
- /* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120,
163779
- /* 320 */ 119, 119, 118, 118, 118, 117, 113, 440, 1035, 542,
163780
- /* 330 */ 1184, 369, 1184, 1185, 1186, 248, 1426, 395, 500, 497,
163781
- /* 340 */ 496, 108, 554, 560, 4, 920, 920, 429, 495, 336,
163782
- /* 350 */ 456, 324, 356, 390, 1229, 1184, 1185, 1186, 557, 562,
163783
- /* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117,
163784
- /* 370 */ 113, 440, 280, 280, 365, 1570, 1597, 437, 436, 150,
163785
- /* 380 */ 405, 441, 71, 71, 1278, 559, 1213, 1184, 1185, 1186,
163786
- /* 390 */ 83, 1215, 267, 551, 539, 511, 1551, 562, 96, 1214,
163787
- /* 400 */ 6, 1270, 468, 138, 123, 124, 114, 1209, 1209, 1042,
163788
- /* 410 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 544,
163789
- /* 420 */ 13, 13, 1021, 503, 1216, 1184, 1216, 543, 106, 106,
163790
- /* 430 */ 218, 562, 1230, 171, 562, 423, 107, 193, 441, 564,
163791
- /* 440 */ 563, 426, 1542, 1011, 321, 545, 1184, 266, 283, 364,
163792
- /* 450 */ 506, 359, 505, 253, 71, 71, 539, 71, 71, 355,
163793
- /* 460 */ 312, 553, 1603, 120, 120, 120, 120, 119, 119, 118,
163794
- /* 470 */ 118, 118, 117, 113, 440, 1011, 1011, 1013, 1014, 27,
163795
- /* 480 */ 280, 280, 1184, 1185, 1186, 1150, 562, 1602, 405, 895,
163796
- /* 490 */ 186, 544, 352, 559, 544, 931, 529, 513, 1150, 512,
163797
- /* 500 */ 409, 1150, 546, 1184, 1185, 1186, 562, 540, 1544, 51,
163798
- /* 510 */ 51, 210, 123, 124, 114, 1209, 1209, 1042, 1045, 1034,
163799
- /* 520 */ 1034, 121, 121, 122, 122, 122, 122, 1184, 470, 56,
163800
- /* 530 */ 56, 405, 280, 280, 1480, 501, 119, 119, 118, 118,
163801
- /* 540 */ 118, 117, 113, 440, 1001, 559, 514, 213, 537, 1551,
163802
- /* 550 */ 312, 553, 138, 6, 528, 123, 124, 114, 1209, 1209,
163803
- /* 560 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163804
- /* 570 */ 1545, 120, 120, 120, 120, 119, 119, 118, 118, 118,
163805
- /* 580 */ 117, 113, 440, 481, 1184, 1185, 1186, 478, 277, 1259,
163806
- /* 590 */ 951, 248, 1184, 369, 500, 497, 496, 1184, 336, 565,
163807
- /* 600 */ 1184, 565, 405, 288, 495, 951, 870, 187, 476, 312,
163808
- /* 610 */ 553, 380, 286, 376, 120, 120, 120, 120, 119, 119,
163809
- /* 620 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163810
- /* 630 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163811
- /* 640 */ 122, 405, 390, 1128, 1184, 863, 98, 280, 280, 1184,
163812
- /* 650 */ 1185, 1186, 369, 1085, 1184, 1185, 1186, 1184, 1185, 1186,
163813
- /* 660 */ 559, 451, 32, 369, 229, 123, 124, 114, 1209, 1209,
163814
- /* 670 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163815
- /* 680 */ 1425, 953, 562, 224, 952, 120, 120, 120, 120, 119,
163816
- /* 690 */ 119, 118, 118, 118, 117, 113, 440, 1150, 224, 1184,
163817
- /* 700 */ 153, 1184, 1185, 1186, 1543, 13, 13, 297, 951, 1224,
163818
- /* 710 */ 1150, 149, 405, 1150, 369, 1573, 1168, 5, 365, 1570,
163819
- /* 720 */ 425, 1230, 3, 951, 120, 120, 120, 120, 119, 119,
163820
- /* 730 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163821
- /* 740 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163822
- /* 750 */ 122, 405, 204, 561, 1184, 1022, 1184, 1185, 1186, 1184,
163823
- /* 760 */ 384, 846, 151, 1542, 282, 398, 1090, 1090, 484, 562,
163824
- /* 770 */ 461, 338, 1311, 1311, 1542, 123, 124, 114, 1209, 1209,
163825
- /* 780 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163826
- /* 790 */ 127, 562, 13, 13, 370, 120, 120, 120, 120, 119,
163827
- /* 800 */ 119, 118, 118, 118, 117, 113, 440, 298, 562, 449,
163828
- /* 810 */ 524, 1184, 1185, 1186, 13, 13, 1184, 1185, 1186, 1289,
163829
- /* 820 */ 459, 1259, 405, 1309, 1309, 1542, 1006, 449, 448, 196,
163830
- /* 830 */ 295, 71, 71, 1257, 120, 120, 120, 120, 119, 119,
163831
- /* 840 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163832
- /* 850 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163833
- /* 860 */ 122, 405, 223, 1065, 1150, 280, 280, 415, 308, 274,
163834
- /* 870 */ 274, 281, 281, 1411, 402, 401, 378, 1150, 559, 562,
163835
- /* 880 */ 1150, 1188, 559, 1590, 559, 123, 124, 114, 1209, 1209,
163836
- /* 890 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163837
- /* 900 */ 449, 1472, 13, 13, 1526, 120, 120, 120, 120, 119,
163838
- /* 910 */ 119, 118, 118, 118, 117, 113, 440, 197, 562, 350,
163839
- /* 920 */ 1576, 569, 2, 1237, 834, 835, 836, 1552, 313, 1204,
163840
- /* 930 */ 142, 6, 405, 251, 250, 249, 202, 1319, 9, 1188,
163841
- /* 940 */ 258, 71, 71, 420, 120, 120, 120, 120, 119, 119,
163842
- /* 950 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163843
- /* 960 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163844
- /* 970 */ 122, 562, 280, 280, 562, 1205, 405, 568, 309, 1237,
163845
- /* 980 */ 345, 1288, 348, 415, 313, 559, 142, 487, 521, 1633,
163846
- /* 990 */ 391, 367, 487, 1319, 70, 70, 1287, 71, 71, 236,
163847
- /* 1000 */ 1317, 101, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121,
163848
- /* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119,
163849
- /* 1020 */ 119, 118, 118, 118, 117, 113, 440, 1106, 280, 280,
163850
- /* 1030 */ 424, 444, 1515, 1205, 435, 280, 280, 1479, 1344, 307,
163851
- /* 1040 */ 470, 559, 1107, 965, 487, 487, 213, 1255, 559, 1528,
163852
- /* 1050 */ 562, 966, 203, 562, 1021, 236, 379, 1108, 515, 120,
163853
- /* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
163854
- /* 1070 */ 440, 1012, 104, 71, 71, 1011, 13, 13, 906, 562,
163855
- /* 1080 */ 1485, 562, 280, 280, 95, 522, 487, 444, 907, 1318,
163856
- /* 1090 */ 1314, 541, 405, 280, 280, 559, 147, 205, 1485, 1487,
163857
- /* 1100 */ 258, 446, 15, 15, 43, 43, 559, 1011, 1011, 1013,
163858
- /* 1110 */ 439, 328, 405, 523, 12, 291, 123, 124, 114, 1209,
163859
- /* 1120 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163860
- /* 1130 */ 122, 343, 405, 858, 1524, 1205, 123, 124, 114, 1209,
163861
- /* 1140 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163862
- /* 1150 */ 122, 1129, 1631, 470, 1631, 367, 123, 111, 114, 1209,
163863
- /* 1160 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163864
- /* 1170 */ 122, 1485, 325, 470, 327, 120, 120, 120, 120, 119,
163865
- /* 1180 */ 119, 118, 118, 118, 117, 113, 440, 199, 1411, 562,
163866
- /* 1190 */ 1286, 858, 460, 1205, 432, 120, 120, 120, 120, 119,
163867
- /* 1200 */ 119, 118, 118, 118, 117, 113, 440, 547, 1129, 1632,
163868
- /* 1210 */ 535, 1632, 57, 57, 886, 120, 120, 120, 120, 119,
163869
- /* 1220 */ 119, 118, 118, 118, 117, 113, 440, 562, 294, 534,
163870
- /* 1230 */ 1127, 1411, 1549, 1550, 1323, 405, 6, 6, 1161, 1260,
163871
- /* 1240 */ 411, 316, 280, 280, 1411, 504, 559, 521, 296, 453,
163872
- /* 1250 */ 44, 44, 562, 887, 12, 559, 326, 474, 421, 403,
163873
- /* 1260 */ 124, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121, 121,
163874
- /* 1270 */ 122, 122, 122, 122, 562, 58, 58, 284, 1184, 1411,
163875
- /* 1280 */ 492, 454, 388, 388, 387, 269, 385, 1127, 1548, 843,
163876
- /* 1290 */ 1161, 403, 6, 562, 317, 1150, 466, 59, 59, 1547,
163877
- /* 1300 */ 1106, 422, 230, 6, 319, 252, 536, 252, 1150, 427,
163878
- /* 1310 */ 562, 1150, 318, 17, 483, 1107, 60, 60, 120, 120,
163879
- /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 440,
163880
- /* 1330 */ 1108, 212, 477, 61, 61, 1184, 1185, 1186, 108, 554,
163881
- /* 1340 */ 320, 4, 232, 452, 522, 562, 233, 452, 562, 433,
163882
- /* 1350 */ 164, 550, 416, 137, 475, 557, 562, 289, 562, 1087,
163883
- /* 1360 */ 562, 289, 562, 1087, 527, 562, 866, 8, 62, 62,
163884
- /* 1370 */ 231, 45, 45, 562, 410, 562, 410, 562, 441, 46,
163885
- /* 1380 */ 46, 47, 47, 49, 49, 50, 50, 195, 63, 63,
163886
- /* 1390 */ 551, 562, 355, 562, 98, 482, 64, 64, 65, 65,
163887
- /* 1400 */ 14, 14, 555, 411, 531, 406, 562, 1021, 562, 530,
163888
- /* 1410 */ 312, 553, 312, 553, 66, 66, 129, 129, 562, 1021,
163889
- /* 1420 */ 562, 508, 926, 866, 1012, 106, 106, 925, 1011, 67,
163890
- /* 1430 */ 67, 52, 52, 107, 447, 441, 564, 563, 412, 173,
163891
- /* 1440 */ 1011, 68, 68, 69, 69, 562, 463, 562, 926, 467,
163892
- /* 1450 */ 1356, 279, 222, 925, 311, 1355, 403, 562, 455, 403,
163893
- /* 1460 */ 1011, 1011, 1013, 235, 403, 84, 209, 1342, 53, 53,
163894
- /* 1470 */ 159, 159, 1011, 1011, 1013, 1014, 27, 1575, 1172, 443,
163895
- /* 1480 */ 160, 160, 284, 95, 105, 1531, 103, 388, 388, 387,
163896
- /* 1490 */ 269, 385, 562, 873, 843, 877, 562, 108, 554, 462,
163897
- /* 1500 */ 4, 562, 148, 30, 38, 562, 1124, 230, 392, 319,
163898
- /* 1510 */ 108, 554, 523, 4, 557, 76, 76, 318, 562, 54,
163899
- /* 1520 */ 54, 562, 333, 464, 72, 72, 329, 557, 130, 130,
163900
- /* 1530 */ 562, 285, 1504, 562, 31, 1503, 562, 441, 334, 479,
163901
- /* 1540 */ 98, 73, 73, 340, 157, 157, 292, 232, 1072, 551,
163902
- /* 1550 */ 441, 873, 1352, 131, 131, 164, 132, 132, 137, 128,
163903
- /* 1560 */ 128, 1564, 551, 531, 562, 315, 562, 344, 532, 1003,
163904
- /* 1570 */ 469, 257, 257, 885, 884, 231, 531, 562, 1021, 562,
163905
- /* 1580 */ 471, 530, 257, 363, 106, 106, 517, 158, 158, 152,
163906
- /* 1590 */ 152, 1021, 107, 362, 441, 564, 563, 106, 106, 1011,
163907
- /* 1600 */ 136, 136, 135, 135, 562, 107, 1072, 441, 564, 563,
163908
- /* 1610 */ 406, 347, 1011, 562, 349, 312, 553, 562, 339, 562,
163909
- /* 1620 */ 98, 493, 353, 254, 98, 892, 893, 133, 133, 351,
163910
- /* 1630 */ 1302, 1011, 1011, 1013, 1014, 27, 134, 134, 1015, 447,
163911
- /* 1640 */ 75, 75, 77, 77, 1011, 1011, 1013, 1014, 27, 1172,
163912
- /* 1650 */ 443, 562, 358, 284, 108, 554, 368, 4, 388, 388,
163913
- /* 1660 */ 387, 269, 385, 562, 1133, 843, 562, 1068, 956, 254,
163914
- /* 1670 */ 257, 557, 968, 969, 74, 74, 549, 923, 230, 110,
163915
- /* 1680 */ 319, 108, 554, 1084, 4, 1084, 42, 42, 318, 48,
163916
- /* 1690 */ 48, 1083, 1365, 1083, 441, 856, 1015, 146, 557, 924,
163917
- /* 1700 */ 1410, 110, 1338, 1350, 548, 1416, 551, 1267, 207, 1258,
163918
- /* 1710 */ 1246, 1245, 1247, 1583, 11, 488, 272, 215, 232, 1335,
163919
- /* 1720 */ 304, 441, 305, 306, 389, 228, 164, 1397, 1392, 137,
163920
- /* 1730 */ 287, 331, 332, 551, 293, 1021, 1385, 337, 473, 200,
163921
- /* 1740 */ 361, 106, 106, 930, 498, 1402, 231, 1401, 1285, 107,
163922
- /* 1750 */ 396, 441, 564, 563, 219, 1476, 1011, 1347, 1475, 1348,
163923
- /* 1760 */ 1346, 1345, 1021, 1224, 552, 1586, 261, 1221, 106, 106,
163924
- /* 1770 */ 1523, 201, 383, 1521, 214, 414, 107, 83, 441, 564,
163925
- /* 1780 */ 563, 406, 211, 1011, 175, 1398, 312, 553, 1011, 1011,
163926
- /* 1790 */ 1013, 1014, 27, 226, 184, 169, 100, 554, 79, 4,
163927
- /* 1800 */ 82, 457, 35, 179, 458, 177, 491, 238, 96, 1481,
163928
- /* 1810 */ 447, 180, 1404, 557, 181, 1011, 1011, 1013, 1014, 27,
163929
- /* 1820 */ 182, 1403, 394, 36, 465, 1406, 397, 188, 1470, 480,
163930
- /* 1830 */ 242, 89, 1492, 486, 342, 244, 441, 273, 192, 346,
163931
- /* 1840 */ 489, 245, 399, 1248, 428, 246, 507, 1296, 551, 91,
163932
- /* 1850 */ 877, 1305, 1304, 220, 1601, 1295, 1303, 430, 431, 516,
163933
- /* 1860 */ 1569, 259, 400, 302, 1600, 1275, 303, 260, 360, 1274,
163934
- /* 1870 */ 1273, 1599, 366, 1555, 434, 1554, 1370, 1021, 1369, 542,
163935
- /* 1880 */ 126, 10, 1456, 106, 106, 377, 102, 97, 310, 526,
163936
- /* 1890 */ 34, 107, 566, 441, 564, 563, 1178, 271, 1011, 268,
163937
- /* 1900 */ 270, 567, 1243, 1238, 206, 1328, 375, 381, 1327, 382,
163938
- /* 1910 */ 407, 161, 174, 408, 1508, 1509, 143, 300, 830, 162,
163939
- /* 1920 */ 1507, 1506, 163, 442, 208, 314, 227, 216, 217, 78,
163940
- /* 1930 */ 1011, 1011, 1013, 1014, 27, 140, 1082, 322, 1080, 165,
163941
- /* 1940 */ 176, 1204, 234, 178, 909, 330, 237, 1096, 183, 166,
163942
- /* 1950 */ 167, 417, 85, 86, 419, 185, 87, 88, 168, 1099,
163943
- /* 1960 */ 239, 1095, 240, 154, 18, 241, 341, 1218, 257, 1088,
163944
- /* 1970 */ 243, 485, 190, 189, 37, 845, 490, 362, 247, 494,
163945
- /* 1980 */ 357, 191, 875, 90, 19, 502, 354, 20, 499, 92,
163946
- /* 1990 */ 170, 155, 888, 93, 301, 509, 94, 1166, 156, 1048,
163947
- /* 2000 */ 1135, 39, 221, 1134, 276, 278, 256, 194, 110, 960,
163948
- /* 2010 */ 954, 1156, 21, 1152, 22, 1160, 1140, 1154, 23, 33,
163949
- /* 2020 */ 24, 1159, 25, 538, 26, 198, 98, 1063, 1049, 1047,
163950
- /* 2030 */ 1051, 7, 1105, 262, 1104, 263, 1052, 28, 40, 558,
163951
- /* 2040 */ 1016, 857, 109, 29, 919, 386, 139, 172, 264, 265,
163952
- /* 2050 */ 1174, 1592, 1173, 1234, 1234, 1234, 1234, 1234, 1234, 1234,
163953
- /* 2060 */ 1234, 1234, 1234, 1591,
163967
+ /* 0 */ 568, 208, 568, 118, 115, 229, 568, 118, 115, 229,
163968
+ /* 10 */ 568, 1314, 377, 1293, 408, 562, 562, 562, 568, 409,
163969
+ /* 20 */ 378, 1314, 1276, 41, 41, 41, 41, 208, 1526, 71,
163970
+ /* 30 */ 71, 971, 419, 41, 41, 491, 303, 279, 303, 972,
163971
+ /* 40 */ 397, 71, 71, 125, 126, 80, 1217, 1217, 1050, 1053,
163972
+ /* 50 */ 1040, 1040, 123, 123, 124, 124, 124, 124, 476, 409,
163973
+ /* 60 */ 1241, 1, 1, 575, 2, 1245, 550, 118, 115, 229,
163974
+ /* 70 */ 317, 480, 146, 480, 524, 118, 115, 229, 529, 1327,
163975
+ /* 80 */ 417, 523, 142, 125, 126, 80, 1217, 1217, 1050, 1053,
163976
+ /* 90 */ 1040, 1040, 123, 123, 124, 124, 124, 124, 118, 115,
163977
+ /* 100 */ 229, 327, 122, 122, 122, 122, 121, 121, 120, 120,
163978
+ /* 110 */ 120, 119, 116, 444, 284, 284, 284, 284, 442, 442,
163979
+ /* 120 */ 442, 1567, 376, 1569, 1192, 375, 1163, 565, 1163, 565,
163980
+ /* 130 */ 409, 1567, 537, 259, 226, 444, 101, 145, 449, 316,
163981
+ /* 140 */ 559, 240, 122, 122, 122, 122, 121, 121, 120, 120,
163982
+ /* 150 */ 120, 119, 116, 444, 125, 126, 80, 1217, 1217, 1050,
163983
+ /* 160 */ 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, 142,
163984
+ /* 170 */ 294, 1192, 339, 448, 120, 120, 120, 119, 116, 444,
163985
+ /* 180 */ 127, 1192, 1193, 1194, 148, 441, 440, 568, 119, 116,
163986
+ /* 190 */ 444, 124, 124, 124, 124, 117, 122, 122, 122, 122,
163987
+ /* 200 */ 121, 121, 120, 120, 120, 119, 116, 444, 454, 113,
163988
+ /* 210 */ 13, 13, 546, 122, 122, 122, 122, 121, 121, 120,
163989
+ /* 220 */ 120, 120, 119, 116, 444, 422, 316, 559, 1192, 1193,
163990
+ /* 230 */ 1194, 149, 1224, 409, 1224, 124, 124, 124, 124, 122,
163991
+ /* 240 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116,
163992
+ /* 250 */ 444, 465, 342, 1037, 1037, 1051, 1054, 125, 126, 80,
163993
+ /* 260 */ 1217, 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124,
163994
+ /* 270 */ 124, 124, 1279, 522, 222, 1192, 568, 409, 224, 514,
163995
+ /* 280 */ 175, 82, 83, 122, 122, 122, 122, 121, 121, 120,
163996
+ /* 290 */ 120, 120, 119, 116, 444, 1007, 16, 16, 1192, 133,
163997
+ /* 300 */ 133, 125, 126, 80, 1217, 1217, 1050, 1053, 1040, 1040,
163998
+ /* 310 */ 123, 123, 124, 124, 124, 124, 122, 122, 122, 122,
163999
+ /* 320 */ 121, 121, 120, 120, 120, 119, 116, 444, 1041, 546,
164000
+ /* 330 */ 1192, 373, 1192, 1193, 1194, 252, 1434, 399, 504, 501,
164001
+ /* 340 */ 500, 111, 560, 566, 4, 926, 926, 433, 499, 340,
164002
+ /* 350 */ 460, 328, 360, 394, 1237, 1192, 1193, 1194, 563, 568,
164003
+ /* 360 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119,
164004
+ /* 370 */ 116, 444, 284, 284, 369, 1580, 1607, 441, 440, 154,
164005
+ /* 380 */ 409, 445, 71, 71, 1286, 565, 1221, 1192, 1193, 1194,
164006
+ /* 390 */ 85, 1223, 271, 557, 543, 515, 1561, 568, 98, 1222,
164007
+ /* 400 */ 6, 1278, 472, 142, 125, 126, 80, 1217, 1217, 1050,
164008
+ /* 410 */ 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, 550,
164009
+ /* 420 */ 13, 13, 1027, 507, 1224, 1192, 1224, 549, 109, 109,
164010
+ /* 430 */ 222, 568, 1238, 175, 568, 427, 110, 197, 445, 570,
164011
+ /* 440 */ 569, 430, 1552, 1017, 325, 551, 1192, 270, 287, 368,
164012
+ /* 450 */ 510, 363, 509, 257, 71, 71, 543, 71, 71, 359,
164013
+ /* 460 */ 316, 559, 1613, 122, 122, 122, 122, 121, 121, 120,
164014
+ /* 470 */ 120, 120, 119, 116, 444, 1017, 1017, 1019, 1020, 27,
164015
+ /* 480 */ 284, 284, 1192, 1193, 1194, 1158, 568, 1612, 409, 901,
164016
+ /* 490 */ 190, 550, 356, 565, 550, 937, 533, 517, 1158, 516,
164017
+ /* 500 */ 413, 1158, 552, 1192, 1193, 1194, 568, 544, 1554, 51,
164018
+ /* 510 */ 51, 214, 125, 126, 80, 1217, 1217, 1050, 1053, 1040,
164019
+ /* 520 */ 1040, 123, 123, 124, 124, 124, 124, 1192, 474, 135,
164020
+ /* 530 */ 135, 409, 284, 284, 1490, 505, 121, 121, 120, 120,
164021
+ /* 540 */ 120, 119, 116, 444, 1007, 565, 518, 217, 541, 1561,
164022
+ /* 550 */ 316, 559, 142, 6, 532, 125, 126, 80, 1217, 1217,
164023
+ /* 560 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164024
+ /* 570 */ 1555, 122, 122, 122, 122, 121, 121, 120, 120, 120,
164025
+ /* 580 */ 119, 116, 444, 485, 1192, 1193, 1194, 482, 281, 1267,
164026
+ /* 590 */ 957, 252, 1192, 373, 504, 501, 500, 1192, 340, 571,
164027
+ /* 600 */ 1192, 571, 409, 292, 499, 957, 876, 191, 480, 316,
164028
+ /* 610 */ 559, 384, 290, 380, 122, 122, 122, 122, 121, 121,
164029
+ /* 620 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164030
+ /* 630 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164031
+ /* 640 */ 124, 409, 394, 1136, 1192, 869, 100, 284, 284, 1192,
164032
+ /* 650 */ 1193, 1194, 373, 1093, 1192, 1193, 1194, 1192, 1193, 1194,
164033
+ /* 660 */ 565, 455, 32, 373, 233, 125, 126, 80, 1217, 1217,
164034
+ /* 670 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164035
+ /* 680 */ 1433, 959, 568, 228, 958, 122, 122, 122, 122, 121,
164036
+ /* 690 */ 121, 120, 120, 120, 119, 116, 444, 1158, 228, 1192,
164037
+ /* 700 */ 157, 1192, 1193, 1194, 1553, 13, 13, 301, 957, 1232,
164038
+ /* 710 */ 1158, 153, 409, 1158, 373, 1583, 1176, 5, 369, 1580,
164039
+ /* 720 */ 429, 1238, 3, 957, 122, 122, 122, 122, 121, 121,
164040
+ /* 730 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164041
+ /* 740 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164042
+ /* 750 */ 124, 409, 208, 567, 1192, 1028, 1192, 1193, 1194, 1192,
164043
+ /* 760 */ 388, 852, 155, 1552, 286, 402, 1098, 1098, 488, 568,
164044
+ /* 770 */ 465, 342, 1319, 1319, 1552, 125, 126, 80, 1217, 1217,
164045
+ /* 780 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164046
+ /* 790 */ 129, 568, 13, 13, 374, 122, 122, 122, 122, 121,
164047
+ /* 800 */ 121, 120, 120, 120, 119, 116, 444, 302, 568, 453,
164048
+ /* 810 */ 528, 1192, 1193, 1194, 13, 13, 1192, 1193, 1194, 1297,
164049
+ /* 820 */ 463, 1267, 409, 1317, 1317, 1552, 1012, 453, 452, 200,
164050
+ /* 830 */ 299, 71, 71, 1265, 122, 122, 122, 122, 121, 121,
164051
+ /* 840 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164052
+ /* 850 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164053
+ /* 860 */ 124, 409, 227, 1073, 1158, 284, 284, 419, 312, 278,
164054
+ /* 870 */ 278, 285, 285, 1419, 406, 405, 382, 1158, 565, 568,
164055
+ /* 880 */ 1158, 1196, 565, 1600, 565, 125, 126, 80, 1217, 1217,
164056
+ /* 890 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164057
+ /* 900 */ 453, 1482, 13, 13, 1536, 122, 122, 122, 122, 121,
164058
+ /* 910 */ 121, 120, 120, 120, 119, 116, 444, 201, 568, 354,
164059
+ /* 920 */ 1586, 575, 2, 1245, 840, 841, 842, 1562, 317, 1212,
164060
+ /* 930 */ 146, 6, 409, 255, 254, 253, 206, 1327, 9, 1196,
164061
+ /* 940 */ 262, 71, 71, 424, 122, 122, 122, 122, 121, 121,
164062
+ /* 950 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164063
+ /* 960 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164064
+ /* 970 */ 124, 568, 284, 284, 568, 1213, 409, 574, 313, 1245,
164065
+ /* 980 */ 349, 1296, 352, 419, 317, 565, 146, 491, 525, 1643,
164066
+ /* 990 */ 395, 371, 491, 1327, 70, 70, 1295, 71, 71, 240,
164067
+ /* 1000 */ 1325, 104, 80, 1217, 1217, 1050, 1053, 1040, 1040, 123,
164068
+ /* 1010 */ 123, 124, 124, 124, 124, 122, 122, 122, 122, 121,
164069
+ /* 1020 */ 121, 120, 120, 120, 119, 116, 444, 1114, 284, 284,
164070
+ /* 1030 */ 428, 448, 1525, 1213, 439, 284, 284, 1489, 1352, 311,
164071
+ /* 1040 */ 474, 565, 1115, 971, 491, 491, 217, 1263, 565, 1538,
164072
+ /* 1050 */ 568, 972, 207, 568, 1027, 240, 383, 1116, 519, 122,
164073
+ /* 1060 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116,
164074
+ /* 1070 */ 444, 1018, 107, 71, 71, 1017, 13, 13, 912, 568,
164075
+ /* 1080 */ 1495, 568, 284, 284, 97, 526, 491, 448, 913, 1326,
164076
+ /* 1090 */ 1322, 545, 409, 284, 284, 565, 151, 209, 1495, 1497,
164077
+ /* 1100 */ 262, 450, 55, 55, 56, 56, 565, 1017, 1017, 1019,
164078
+ /* 1110 */ 443, 332, 409, 527, 12, 295, 125, 126, 80, 1217,
164079
+ /* 1120 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164080
+ /* 1130 */ 124, 347, 409, 864, 1534, 1213, 125, 126, 80, 1217,
164081
+ /* 1140 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164082
+ /* 1150 */ 124, 1137, 1641, 474, 1641, 371, 125, 114, 80, 1217,
164083
+ /* 1160 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164084
+ /* 1170 */ 124, 1495, 329, 474, 331, 122, 122, 122, 122, 121,
164085
+ /* 1180 */ 121, 120, 120, 120, 119, 116, 444, 203, 1419, 568,
164086
+ /* 1190 */ 1294, 864, 464, 1213, 436, 122, 122, 122, 122, 121,
164087
+ /* 1200 */ 121, 120, 120, 120, 119, 116, 444, 553, 1137, 1642,
164088
+ /* 1210 */ 539, 1642, 15, 15, 892, 122, 122, 122, 122, 121,
164089
+ /* 1220 */ 121, 120, 120, 120, 119, 116, 444, 568, 298, 538,
164090
+ /* 1230 */ 1135, 1419, 1559, 1560, 1331, 409, 6, 6, 1169, 1268,
164091
+ /* 1240 */ 415, 320, 284, 284, 1419, 508, 565, 525, 300, 457,
164092
+ /* 1250 */ 43, 43, 568, 893, 12, 565, 330, 478, 425, 407,
164093
+ /* 1260 */ 126, 80, 1217, 1217, 1050, 1053, 1040, 1040, 123, 123,
164094
+ /* 1270 */ 124, 124, 124, 124, 568, 57, 57, 288, 1192, 1419,
164095
+ /* 1280 */ 496, 458, 392, 392, 391, 273, 389, 1135, 1558, 849,
164096
+ /* 1290 */ 1169, 407, 6, 568, 321, 1158, 470, 44, 44, 1557,
164097
+ /* 1300 */ 1114, 426, 234, 6, 323, 256, 540, 256, 1158, 431,
164098
+ /* 1310 */ 568, 1158, 322, 17, 487, 1115, 58, 58, 122, 122,
164099
+ /* 1320 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 444,
164100
+ /* 1330 */ 1116, 216, 481, 59, 59, 1192, 1193, 1194, 111, 560,
164101
+ /* 1340 */ 324, 4, 236, 456, 526, 568, 237, 456, 568, 437,
164102
+ /* 1350 */ 168, 556, 420, 141, 479, 563, 568, 293, 568, 1095,
164103
+ /* 1360 */ 568, 293, 568, 1095, 531, 568, 872, 8, 60, 60,
164104
+ /* 1370 */ 235, 61, 61, 568, 414, 568, 414, 568, 445, 62,
164105
+ /* 1380 */ 62, 45, 45, 46, 46, 47, 47, 199, 49, 49,
164106
+ /* 1390 */ 557, 568, 359, 568, 100, 486, 50, 50, 63, 63,
164107
+ /* 1400 */ 64, 64, 561, 415, 535, 410, 568, 1027, 568, 534,
164108
+ /* 1410 */ 316, 559, 316, 559, 65, 65, 14, 14, 568, 1027,
164109
+ /* 1420 */ 568, 512, 932, 872, 1018, 109, 109, 931, 1017, 66,
164110
+ /* 1430 */ 66, 131, 131, 110, 451, 445, 570, 569, 416, 177,
164111
+ /* 1440 */ 1017, 132, 132, 67, 67, 568, 467, 568, 932, 471,
164112
+ /* 1450 */ 1364, 283, 226, 931, 315, 1363, 407, 568, 459, 407,
164113
+ /* 1460 */ 1017, 1017, 1019, 239, 407, 86, 213, 1350, 52, 52,
164114
+ /* 1470 */ 68, 68, 1017, 1017, 1019, 1020, 27, 1585, 1180, 447,
164115
+ /* 1480 */ 69, 69, 288, 97, 108, 1541, 106, 392, 392, 391,
164116
+ /* 1490 */ 273, 389, 568, 879, 849, 883, 568, 111, 560, 466,
164117
+ /* 1500 */ 4, 568, 152, 30, 38, 568, 1132, 234, 396, 323,
164118
+ /* 1510 */ 111, 560, 527, 4, 563, 53, 53, 322, 568, 163,
164119
+ /* 1520 */ 163, 568, 337, 468, 164, 164, 333, 563, 76, 76,
164120
+ /* 1530 */ 568, 289, 1514, 568, 31, 1513, 568, 445, 338, 483,
164121
+ /* 1540 */ 100, 54, 54, 344, 72, 72, 296, 236, 1080, 557,
164122
+ /* 1550 */ 445, 879, 1360, 134, 134, 168, 73, 73, 141, 161,
164123
+ /* 1560 */ 161, 1574, 557, 535, 568, 319, 568, 348, 536, 1009,
164124
+ /* 1570 */ 473, 261, 261, 891, 890, 235, 535, 568, 1027, 568,
164125
+ /* 1580 */ 475, 534, 261, 367, 109, 109, 521, 136, 136, 130,
164126
+ /* 1590 */ 130, 1027, 110, 366, 445, 570, 569, 109, 109, 1017,
164127
+ /* 1600 */ 162, 162, 156, 156, 568, 110, 1080, 445, 570, 569,
164128
+ /* 1610 */ 410, 351, 1017, 568, 353, 316, 559, 568, 343, 568,
164129
+ /* 1620 */ 100, 497, 357, 258, 100, 898, 899, 140, 140, 355,
164130
+ /* 1630 */ 1310, 1017, 1017, 1019, 1020, 27, 139, 139, 362, 451,
164131
+ /* 1640 */ 137, 137, 138, 138, 1017, 1017, 1019, 1020, 27, 1180,
164132
+ /* 1650 */ 447, 568, 372, 288, 111, 560, 1021, 4, 392, 392,
164133
+ /* 1660 */ 391, 273, 389, 568, 1141, 849, 568, 1076, 568, 258,
164134
+ /* 1670 */ 492, 563, 568, 211, 75, 75, 555, 962, 234, 261,
164135
+ /* 1680 */ 323, 111, 560, 929, 4, 113, 77, 77, 322, 74,
164136
+ /* 1690 */ 74, 42, 42, 1373, 445, 48, 48, 1418, 563, 974,
164137
+ /* 1700 */ 975, 1092, 1091, 1092, 1091, 862, 557, 150, 930, 1346,
164138
+ /* 1710 */ 113, 1358, 554, 1424, 1021, 1275, 1266, 1254, 236, 1253,
164139
+ /* 1720 */ 1255, 445, 1593, 1343, 308, 276, 168, 309, 11, 141,
164140
+ /* 1730 */ 393, 310, 232, 557, 1405, 1027, 335, 291, 1400, 219,
164141
+ /* 1740 */ 336, 109, 109, 936, 297, 1410, 235, 341, 477, 110,
164142
+ /* 1750 */ 502, 445, 570, 569, 1393, 1409, 1017, 400, 1293, 365,
164143
+ /* 1760 */ 223, 1486, 1027, 1485, 1355, 1356, 1354, 1353, 109, 109,
164144
+ /* 1770 */ 204, 1596, 1232, 558, 265, 218, 110, 205, 445, 570,
164145
+ /* 1780 */ 569, 410, 387, 1017, 1533, 179, 316, 559, 1017, 1017,
164146
+ /* 1790 */ 1019, 1020, 27, 230, 1531, 1229, 79, 560, 85, 4,
164147
+ /* 1800 */ 418, 215, 548, 81, 84, 188, 1406, 173, 181, 461,
164148
+ /* 1810 */ 451, 35, 462, 563, 183, 1017, 1017, 1019, 1020, 27,
164149
+ /* 1820 */ 184, 1491, 185, 186, 495, 242, 98, 398, 1412, 36,
164150
+ /* 1830 */ 1411, 484, 91, 469, 401, 1414, 445, 192, 1480, 246,
164151
+ /* 1840 */ 1502, 490, 346, 277, 248, 196, 493, 511, 557, 350,
164152
+ /* 1850 */ 1256, 249, 250, 403, 1313, 1312, 111, 560, 432, 4,
164153
+ /* 1860 */ 1311, 1304, 93, 1611, 883, 1610, 224, 404, 434, 520,
164154
+ /* 1870 */ 263, 435, 1579, 563, 1283, 1282, 364, 1027, 306, 1281,
164155
+ /* 1880 */ 264, 1609, 1565, 109, 109, 370, 1303, 307, 1564, 438,
164156
+ /* 1890 */ 128, 110, 1378, 445, 570, 569, 445, 546, 1017, 10,
164157
+ /* 1900 */ 1466, 105, 381, 1377, 34, 572, 99, 1336, 557, 314,
164158
+ /* 1910 */ 1186, 530, 272, 274, 379, 210, 1335, 547, 385, 386,
164159
+ /* 1920 */ 275, 573, 1251, 1246, 411, 412, 1518, 165, 178, 1519,
164160
+ /* 1930 */ 1017, 1017, 1019, 1020, 27, 1517, 1516, 1027, 78, 147,
164161
+ /* 1940 */ 166, 220, 221, 109, 109, 836, 304, 167, 446, 212,
164162
+ /* 1950 */ 318, 110, 231, 445, 570, 569, 144, 1090, 1017, 1088,
164163
+ /* 1960 */ 326, 180, 169, 1212, 182, 334, 238, 915, 241, 1104,
164164
+ /* 1970 */ 187, 170, 171, 421, 87, 88, 423, 189, 89, 90,
164165
+ /* 1980 */ 172, 1107, 243, 1103, 244, 158, 18, 245, 345, 247,
164166
+ /* 1990 */ 1017, 1017, 1019, 1020, 27, 261, 1096, 193, 1226, 489,
164167
+ /* 2000 */ 194, 37, 366, 851, 494, 251, 195, 506, 92, 19,
164168
+ /* 2010 */ 498, 358, 20, 503, 881, 361, 94, 894, 305, 159,
164169
+ /* 2020 */ 513, 39, 95, 1174, 160, 1056, 966, 1143, 96, 174,
164170
+ /* 2030 */ 1142, 225, 280, 282, 198, 960, 113, 1164, 1160, 260,
164171
+ /* 2040 */ 21, 22, 23, 1162, 1168, 1167, 1148, 24, 33, 25,
164172
+ /* 2050 */ 202, 542, 26, 100, 1071, 102, 1057, 103, 7, 1055,
164173
+ /* 2060 */ 1059, 1113, 1060, 1112, 266, 267, 28, 40, 390, 1022,
164174
+ /* 2070 */ 863, 112, 29, 564, 1182, 1181, 268, 176, 143, 925,
164175
+ /* 2080 */ 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
164176
+ /* 2090 */ 1242, 1242, 1242, 1242, 269, 1602, 1242, 1601,
163954164177
};
163955164178
static const YYCODETYPE yy_lookahead[] = {
163956164179
/* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276,
163957164180
/* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19,
163958164181
/* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216,
@@ -164114,57 +164337,57 @@
164114164337
/* 1580 */ 23, 90, 25, 121, 106, 107, 19, 216, 217, 216,
164115164338
/* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121,
164116164339
/* 1600 */ 216, 217, 216, 217, 193, 114, 117, 116, 117, 118,
164117164340
/* 1610 */ 133, 193, 121, 193, 193, 138, 139, 193, 23, 193,
164118164341
/* 1620 */ 25, 23, 23, 25, 25, 7, 8, 216, 217, 193,
164119
- /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 59, 162,
164342
+ /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 193, 162,
164120164343
/* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1,
164121
- /* 1650 */ 2, 193, 193, 5, 19, 20, 193, 22, 10, 11,
164122
- /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 23, 25,
164123
- /* 1670 */ 25, 36, 83, 84, 216, 217, 236, 23, 30, 25,
164124
- /* 1680 */ 32, 19, 20, 153, 22, 155, 216, 217, 40, 216,
164125
- /* 1690 */ 217, 153, 193, 155, 59, 23, 117, 25, 36, 23,
164126
- /* 1700 */ 193, 25, 193, 193, 193, 193, 71, 193, 242, 193,
164127
- /* 1710 */ 193, 193, 193, 193, 243, 288, 287, 214, 70, 255,
164128
- /* 1720 */ 255, 59, 255, 255, 191, 297, 78, 271, 267, 81,
164129
- /* 1730 */ 245, 293, 246, 71, 246, 100, 267, 245, 293, 249,
164130
- /* 1740 */ 219, 106, 107, 108, 220, 271, 98, 271, 225, 114,
164131
- /* 1750 */ 271, 116, 117, 118, 229, 219, 121, 259, 219, 259,
164132
- /* 1760 */ 259, 259, 100, 60, 280, 196, 141, 38, 106, 107,
164133
- /* 1770 */ 200, 249, 245, 200, 243, 200, 114, 151, 116, 117,
164134
- /* 1780 */ 118, 133, 150, 121, 297, 272, 138, 139, 153, 154,
164135
- /* 1790 */ 155, 156, 157, 297, 22, 43, 19, 20, 294, 22,
164136
- /* 1800 */ 294, 18, 270, 237, 200, 234, 18, 199, 149, 283,
164137
- /* 1810 */ 162, 237, 272, 36, 237, 153, 154, 155, 156, 157,
164138
- /* 1820 */ 237, 272, 246, 270, 246, 234, 246, 234, 246, 200,
164139
- /* 1830 */ 199, 158, 290, 62, 289, 199, 59, 200, 22, 200,
164140
- /* 1840 */ 221, 199, 221, 200, 64, 199, 115, 227, 71, 22,
164141
- /* 1850 */ 126, 218, 218, 165, 224, 227, 218, 24, 113, 305,
164142
- /* 1860 */ 312, 200, 221, 282, 224, 218, 282, 91, 218, 220,
164143
- /* 1870 */ 218, 218, 221, 317, 82, 317, 265, 100, 265, 145,
164144
- /* 1880 */ 148, 22, 277, 106, 107, 200, 158, 147, 279, 146,
164145
- /* 1890 */ 25, 114, 202, 116, 117, 118, 13, 6, 121, 194,
164146
- /* 1900 */ 194, 192, 192, 192, 248, 250, 249, 247, 250, 246,
164147
- /* 1910 */ 303, 207, 300, 303, 213, 213, 222, 222, 4, 207,
164148
- /* 1920 */ 213, 213, 207, 3, 22, 163, 15, 214, 214, 213,
164149
- /* 1930 */ 153, 154, 155, 156, 157, 16, 23, 139, 23, 130,
164150
- /* 1940 */ 151, 25, 24, 142, 20, 16, 144, 1, 142, 130,
164151
- /* 1950 */ 130, 61, 53, 53, 37, 151, 53, 53, 130, 116,
164152
- /* 1960 */ 34, 1, 141, 5, 22, 115, 161, 75, 25, 68,
164153
- /* 1970 */ 141, 41, 115, 68, 24, 20, 19, 131, 125, 67,
164154
- /* 1980 */ 24, 22, 59, 22, 22, 96, 23, 22, 67, 22,
164155
- /* 1990 */ 37, 23, 28, 149, 67, 22, 25, 23, 23, 23,
164156
- /* 2000 */ 23, 22, 141, 97, 23, 23, 34, 22, 25, 116,
164157
- /* 2010 */ 143, 75, 34, 88, 34, 75, 23, 86, 34, 22,
164158
- /* 2020 */ 34, 93, 34, 24, 34, 25, 25, 23, 23, 23,
164159
- /* 2030 */ 23, 44, 23, 25, 23, 22, 11, 22, 22, 25,
164160
- /* 2040 */ 23, 23, 22, 22, 135, 15, 23, 25, 141, 141,
164161
- /* 2050 */ 1, 141, 1, 319, 319, 319, 319, 319, 319, 319,
164162
- /* 2060 */ 319, 319, 319, 141, 319, 319, 319, 319, 319, 319,
164163
- /* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164344
+ /* 1650 */ 2, 193, 193, 5, 19, 20, 59, 22, 10, 11,
164345
+ /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 193, 25,
164346
+ /* 1670 */ 288, 36, 193, 242, 216, 217, 236, 23, 30, 25,
164347
+ /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216,
164348
+ /* 1690 */ 217, 216, 217, 193, 59, 216, 217, 193, 36, 83,
164349
+ /* 1700 */ 84, 153, 153, 155, 155, 23, 71, 25, 23, 193,
164350
+ /* 1710 */ 25, 193, 193, 193, 117, 193, 193, 193, 70, 193,
164351
+ /* 1720 */ 193, 59, 193, 255, 255, 287, 78, 255, 243, 81,
164352
+ /* 1730 */ 191, 255, 297, 71, 271, 100, 293, 245, 267, 214,
164353
+ /* 1740 */ 246, 106, 107, 108, 246, 271, 98, 245, 293, 114,
164354
+ /* 1750 */ 220, 116, 117, 118, 267, 271, 121, 271, 225, 219,
164355
+ /* 1760 */ 229, 219, 100, 219, 259, 259, 259, 259, 106, 107,
164356
+ /* 1770 */ 249, 196, 60, 280, 141, 243, 114, 249, 116, 117,
164357
+ /* 1780 */ 118, 133, 245, 121, 200, 297, 138, 139, 153, 154,
164358
+ /* 1790 */ 155, 156, 157, 297, 200, 38, 19, 20, 151, 22,
164359
+ /* 1800 */ 200, 150, 140, 294, 294, 22, 272, 43, 234, 18,
164360
+ /* 1810 */ 162, 270, 200, 36, 237, 153, 154, 155, 156, 157,
164361
+ /* 1820 */ 237, 283, 237, 237, 18, 199, 149, 246, 272, 270,
164362
+ /* 1830 */ 272, 200, 158, 246, 246, 234, 59, 234, 246, 199,
164363
+ /* 1840 */ 290, 62, 289, 200, 199, 22, 221, 115, 71, 200,
164364
+ /* 1850 */ 200, 199, 199, 221, 218, 218, 19, 20, 64, 22,
164365
+ /* 1860 */ 218, 227, 22, 224, 126, 224, 165, 221, 24, 305,
164366
+ /* 1870 */ 200, 113, 312, 36, 218, 220, 218, 100, 282, 218,
164367
+ /* 1880 */ 91, 218, 317, 106, 107, 221, 227, 282, 317, 82,
164368
+ /* 1890 */ 148, 114, 265, 116, 117, 118, 59, 145, 121, 22,
164369
+ /* 1900 */ 277, 158, 200, 265, 25, 202, 147, 250, 71, 279,
164370
+ /* 1910 */ 13, 146, 194, 194, 249, 248, 250, 140, 247, 246,
164371
+ /* 1920 */ 6, 192, 192, 192, 303, 303, 213, 207, 300, 213,
164372
+ /* 1930 */ 153, 154, 155, 156, 157, 213, 213, 100, 213, 222,
164373
+ /* 1940 */ 207, 214, 214, 106, 107, 4, 222, 207, 3, 22,
164374
+ /* 1950 */ 163, 114, 15, 116, 117, 118, 16, 23, 121, 23,
164375
+ /* 1960 */ 139, 151, 130, 25, 142, 16, 24, 20, 144, 1,
164376
+ /* 1970 */ 142, 130, 130, 61, 53, 53, 37, 151, 53, 53,
164377
+ /* 1980 */ 130, 116, 34, 1, 141, 5, 22, 115, 161, 141,
164378
+ /* 1990 */ 153, 154, 155, 156, 157, 25, 68, 68, 75, 41,
164379
+ /* 2000 */ 115, 24, 131, 20, 19, 125, 22, 96, 22, 22,
164380
+ /* 2010 */ 67, 23, 22, 67, 59, 24, 22, 28, 67, 23,
164381
+ /* 2020 */ 22, 22, 149, 23, 23, 23, 116, 23, 25, 37,
164382
+ /* 2030 */ 97, 141, 23, 23, 22, 143, 25, 75, 88, 34,
164383
+ /* 2040 */ 34, 34, 34, 86, 75, 93, 23, 34, 22, 34,
164384
+ /* 2050 */ 25, 24, 34, 25, 23, 142, 23, 142, 44, 23,
164385
+ /* 2060 */ 23, 23, 11, 23, 25, 22, 22, 22, 15, 23,
164386
+ /* 2070 */ 23, 22, 22, 25, 1, 1, 141, 25, 23, 135,
164164164387
/* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164165
- /* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164388
+ /* 2090 */ 319, 319, 319, 319, 141, 141, 319, 141, 319, 319,
164166164389
/* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164167164390
/* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164168164391
/* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164169164392
/* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164170164393
/* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
@@ -164175,77 +164398,82 @@
164175164398
/* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164176164399
/* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164177164400
/* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164178164401
/* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164179164402
/* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164180
- /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319,
164403
+ /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164404
+ /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164405
+ /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164406
+ /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164407
+ /* 2280 */ 319, 319, 319,
164181164408
};
164182
-#define YY_SHIFT_COUNT (569)
164409
+#define YY_SHIFT_COUNT (575)
164183164410
#define YY_SHIFT_MIN (0)
164184
-#define YY_SHIFT_MAX (2051)
164411
+#define YY_SHIFT_MAX (2074)
164185164412
static const unsigned short int yy_shift_ofst[] = {
164186
- /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1662,
164187
- /* 10 */ 1662, 1662, 471, 0, 0, 214, 1093, 1662, 1662, 1662,
164188
- /* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164413
+ /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837,
164414
+ /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837,
164415
+ /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164189164416
/* 30 */ 271, 271, 1219, 1219, 216, 88, 1, 1, 1, 1,
164190164417
/* 40 */ 1, 40, 111, 258, 361, 469, 512, 583, 622, 693,
164191164418
/* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093,
164192164419
/* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
164193164420
/* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662,
164194
- /* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164195
- /* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164196
- /* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164197
- /* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662,
164198
- /* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181,
164199
- /* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366,
164200
- /* 140 */ 533, 533, 740, 1261, 533, 533, 79, 79, 533, 412,
164201
- /* 150 */ 412, 412, 77, 412, 123, 113, 113, 22, 22, 2064,
164202
- /* 160 */ 2064, 328, 328, 328, 239, 468, 468, 468, 468, 1015,
164203
- /* 170 */ 1015, 409, 366, 1129, 1186, 533, 533, 533, 533, 533,
164421
+ /* 80 */ 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164422
+ /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164423
+ /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164424
+ /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164425
+ /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164426
+ /* 130 */ 137, 181, 181, 181, 181, 181, 181, 181, 94, 430,
164427
+ /* 140 */ 66, 65, 112, 366, 533, 533, 740, 1261, 533, 533,
164428
+ /* 150 */ 79, 79, 533, 412, 412, 412, 77, 412, 123, 113,
164429
+ /* 160 */ 113, 22, 22, 2098, 2098, 328, 328, 328, 239, 468,
164430
+ /* 170 */ 468, 468, 468, 1015, 1015, 409, 366, 1129, 1186, 533,
164204164431
/* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
164205
- /* 190 */ 533, 533, 533, 533, 533, 969, 621, 621, 533, 642,
164206
- /* 200 */ 788, 788, 1228, 1228, 822, 822, 67, 1274, 2064, 2064,
164207
- /* 210 */ 2064, 2064, 2064, 2064, 2064, 1307, 954, 954, 585, 472,
164208
- /* 220 */ 640, 387, 695, 538, 541, 700, 533, 533, 533, 533,
164209
- /* 230 */ 533, 533, 533, 533, 533, 533, 222, 533, 533, 533,
164210
- /* 240 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 1179,
164211
- /* 250 */ 1179, 1179, 533, 533, 533, 565, 533, 533, 533, 916,
164212
- /* 260 */ 1144, 533, 533, 1288, 533, 533, 533, 533, 533, 533,
164213
- /* 270 */ 533, 533, 639, 1330, 209, 1076, 1076, 1076, 1076, 580,
164214
- /* 280 */ 209, 209, 1313, 768, 917, 649, 1181, 1316, 405, 1316,
164215
- /* 290 */ 1238, 249, 1181, 1181, 249, 1181, 405, 1238, 1369, 464,
164216
- /* 300 */ 1259, 1012, 1012, 1012, 1368, 1368, 1368, 1368, 184, 184,
164217
- /* 310 */ 1326, 904, 1287, 1480, 1703, 1703, 1625, 1625, 1729, 1729,
164218
- /* 320 */ 1625, 1626, 1632, 1772, 1752, 1783, 1783, 1783, 1783, 1625,
164219
- /* 330 */ 1788, 1659, 1632, 1632, 1659, 1772, 1752, 1659, 1752, 1659,
164220
- /* 340 */ 1625, 1788, 1673, 1771, 1625, 1788, 1816, 1625, 1788, 1625,
164221
- /* 350 */ 1788, 1816, 1731, 1731, 1731, 1780, 1827, 1827, 1816, 1731,
164222
- /* 360 */ 1724, 1731, 1780, 1731, 1731, 1688, 1833, 1745, 1745, 1816,
164223
- /* 370 */ 1625, 1776, 1776, 1792, 1792, 1732, 1734, 1859, 1625, 1728,
164224
- /* 380 */ 1732, 1740, 1743, 1659, 1865, 1883, 1883, 1891, 1891, 1891,
164225
- /* 390 */ 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064,
164226
- /* 400 */ 2064, 2064, 2064, 2064, 2064, 207, 1095, 331, 620, 903,
164227
- /* 410 */ 806, 1074, 1483, 1432, 1481, 1322, 1370, 1394, 1515, 1291,
164228
- /* 420 */ 1546, 1547, 1557, 1595, 1598, 1599, 1434, 1453, 1618, 1462,
164229
- /* 430 */ 1567, 1489, 1644, 1645, 1589, 1654, 1530, 1538, 1672, 1676,
164230
- /* 440 */ 1579, 742, 1914, 1920, 1902, 1762, 1911, 1919, 1913, 1915,
164231
- /* 450 */ 1798, 1789, 1809, 1916, 1916, 1918, 1801, 1924, 1802, 1929,
164232
- /* 460 */ 1946, 1806, 1819, 1916, 1820, 1890, 1917, 1916, 1804, 1899,
164233
- /* 470 */ 1900, 1903, 1904, 1828, 1843, 1926, 1821, 1960, 1958, 1942,
164234
- /* 480 */ 1850, 1805, 1901, 1943, 1905, 1892, 1930, 1829, 1857, 1950,
164235
- /* 490 */ 1955, 1957, 1846, 1853, 1959, 1912, 1961, 1962, 1963, 1965,
164236
- /* 500 */ 1921, 1923, 1956, 1889, 1964, 1967, 1927, 1953, 1968, 1844,
164237
- /* 510 */ 1973, 1974, 1975, 1976, 1971, 1977, 1979, 1906, 1861, 1981,
164238
- /* 520 */ 1982, 1893, 1972, 1985, 1867, 1983, 1978, 1980, 1984, 1986,
164239
- /* 530 */ 1925, 1936, 1931, 1987, 1940, 1928, 1988, 1993, 1997, 1999,
164240
- /* 540 */ 2000, 2001, 1990, 2004, 1983, 2005, 2006, 2007, 2009, 2008,
164241
- /* 550 */ 2011, 2013, 2025, 2015, 2016, 2017, 2018, 2020, 2021, 2014,
164242
- /* 560 */ 1909, 1907, 1908, 1910, 1922, 2022, 2023, 2030, 2049, 2051,
164432
+ /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 969,
164433
+ /* 200 */ 621, 621, 533, 642, 788, 788, 1228, 1228, 822, 822,
164434
+ /* 210 */ 67, 1274, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 1307,
164435
+ /* 220 */ 954, 954, 585, 472, 640, 387, 695, 538, 541, 700,
164436
+ /* 230 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
164437
+ /* 240 */ 222, 533, 533, 533, 533, 533, 533, 533, 533, 533,
164438
+ /* 250 */ 533, 533, 533, 1179, 1179, 1179, 533, 533, 533, 565,
164439
+ /* 260 */ 533, 533, 533, 916, 1144, 533, 533, 1288, 533, 533,
164440
+ /* 270 */ 533, 533, 533, 533, 533, 533, 639, 1330, 209, 1076,
164441
+ /* 280 */ 1076, 1076, 1076, 580, 209, 209, 1313, 768, 917, 649,
164442
+ /* 290 */ 1181, 1316, 405, 1316, 1238, 249, 1181, 1181, 249, 1181,
164443
+ /* 300 */ 405, 1238, 1369, 464, 1259, 1012, 1012, 1012, 1368, 1368,
164444
+ /* 310 */ 1368, 1368, 184, 184, 1326, 904, 1287, 1480, 1712, 1712,
164445
+ /* 320 */ 1633, 1633, 1757, 1757, 1633, 1647, 1651, 1783, 1764, 1791,
164446
+ /* 330 */ 1791, 1791, 1791, 1633, 1806, 1677, 1651, 1651, 1677, 1783,
164447
+ /* 340 */ 1764, 1677, 1764, 1677, 1633, 1806, 1674, 1779, 1633, 1806,
164448
+ /* 350 */ 1823, 1633, 1806, 1633, 1806, 1823, 1732, 1732, 1732, 1794,
164449
+ /* 360 */ 1840, 1840, 1823, 1732, 1738, 1732, 1794, 1732, 1732, 1701,
164450
+ /* 370 */ 1844, 1758, 1758, 1823, 1633, 1789, 1789, 1807, 1807, 1742,
164451
+ /* 380 */ 1752, 1877, 1633, 1743, 1742, 1759, 1765, 1677, 1879, 1897,
164452
+ /* 390 */ 1897, 1914, 1914, 1914, 2098, 2098, 2098, 2098, 2098, 2098,
164453
+ /* 400 */ 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 207,
164454
+ /* 410 */ 1095, 331, 620, 903, 806, 1074, 1483, 1432, 1481, 1322,
164455
+ /* 420 */ 1370, 1394, 1515, 1291, 1546, 1547, 1557, 1595, 1598, 1599,
164456
+ /* 430 */ 1434, 1453, 1618, 1462, 1567, 1489, 1644, 1654, 1616, 1660,
164457
+ /* 440 */ 1548, 1549, 1682, 1685, 1597, 742, 1941, 1945, 1927, 1787,
164458
+ /* 450 */ 1937, 1940, 1934, 1936, 1821, 1810, 1832, 1938, 1938, 1942,
164459
+ /* 460 */ 1822, 1947, 1824, 1949, 1968, 1828, 1841, 1938, 1842, 1912,
164460
+ /* 470 */ 1939, 1938, 1826, 1921, 1922, 1925, 1926, 1850, 1865, 1948,
164461
+ /* 480 */ 1843, 1982, 1980, 1964, 1872, 1827, 1928, 1970, 1929, 1923,
164462
+ /* 490 */ 1958, 1848, 1885, 1977, 1983, 1985, 1871, 1880, 1984, 1943,
164463
+ /* 500 */ 1986, 1987, 1988, 1990, 1946, 1955, 1991, 1911, 1989, 1994,
164464
+ /* 510 */ 1951, 1992, 1996, 1873, 1998, 2000, 2001, 2002, 2003, 2004,
164465
+ /* 520 */ 1999, 1933, 1890, 2009, 2010, 1910, 2005, 2012, 1892, 2011,
164466
+ /* 530 */ 2006, 2007, 2008, 2013, 1950, 1962, 1957, 2014, 1969, 1952,
164467
+ /* 540 */ 2015, 2023, 2026, 2027, 2025, 2028, 2018, 1913, 1915, 2031,
164468
+ /* 550 */ 2011, 2033, 2036, 2037, 2038, 2039, 2040, 2043, 2051, 2044,
164469
+ /* 560 */ 2045, 2046, 2047, 2049, 2050, 2048, 1944, 1935, 1953, 1954,
164470
+ /* 570 */ 1956, 2052, 2055, 2053, 2073, 2074,
164243164471
};
164244
-#define YY_REDUCE_COUNT (404)
164472
+#define YY_REDUCE_COUNT (408)
164245164473
#define YY_REDUCE_MIN (-271)
164246
-#define YY_REDUCE_MAX (1716)
164474
+#define YY_REDUCE_MAX (1740)
164247164475
static const short yy_reduce_ofst[] = {
164248164476
/* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187,
164249164477
/* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489,
164250164478
/* 20 */ 576, -175, 598, 686, 615, 725, 860, 778, 781, 857,
164251164479
/* 30 */ 616, 887, 87, 240, -192, 408, 626, 796, 843, 854,
@@ -164255,98 +164483,99 @@
164255164483
/* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 80, 83,
164256164484
/* 80 */ 313, 886, 888, 996, 1034, 1059, 1081, 1100, 1117, 1152,
164257164485
/* 90 */ 1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198,
164258164486
/* 100 */ 1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303,
164259164487
/* 110 */ 1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384,
164260
- /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, -271, -271,
164261
- /* 130 */ -271, -271, -271, -271, -271, -271, -271, 138, 459, 396,
164262
- /* 140 */ -158, 470, 302, -212, 521, 201, -195, -92, 559, 630,
164263
- /* 150 */ 632, 630, -271, 632, 901, 63, 407, -271, -271, -271,
164264
- /* 160 */ -271, 161, 161, 161, 251, 335, 847, 960, 980, 537,
164265
- /* 170 */ 588, 618, 628, 688, 688, -166, -161, 674, 790, 794,
164266
- /* 180 */ 799, 851, 852, -122, 680, -120, 995, 1038, 415, 1051,
164267
- /* 190 */ 893, 798, 962, 400, 1086, 779, 923, 924, 263, 1041,
164268
- /* 200 */ 979, 990, 1083, 1097, 1031, 1194, 362, 994, 1139, 1005,
164269
- /* 210 */ 1037, 1202, 1205, 1195, 1210, -194, 56, 185, -135, 232,
164270
- /* 220 */ 522, 560, 601, 617, 669, 683, 711, 856, 908, 941,
164271
- /* 230 */ 1048, 1101, 1147, 1257, 1262, 1265, 392, 1292, 1333, 1339,
164272
- /* 240 */ 1342, 1346, 1350, 1359, 1374, 1418, 1421, 1436, 1437, 593,
164273
- /* 250 */ 755, 770, 997, 1459, 1463, 1209, 1499, 1507, 1509, 1132,
164274
- /* 260 */ 1243, 1510, 1511, 1440, 1512, 560, 1514, 1516, 1517, 1518,
164275
- /* 270 */ 1519, 1520, 1427, 1429, 1466, 1464, 1465, 1467, 1468, 1209,
164276
- /* 280 */ 1466, 1466, 1471, 1503, 1533, 1428, 1456, 1461, 1485, 1469,
164277
- /* 290 */ 1438, 1486, 1474, 1476, 1488, 1479, 1492, 1445, 1524, 1525,
164278
- /* 300 */ 1523, 1521, 1536, 1539, 1498, 1500, 1501, 1502, 1490, 1522,
164279
- /* 310 */ 1484, 1527, 1531, 1569, 1487, 1496, 1570, 1573, 1504, 1506,
164280
- /* 320 */ 1575, 1526, 1513, 1532, 1571, 1566, 1574, 1577, 1583, 1604,
164281
- /* 330 */ 1608, 1576, 1540, 1549, 1578, 1553, 1591, 1580, 1593, 1582,
164282
- /* 340 */ 1629, 1631, 1542, 1545, 1637, 1636, 1619, 1639, 1642, 1643,
164283
- /* 350 */ 1646, 1621, 1633, 1634, 1638, 1620, 1630, 1640, 1641, 1647,
164284
- /* 360 */ 1649, 1650, 1628, 1652, 1653, 1548, 1554, 1581, 1584, 1651,
164285
- /* 370 */ 1661, 1556, 1558, 1611, 1613, 1655, 1657, 1605, 1685, 1609,
164286
- /* 380 */ 1658, 1656, 1660, 1663, 1690, 1705, 1706, 1709, 1710, 1711,
164287
- /* 390 */ 1607, 1610, 1612, 1704, 1701, 1702, 1707, 1708, 1712, 1694,
164288
- /* 400 */ 1695, 1713, 1714, 1716, 1715,
164488
+ /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, 1475, 1479,
164489
+ /* 130 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
164490
+ /* 140 */ -271, 138, 459, 396, -158, 470, 302, -212, 521, 201,
164491
+ /* 150 */ -195, -92, 559, 630, 632, 630, -271, 632, 901, 63,
164492
+ /* 160 */ 407, -271, -271, -271, -271, 161, 161, 161, 251, 335,
164493
+ /* 170 */ 847, 960, 980, 537, 588, 618, 628, 688, 688, -166,
164494
+ /* 180 */ -161, 674, 790, 794, 799, 851, 852, -122, 680, -120,
164495
+ /* 190 */ 995, 1038, 415, 1051, 893, 798, 962, 400, 1086, 779,
164496
+ /* 200 */ 923, 924, 263, 1041, 979, 990, 1083, 1097, 1031, 1194,
164497
+ /* 210 */ 362, 994, 1139, 1005, 1037, 1202, 1205, 1195, 1210, -194,
164498
+ /* 220 */ 56, 185, -135, 232, 522, 560, 601, 617, 669, 683,
164499
+ /* 230 */ 711, 856, 908, 941, 1048, 1101, 1147, 1257, 1262, 1265,
164500
+ /* 240 */ 392, 1292, 1333, 1339, 1342, 1346, 1350, 1359, 1374, 1418,
164501
+ /* 250 */ 1421, 1436, 1437, 593, 755, 770, 997, 1445, 1459, 1209,
164502
+ /* 260 */ 1500, 1504, 1516, 1132, 1243, 1518, 1519, 1440, 1520, 560,
164503
+ /* 270 */ 1522, 1523, 1524, 1526, 1527, 1529, 1382, 1438, 1431, 1468,
164504
+ /* 280 */ 1469, 1472, 1476, 1209, 1431, 1431, 1485, 1525, 1539, 1435,
164505
+ /* 290 */ 1463, 1471, 1492, 1487, 1443, 1494, 1474, 1484, 1498, 1486,
164506
+ /* 300 */ 1502, 1455, 1530, 1531, 1533, 1540, 1542, 1544, 1505, 1506,
164507
+ /* 310 */ 1507, 1508, 1521, 1528, 1493, 1537, 1532, 1575, 1488, 1496,
164508
+ /* 320 */ 1584, 1594, 1509, 1510, 1600, 1538, 1534, 1541, 1574, 1577,
164509
+ /* 330 */ 1583, 1585, 1586, 1612, 1626, 1581, 1556, 1558, 1587, 1559,
164510
+ /* 340 */ 1601, 1588, 1603, 1592, 1631, 1640, 1550, 1553, 1643, 1645,
164511
+ /* 350 */ 1625, 1649, 1652, 1650, 1653, 1632, 1636, 1637, 1642, 1634,
164512
+ /* 360 */ 1639, 1641, 1646, 1656, 1655, 1658, 1659, 1661, 1663, 1560,
164513
+ /* 370 */ 1564, 1596, 1605, 1664, 1670, 1565, 1571, 1627, 1638, 1657,
164514
+ /* 380 */ 1665, 1623, 1702, 1630, 1666, 1667, 1671, 1673, 1703, 1718,
164515
+ /* 390 */ 1719, 1729, 1730, 1731, 1621, 1622, 1628, 1720, 1713, 1716,
164516
+ /* 400 */ 1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740,
164289164517
};
164290164518
static const YYACTIONTYPE yy_default[] = {
164291
- /* 0 */ 1637, 1637, 1637, 1465, 1232, 1343, 1232, 1232, 1232, 1465,
164292
- /* 10 */ 1465, 1465, 1232, 1373, 1373, 1518, 1265, 1232, 1232, 1232,
164293
- /* 20 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1464, 1232, 1232,
164294
- /* 30 */ 1232, 1232, 1553, 1553, 1232, 1232, 1232, 1232, 1232, 1232,
164295
- /* 40 */ 1232, 1232, 1382, 1232, 1389, 1232, 1232, 1232, 1232, 1232,
164296
- /* 50 */ 1466, 1467, 1232, 1232, 1232, 1517, 1519, 1482, 1396, 1395,
164297
- /* 60 */ 1394, 1393, 1500, 1361, 1387, 1380, 1384, 1460, 1461, 1459,
164298
- /* 70 */ 1463, 1467, 1466, 1232, 1383, 1430, 1444, 1429, 1232, 1232,
164299
- /* 80 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164300
- /* 90 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164301
- /* 100 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164302
- /* 110 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164303
- /* 120 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1438, 1443,
164304
- /* 130 */ 1450, 1442, 1439, 1432, 1431, 1433, 1434, 1232, 1232, 1256,
164305
- /* 140 */ 1232, 1232, 1253, 1307, 1232, 1232, 1232, 1232, 1232, 1537,
164306
- /* 150 */ 1536, 1232, 1435, 1232, 1265, 1424, 1423, 1447, 1436, 1446,
164307
- /* 160 */ 1445, 1525, 1589, 1588, 1483, 1232, 1232, 1232, 1232, 1232,
164308
- /* 170 */ 1232, 1553, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164309
- /* 180 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164310
- /* 190 */ 1232, 1232, 1232, 1232, 1232, 1363, 1553, 1553, 1232, 1265,
164311
- /* 200 */ 1553, 1553, 1364, 1364, 1261, 1261, 1367, 1232, 1532, 1334,
164312
- /* 210 */ 1334, 1334, 1334, 1343, 1334, 1232, 1232, 1232, 1232, 1232,
164313
- /* 220 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164314
- /* 230 */ 1522, 1520, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164315
- /* 240 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164316
- /* 250 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1339,
164317
- /* 260 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164318
- /* 270 */ 1232, 1582, 1232, 1495, 1321, 1339, 1339, 1339, 1339, 1341,
164319
- /* 280 */ 1322, 1320, 1333, 1266, 1239, 1629, 1399, 1388, 1340, 1388,
164320
- /* 290 */ 1626, 1386, 1399, 1399, 1386, 1399, 1340, 1626, 1282, 1605,
164321
- /* 300 */ 1277, 1373, 1373, 1373, 1363, 1363, 1363, 1363, 1367, 1367,
164322
- /* 310 */ 1462, 1340, 1333, 1232, 1629, 1629, 1349, 1349, 1628, 1628,
164323
- /* 320 */ 1349, 1483, 1613, 1408, 1310, 1316, 1316, 1316, 1316, 1349,
164324
- /* 330 */ 1250, 1386, 1613, 1613, 1386, 1408, 1310, 1386, 1310, 1386,
164325
- /* 340 */ 1349, 1250, 1499, 1623, 1349, 1250, 1473, 1349, 1250, 1349,
164326
- /* 350 */ 1250, 1473, 1308, 1308, 1308, 1297, 1232, 1232, 1473, 1308,
164327
- /* 360 */ 1282, 1308, 1297, 1308, 1308, 1571, 1232, 1477, 1477, 1473,
164328
- /* 370 */ 1349, 1563, 1563, 1376, 1376, 1381, 1367, 1468, 1349, 1232,
164329
- /* 380 */ 1381, 1379, 1377, 1386, 1300, 1585, 1585, 1581, 1581, 1581,
164330
- /* 390 */ 1634, 1634, 1532, 1598, 1265, 1265, 1265, 1265, 1598, 1284,
164331
- /* 400 */ 1284, 1266, 1266, 1265, 1598, 1232, 1232, 1232, 1232, 1232,
164332
- /* 410 */ 1232, 1593, 1232, 1527, 1484, 1353, 1232, 1232, 1232, 1232,
164333
- /* 420 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164334
- /* 430 */ 1538, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164335
- /* 440 */ 1232, 1413, 1232, 1235, 1529, 1232, 1232, 1232, 1232, 1232,
164336
- /* 450 */ 1232, 1232, 1232, 1390, 1391, 1354, 1232, 1232, 1232, 1232,
164337
- /* 460 */ 1232, 1232, 1232, 1405, 1232, 1232, 1232, 1400, 1232, 1232,
164338
- /* 470 */ 1232, 1232, 1232, 1232, 1232, 1232, 1625, 1232, 1232, 1232,
164339
- /* 480 */ 1232, 1232, 1232, 1498, 1497, 1232, 1232, 1351, 1232, 1232,
164340
- /* 490 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164341
- /* 500 */ 1232, 1280, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164342
- /* 510 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164343
- /* 520 */ 1232, 1232, 1232, 1232, 1232, 1378, 1232, 1232, 1232, 1232,
164344
- /* 530 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164345
- /* 540 */ 1568, 1368, 1232, 1232, 1616, 1232, 1232, 1232, 1232, 1232,
164346
- /* 550 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1609,
164347
- /* 560 */ 1324, 1415, 1232, 1414, 1418, 1254, 1232, 1244, 1232, 1232,
164519
+ /* 0 */ 1647, 1647, 1647, 1475, 1240, 1351, 1240, 1240, 1240, 1475,
164520
+ /* 10 */ 1475, 1475, 1240, 1381, 1381, 1528, 1273, 1240, 1240, 1240,
164521
+ /* 20 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1474, 1240, 1240,
164522
+ /* 30 */ 1240, 1240, 1563, 1563, 1240, 1240, 1240, 1240, 1240, 1240,
164523
+ /* 40 */ 1240, 1240, 1390, 1240, 1397, 1240, 1240, 1240, 1240, 1240,
164524
+ /* 50 */ 1476, 1477, 1240, 1240, 1240, 1527, 1529, 1492, 1404, 1403,
164525
+ /* 60 */ 1402, 1401, 1510, 1369, 1395, 1388, 1392, 1470, 1471, 1469,
164526
+ /* 70 */ 1473, 1477, 1476, 1240, 1391, 1438, 1454, 1437, 1240, 1240,
164527
+ /* 80 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164528
+ /* 90 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164529
+ /* 100 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164530
+ /* 110 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164531
+ /* 120 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164532
+ /* 130 */ 1446, 1453, 1452, 1451, 1460, 1450, 1447, 1440, 1439, 1441,
164533
+ /* 140 */ 1442, 1240, 1240, 1264, 1240, 1240, 1261, 1315, 1240, 1240,
164534
+ /* 150 */ 1240, 1240, 1240, 1547, 1546, 1240, 1443, 1240, 1273, 1432,
164535
+ /* 160 */ 1431, 1457, 1444, 1456, 1455, 1535, 1599, 1598, 1493, 1240,
164536
+ /* 170 */ 1240, 1240, 1240, 1240, 1240, 1563, 1240, 1240, 1240, 1240,
164537
+ /* 180 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164538
+ /* 190 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1371,
164539
+ /* 200 */ 1563, 1563, 1240, 1273, 1563, 1563, 1372, 1372, 1269, 1269,
164540
+ /* 210 */ 1375, 1240, 1542, 1342, 1342, 1342, 1342, 1351, 1342, 1240,
164541
+ /* 220 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164542
+ /* 230 */ 1240, 1240, 1240, 1240, 1532, 1530, 1240, 1240, 1240, 1240,
164543
+ /* 240 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164544
+ /* 250 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164545
+ /* 260 */ 1240, 1240, 1240, 1347, 1240, 1240, 1240, 1240, 1240, 1240,
164546
+ /* 270 */ 1240, 1240, 1240, 1240, 1240, 1592, 1240, 1505, 1329, 1347,
164547
+ /* 280 */ 1347, 1347, 1347, 1349, 1330, 1328, 1341, 1274, 1247, 1639,
164548
+ /* 290 */ 1407, 1396, 1348, 1396, 1636, 1394, 1407, 1407, 1394, 1407,
164549
+ /* 300 */ 1348, 1636, 1290, 1615, 1285, 1381, 1381, 1381, 1371, 1371,
164550
+ /* 310 */ 1371, 1371, 1375, 1375, 1472, 1348, 1341, 1240, 1639, 1639,
164551
+ /* 320 */ 1357, 1357, 1638, 1638, 1357, 1493, 1623, 1416, 1318, 1324,
164552
+ /* 330 */ 1324, 1324, 1324, 1357, 1258, 1394, 1623, 1623, 1394, 1416,
164553
+ /* 340 */ 1318, 1394, 1318, 1394, 1357, 1258, 1509, 1633, 1357, 1258,
164554
+ /* 350 */ 1483, 1357, 1258, 1357, 1258, 1483, 1316, 1316, 1316, 1305,
164555
+ /* 360 */ 1240, 1240, 1483, 1316, 1290, 1316, 1305, 1316, 1316, 1581,
164556
+ /* 370 */ 1240, 1487, 1487, 1483, 1357, 1573, 1573, 1384, 1384, 1389,
164557
+ /* 380 */ 1375, 1478, 1357, 1240, 1389, 1387, 1385, 1394, 1308, 1595,
164558
+ /* 390 */ 1595, 1591, 1591, 1591, 1644, 1644, 1542, 1608, 1273, 1273,
164559
+ /* 400 */ 1273, 1273, 1608, 1292, 1292, 1274, 1274, 1273, 1608, 1240,
164560
+ /* 410 */ 1240, 1240, 1240, 1240, 1240, 1603, 1240, 1537, 1494, 1361,
164561
+ /* 420 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164562
+ /* 430 */ 1240, 1240, 1240, 1240, 1548, 1240, 1240, 1240, 1240, 1240,
164563
+ /* 440 */ 1240, 1240, 1240, 1240, 1240, 1421, 1240, 1243, 1539, 1240,
164564
+ /* 450 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1398, 1399, 1362,
164565
+ /* 460 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1413, 1240, 1240,
164566
+ /* 470 */ 1240, 1408, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164567
+ /* 480 */ 1635, 1240, 1240, 1240, 1240, 1240, 1240, 1508, 1507, 1240,
164568
+ /* 490 */ 1240, 1359, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164569
+ /* 500 */ 1240, 1240, 1240, 1240, 1240, 1288, 1240, 1240, 1240, 1240,
164570
+ /* 510 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164571
+ /* 520 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1386,
164572
+ /* 530 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164573
+ /* 540 */ 1240, 1240, 1240, 1240, 1578, 1376, 1240, 1240, 1240, 1240,
164574
+ /* 550 */ 1626, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164575
+ /* 560 */ 1240, 1240, 1240, 1240, 1240, 1619, 1332, 1423, 1240, 1422,
164576
+ /* 570 */ 1426, 1262, 1240, 1252, 1240, 1240,
164348164577
};
164349164578
/********** End of lemon-generated parsing tables *****************************/
164350164579
164351164580
/* The next table maps tokens (terminal symbols) into fallback tokens.
164352164581
** If a construct like the following:
@@ -165170,204 +165399,206 @@
165170165399
/* 204 */ "expr ::= expr likeop expr ESCAPE expr",
165171165400
/* 205 */ "expr ::= expr ISNULL|NOTNULL",
165172165401
/* 206 */ "expr ::= expr NOT NULL",
165173165402
/* 207 */ "expr ::= expr IS expr",
165174165403
/* 208 */ "expr ::= expr IS NOT expr",
165175
- /* 209 */ "expr ::= NOT expr",
165176
- /* 210 */ "expr ::= BITNOT expr",
165177
- /* 211 */ "expr ::= PLUS|MINUS expr",
165178
- /* 212 */ "expr ::= expr PTR expr",
165179
- /* 213 */ "between_op ::= BETWEEN",
165180
- /* 214 */ "between_op ::= NOT BETWEEN",
165181
- /* 215 */ "expr ::= expr between_op expr AND expr",
165182
- /* 216 */ "in_op ::= IN",
165183
- /* 217 */ "in_op ::= NOT IN",
165184
- /* 218 */ "expr ::= expr in_op LP exprlist RP",
165185
- /* 219 */ "expr ::= LP select RP",
165186
- /* 220 */ "expr ::= expr in_op LP select RP",
165187
- /* 221 */ "expr ::= expr in_op nm dbnm paren_exprlist",
165188
- /* 222 */ "expr ::= EXISTS LP select RP",
165189
- /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END",
165190
- /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
165191
- /* 225 */ "case_exprlist ::= WHEN expr THEN expr",
165192
- /* 226 */ "case_else ::= ELSE expr",
165193
- /* 227 */ "case_else ::=",
165194
- /* 228 */ "case_operand ::= expr",
165195
- /* 229 */ "case_operand ::=",
165196
- /* 230 */ "exprlist ::=",
165197
- /* 231 */ "nexprlist ::= nexprlist COMMA expr",
165198
- /* 232 */ "nexprlist ::= expr",
165199
- /* 233 */ "paren_exprlist ::=",
165200
- /* 234 */ "paren_exprlist ::= LP exprlist RP",
165201
- /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
165202
- /* 236 */ "uniqueflag ::= UNIQUE",
165203
- /* 237 */ "uniqueflag ::=",
165204
- /* 238 */ "eidlist_opt ::=",
165205
- /* 239 */ "eidlist_opt ::= LP eidlist RP",
165206
- /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder",
165207
- /* 241 */ "eidlist ::= nm collate sortorder",
165208
- /* 242 */ "collate ::=",
165209
- /* 243 */ "collate ::= COLLATE ID|STRING",
165210
- /* 244 */ "cmd ::= DROP INDEX ifexists fullname",
165211
- /* 245 */ "cmd ::= VACUUM vinto",
165212
- /* 246 */ "cmd ::= VACUUM nm vinto",
165213
- /* 247 */ "vinto ::= INTO expr",
165214
- /* 248 */ "vinto ::=",
165215
- /* 249 */ "cmd ::= PRAGMA nm dbnm",
165216
- /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
165217
- /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
165218
- /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
165219
- /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
165220
- /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT",
165221
- /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT",
165222
- /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
165223
- /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
165224
- /* 258 */ "trigger_time ::= BEFORE|AFTER",
165225
- /* 259 */ "trigger_time ::= INSTEAD OF",
165226
- /* 260 */ "trigger_time ::=",
165227
- /* 261 */ "trigger_event ::= DELETE|INSERT",
165228
- /* 262 */ "trigger_event ::= UPDATE",
165229
- /* 263 */ "trigger_event ::= UPDATE OF idlist",
165230
- /* 264 */ "when_clause ::=",
165231
- /* 265 */ "when_clause ::= WHEN expr",
165232
- /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
165233
- /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI",
165234
- /* 268 */ "trnm ::= nm DOT nm",
165235
- /* 269 */ "tridxby ::= INDEXED BY nm",
165236
- /* 270 */ "tridxby ::= NOT INDEXED",
165237
- /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
165238
- /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
165239
- /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
165240
- /* 274 */ "trigger_cmd ::= scanpt select scanpt",
165241
- /* 275 */ "expr ::= RAISE LP IGNORE RP",
165242
- /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP",
165243
- /* 277 */ "raisetype ::= ROLLBACK",
165244
- /* 278 */ "raisetype ::= ABORT",
165245
- /* 279 */ "raisetype ::= FAIL",
165246
- /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname",
165247
- /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
165248
- /* 282 */ "cmd ::= DETACH database_kw_opt expr",
165249
- /* 283 */ "key_opt ::=",
165250
- /* 284 */ "key_opt ::= KEY expr",
165251
- /* 285 */ "cmd ::= REINDEX",
165252
- /* 286 */ "cmd ::= REINDEX nm dbnm",
165253
- /* 287 */ "cmd ::= ANALYZE",
165254
- /* 288 */ "cmd ::= ANALYZE nm dbnm",
165255
- /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
165256
- /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
165257
- /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
165258
- /* 292 */ "add_column_fullname ::= fullname",
165259
- /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
165260
- /* 294 */ "cmd ::= create_vtab",
165261
- /* 295 */ "cmd ::= create_vtab LP vtabarglist RP",
165262
- /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
165263
- /* 297 */ "vtabarg ::=",
165264
- /* 298 */ "vtabargtoken ::= ANY",
165265
- /* 299 */ "vtabargtoken ::= lp anylist RP",
165266
- /* 300 */ "lp ::= LP",
165267
- /* 301 */ "with ::= WITH wqlist",
165268
- /* 302 */ "with ::= WITH RECURSIVE wqlist",
165269
- /* 303 */ "wqas ::= AS",
165270
- /* 304 */ "wqas ::= AS MATERIALIZED",
165271
- /* 305 */ "wqas ::= AS NOT MATERIALIZED",
165272
- /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
165273
- /* 307 */ "wqlist ::= wqitem",
165274
- /* 308 */ "wqlist ::= wqlist COMMA wqitem",
165275
- /* 309 */ "windowdefn_list ::= windowdefn",
165276
- /* 310 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
165277
- /* 311 */ "windowdefn ::= nm AS LP window RP",
165278
- /* 312 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
165279
- /* 313 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
165280
- /* 314 */ "window ::= ORDER BY sortlist frame_opt",
165281
- /* 315 */ "window ::= nm ORDER BY sortlist frame_opt",
165282
- /* 316 */ "window ::= frame_opt",
165283
- /* 317 */ "window ::= nm frame_opt",
165284
- /* 318 */ "frame_opt ::=",
165285
- /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
165286
- /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
165287
- /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
165288
- /* 322 */ "frame_bound_s ::= frame_bound",
165289
- /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
165290
- /* 324 */ "frame_bound_e ::= frame_bound",
165291
- /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
165292
- /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
165293
- /* 327 */ "frame_bound ::= CURRENT ROW",
165294
- /* 328 */ "frame_exclude_opt ::=",
165295
- /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
165296
- /* 330 */ "frame_exclude ::= NO OTHERS",
165297
- /* 331 */ "frame_exclude ::= CURRENT ROW",
165298
- /* 332 */ "frame_exclude ::= GROUP|TIES",
165299
- /* 333 */ "window_clause ::= WINDOW windowdefn_list",
165300
- /* 334 */ "filter_over ::= filter_clause over_clause",
165301
- /* 335 */ "filter_over ::= over_clause",
165302
- /* 336 */ "filter_over ::= filter_clause",
165303
- /* 337 */ "over_clause ::= OVER LP window RP",
165304
- /* 338 */ "over_clause ::= OVER nm",
165305
- /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP",
165306
- /* 340 */ "input ::= cmdlist",
165307
- /* 341 */ "cmdlist ::= cmdlist ecmd",
165308
- /* 342 */ "cmdlist ::= ecmd",
165309
- /* 343 */ "ecmd ::= SEMI",
165310
- /* 344 */ "ecmd ::= cmdx SEMI",
165311
- /* 345 */ "ecmd ::= explain cmdx SEMI",
165312
- /* 346 */ "trans_opt ::=",
165313
- /* 347 */ "trans_opt ::= TRANSACTION",
165314
- /* 348 */ "trans_opt ::= TRANSACTION nm",
165315
- /* 349 */ "savepoint_opt ::= SAVEPOINT",
165316
- /* 350 */ "savepoint_opt ::=",
165317
- /* 351 */ "cmd ::= create_table create_table_args",
165318
- /* 352 */ "table_option_set ::= table_option",
165319
- /* 353 */ "columnlist ::= columnlist COMMA columnname carglist",
165320
- /* 354 */ "columnlist ::= columnname carglist",
165321
- /* 355 */ "nm ::= ID|INDEXED",
165322
- /* 356 */ "nm ::= STRING",
165323
- /* 357 */ "nm ::= JOIN_KW",
165324
- /* 358 */ "typetoken ::= typename",
165325
- /* 359 */ "typename ::= ID|STRING",
165326
- /* 360 */ "signed ::= plus_num",
165327
- /* 361 */ "signed ::= minus_num",
165328
- /* 362 */ "carglist ::= carglist ccons",
165329
- /* 363 */ "carglist ::=",
165330
- /* 364 */ "ccons ::= NULL onconf",
165331
- /* 365 */ "ccons ::= GENERATED ALWAYS AS generated",
165332
- /* 366 */ "ccons ::= AS generated",
165333
- /* 367 */ "conslist_opt ::= COMMA conslist",
165334
- /* 368 */ "conslist ::= conslist tconscomma tcons",
165335
- /* 369 */ "conslist ::= tcons",
165336
- /* 370 */ "tconscomma ::=",
165337
- /* 371 */ "defer_subclause_opt ::= defer_subclause",
165338
- /* 372 */ "resolvetype ::= raisetype",
165339
- /* 373 */ "selectnowith ::= oneselect",
165340
- /* 374 */ "oneselect ::= values",
165341
- /* 375 */ "sclp ::= selcollist COMMA",
165342
- /* 376 */ "as ::= ID|STRING",
165343
- /* 377 */ "indexed_opt ::= indexed_by",
165344
- /* 378 */ "returning ::=",
165345
- /* 379 */ "expr ::= term",
165346
- /* 380 */ "likeop ::= LIKE_KW|MATCH",
165347
- /* 381 */ "exprlist ::= nexprlist",
165348
- /* 382 */ "nmnum ::= plus_num",
165349
- /* 383 */ "nmnum ::= nm",
165350
- /* 384 */ "nmnum ::= ON",
165351
- /* 385 */ "nmnum ::= DELETE",
165352
- /* 386 */ "nmnum ::= DEFAULT",
165353
- /* 387 */ "plus_num ::= INTEGER|FLOAT",
165354
- /* 388 */ "foreach_clause ::=",
165355
- /* 389 */ "foreach_clause ::= FOR EACH ROW",
165356
- /* 390 */ "trnm ::= nm",
165357
- /* 391 */ "tridxby ::=",
165358
- /* 392 */ "database_kw_opt ::= DATABASE",
165359
- /* 393 */ "database_kw_opt ::=",
165360
- /* 394 */ "kwcolumn_opt ::=",
165361
- /* 395 */ "kwcolumn_opt ::= COLUMNKW",
165362
- /* 396 */ "vtabarglist ::= vtabarg",
165363
- /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
165364
- /* 398 */ "vtabarg ::= vtabarg vtabargtoken",
165365
- /* 399 */ "anylist ::=",
165366
- /* 400 */ "anylist ::= anylist LP anylist RP",
165367
- /* 401 */ "anylist ::= anylist ANY",
165368
- /* 402 */ "with ::=",
165404
+ /* 209 */ "expr ::= expr IS NOT DISTINCT FROM expr",
165405
+ /* 210 */ "expr ::= expr IS DISTINCT FROM expr",
165406
+ /* 211 */ "expr ::= NOT expr",
165407
+ /* 212 */ "expr ::= BITNOT expr",
165408
+ /* 213 */ "expr ::= PLUS|MINUS expr",
165409
+ /* 214 */ "expr ::= expr PTR expr",
165410
+ /* 215 */ "between_op ::= BETWEEN",
165411
+ /* 216 */ "between_op ::= NOT BETWEEN",
165412
+ /* 217 */ "expr ::= expr between_op expr AND expr",
165413
+ /* 218 */ "in_op ::= IN",
165414
+ /* 219 */ "in_op ::= NOT IN",
165415
+ /* 220 */ "expr ::= expr in_op LP exprlist RP",
165416
+ /* 221 */ "expr ::= LP select RP",
165417
+ /* 222 */ "expr ::= expr in_op LP select RP",
165418
+ /* 223 */ "expr ::= expr in_op nm dbnm paren_exprlist",
165419
+ /* 224 */ "expr ::= EXISTS LP select RP",
165420
+ /* 225 */ "expr ::= CASE case_operand case_exprlist case_else END",
165421
+ /* 226 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
165422
+ /* 227 */ "case_exprlist ::= WHEN expr THEN expr",
165423
+ /* 228 */ "case_else ::= ELSE expr",
165424
+ /* 229 */ "case_else ::=",
165425
+ /* 230 */ "case_operand ::= expr",
165426
+ /* 231 */ "case_operand ::=",
165427
+ /* 232 */ "exprlist ::=",
165428
+ /* 233 */ "nexprlist ::= nexprlist COMMA expr",
165429
+ /* 234 */ "nexprlist ::= expr",
165430
+ /* 235 */ "paren_exprlist ::=",
165431
+ /* 236 */ "paren_exprlist ::= LP exprlist RP",
165432
+ /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
165433
+ /* 238 */ "uniqueflag ::= UNIQUE",
165434
+ /* 239 */ "uniqueflag ::=",
165435
+ /* 240 */ "eidlist_opt ::=",
165436
+ /* 241 */ "eidlist_opt ::= LP eidlist RP",
165437
+ /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder",
165438
+ /* 243 */ "eidlist ::= nm collate sortorder",
165439
+ /* 244 */ "collate ::=",
165440
+ /* 245 */ "collate ::= COLLATE ID|STRING",
165441
+ /* 246 */ "cmd ::= DROP INDEX ifexists fullname",
165442
+ /* 247 */ "cmd ::= VACUUM vinto",
165443
+ /* 248 */ "cmd ::= VACUUM nm vinto",
165444
+ /* 249 */ "vinto ::= INTO expr",
165445
+ /* 250 */ "vinto ::=",
165446
+ /* 251 */ "cmd ::= PRAGMA nm dbnm",
165447
+ /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
165448
+ /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
165449
+ /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
165450
+ /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
165451
+ /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT",
165452
+ /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT",
165453
+ /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
165454
+ /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
165455
+ /* 260 */ "trigger_time ::= BEFORE|AFTER",
165456
+ /* 261 */ "trigger_time ::= INSTEAD OF",
165457
+ /* 262 */ "trigger_time ::=",
165458
+ /* 263 */ "trigger_event ::= DELETE|INSERT",
165459
+ /* 264 */ "trigger_event ::= UPDATE",
165460
+ /* 265 */ "trigger_event ::= UPDATE OF idlist",
165461
+ /* 266 */ "when_clause ::=",
165462
+ /* 267 */ "when_clause ::= WHEN expr",
165463
+ /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
165464
+ /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI",
165465
+ /* 270 */ "trnm ::= nm DOT nm",
165466
+ /* 271 */ "tridxby ::= INDEXED BY nm",
165467
+ /* 272 */ "tridxby ::= NOT INDEXED",
165468
+ /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
165469
+ /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
165470
+ /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
165471
+ /* 276 */ "trigger_cmd ::= scanpt select scanpt",
165472
+ /* 277 */ "expr ::= RAISE LP IGNORE RP",
165473
+ /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP",
165474
+ /* 279 */ "raisetype ::= ROLLBACK",
165475
+ /* 280 */ "raisetype ::= ABORT",
165476
+ /* 281 */ "raisetype ::= FAIL",
165477
+ /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname",
165478
+ /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
165479
+ /* 284 */ "cmd ::= DETACH database_kw_opt expr",
165480
+ /* 285 */ "key_opt ::=",
165481
+ /* 286 */ "key_opt ::= KEY expr",
165482
+ /* 287 */ "cmd ::= REINDEX",
165483
+ /* 288 */ "cmd ::= REINDEX nm dbnm",
165484
+ /* 289 */ "cmd ::= ANALYZE",
165485
+ /* 290 */ "cmd ::= ANALYZE nm dbnm",
165486
+ /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
165487
+ /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
165488
+ /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
165489
+ /* 294 */ "add_column_fullname ::= fullname",
165490
+ /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
165491
+ /* 296 */ "cmd ::= create_vtab",
165492
+ /* 297 */ "cmd ::= create_vtab LP vtabarglist RP",
165493
+ /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
165494
+ /* 299 */ "vtabarg ::=",
165495
+ /* 300 */ "vtabargtoken ::= ANY",
165496
+ /* 301 */ "vtabargtoken ::= lp anylist RP",
165497
+ /* 302 */ "lp ::= LP",
165498
+ /* 303 */ "with ::= WITH wqlist",
165499
+ /* 304 */ "with ::= WITH RECURSIVE wqlist",
165500
+ /* 305 */ "wqas ::= AS",
165501
+ /* 306 */ "wqas ::= AS MATERIALIZED",
165502
+ /* 307 */ "wqas ::= AS NOT MATERIALIZED",
165503
+ /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
165504
+ /* 309 */ "wqlist ::= wqitem",
165505
+ /* 310 */ "wqlist ::= wqlist COMMA wqitem",
165506
+ /* 311 */ "windowdefn_list ::= windowdefn",
165507
+ /* 312 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
165508
+ /* 313 */ "windowdefn ::= nm AS LP window RP",
165509
+ /* 314 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
165510
+ /* 315 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
165511
+ /* 316 */ "window ::= ORDER BY sortlist frame_opt",
165512
+ /* 317 */ "window ::= nm ORDER BY sortlist frame_opt",
165513
+ /* 318 */ "window ::= frame_opt",
165514
+ /* 319 */ "window ::= nm frame_opt",
165515
+ /* 320 */ "frame_opt ::=",
165516
+ /* 321 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
165517
+ /* 322 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
165518
+ /* 323 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
165519
+ /* 324 */ "frame_bound_s ::= frame_bound",
165520
+ /* 325 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
165521
+ /* 326 */ "frame_bound_e ::= frame_bound",
165522
+ /* 327 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
165523
+ /* 328 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
165524
+ /* 329 */ "frame_bound ::= CURRENT ROW",
165525
+ /* 330 */ "frame_exclude_opt ::=",
165526
+ /* 331 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
165527
+ /* 332 */ "frame_exclude ::= NO OTHERS",
165528
+ /* 333 */ "frame_exclude ::= CURRENT ROW",
165529
+ /* 334 */ "frame_exclude ::= GROUP|TIES",
165530
+ /* 335 */ "window_clause ::= WINDOW windowdefn_list",
165531
+ /* 336 */ "filter_over ::= filter_clause over_clause",
165532
+ /* 337 */ "filter_over ::= over_clause",
165533
+ /* 338 */ "filter_over ::= filter_clause",
165534
+ /* 339 */ "over_clause ::= OVER LP window RP",
165535
+ /* 340 */ "over_clause ::= OVER nm",
165536
+ /* 341 */ "filter_clause ::= FILTER LP WHERE expr RP",
165537
+ /* 342 */ "input ::= cmdlist",
165538
+ /* 343 */ "cmdlist ::= cmdlist ecmd",
165539
+ /* 344 */ "cmdlist ::= ecmd",
165540
+ /* 345 */ "ecmd ::= SEMI",
165541
+ /* 346 */ "ecmd ::= cmdx SEMI",
165542
+ /* 347 */ "ecmd ::= explain cmdx SEMI",
165543
+ /* 348 */ "trans_opt ::=",
165544
+ /* 349 */ "trans_opt ::= TRANSACTION",
165545
+ /* 350 */ "trans_opt ::= TRANSACTION nm",
165546
+ /* 351 */ "savepoint_opt ::= SAVEPOINT",
165547
+ /* 352 */ "savepoint_opt ::=",
165548
+ /* 353 */ "cmd ::= create_table create_table_args",
165549
+ /* 354 */ "table_option_set ::= table_option",
165550
+ /* 355 */ "columnlist ::= columnlist COMMA columnname carglist",
165551
+ /* 356 */ "columnlist ::= columnname carglist",
165552
+ /* 357 */ "nm ::= ID|INDEXED",
165553
+ /* 358 */ "nm ::= STRING",
165554
+ /* 359 */ "nm ::= JOIN_KW",
165555
+ /* 360 */ "typetoken ::= typename",
165556
+ /* 361 */ "typename ::= ID|STRING",
165557
+ /* 362 */ "signed ::= plus_num",
165558
+ /* 363 */ "signed ::= minus_num",
165559
+ /* 364 */ "carglist ::= carglist ccons",
165560
+ /* 365 */ "carglist ::=",
165561
+ /* 366 */ "ccons ::= NULL onconf",
165562
+ /* 367 */ "ccons ::= GENERATED ALWAYS AS generated",
165563
+ /* 368 */ "ccons ::= AS generated",
165564
+ /* 369 */ "conslist_opt ::= COMMA conslist",
165565
+ /* 370 */ "conslist ::= conslist tconscomma tcons",
165566
+ /* 371 */ "conslist ::= tcons",
165567
+ /* 372 */ "tconscomma ::=",
165568
+ /* 373 */ "defer_subclause_opt ::= defer_subclause",
165569
+ /* 374 */ "resolvetype ::= raisetype",
165570
+ /* 375 */ "selectnowith ::= oneselect",
165571
+ /* 376 */ "oneselect ::= values",
165572
+ /* 377 */ "sclp ::= selcollist COMMA",
165573
+ /* 378 */ "as ::= ID|STRING",
165574
+ /* 379 */ "indexed_opt ::= indexed_by",
165575
+ /* 380 */ "returning ::=",
165576
+ /* 381 */ "expr ::= term",
165577
+ /* 382 */ "likeop ::= LIKE_KW|MATCH",
165578
+ /* 383 */ "exprlist ::= nexprlist",
165579
+ /* 384 */ "nmnum ::= plus_num",
165580
+ /* 385 */ "nmnum ::= nm",
165581
+ /* 386 */ "nmnum ::= ON",
165582
+ /* 387 */ "nmnum ::= DELETE",
165583
+ /* 388 */ "nmnum ::= DEFAULT",
165584
+ /* 389 */ "plus_num ::= INTEGER|FLOAT",
165585
+ /* 390 */ "foreach_clause ::=",
165586
+ /* 391 */ "foreach_clause ::= FOR EACH ROW",
165587
+ /* 392 */ "trnm ::= nm",
165588
+ /* 393 */ "tridxby ::=",
165589
+ /* 394 */ "database_kw_opt ::= DATABASE",
165590
+ /* 395 */ "database_kw_opt ::=",
165591
+ /* 396 */ "kwcolumn_opt ::=",
165592
+ /* 397 */ "kwcolumn_opt ::= COLUMNKW",
165593
+ /* 398 */ "vtabarglist ::= vtabarg",
165594
+ /* 399 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
165595
+ /* 400 */ "vtabarg ::= vtabarg vtabargtoken",
165596
+ /* 401 */ "anylist ::=",
165597
+ /* 402 */ "anylist ::= anylist LP anylist RP",
165598
+ /* 403 */ "anylist ::= anylist ANY",
165599
+ /* 404 */ "with ::=",
165369165600
};
165370165601
#endif /* NDEBUG */
165371165602
165372165603
165373165604
#if YYSTACKDEPTH<=0
@@ -166079,204 +166310,206 @@
166079166310
217, /* (204) expr ::= expr likeop expr ESCAPE expr */
166080166311
217, /* (205) expr ::= expr ISNULL|NOTNULL */
166081166312
217, /* (206) expr ::= expr NOT NULL */
166082166313
217, /* (207) expr ::= expr IS expr */
166083166314
217, /* (208) expr ::= expr IS NOT expr */
166084
- 217, /* (209) expr ::= NOT expr */
166085
- 217, /* (210) expr ::= BITNOT expr */
166086
- 217, /* (211) expr ::= PLUS|MINUS expr */
166087
- 217, /* (212) expr ::= expr PTR expr */
166088
- 275, /* (213) between_op ::= BETWEEN */
166089
- 275, /* (214) between_op ::= NOT BETWEEN */
166090
- 217, /* (215) expr ::= expr between_op expr AND expr */
166091
- 276, /* (216) in_op ::= IN */
166092
- 276, /* (217) in_op ::= NOT IN */
166093
- 217, /* (218) expr ::= expr in_op LP exprlist RP */
166094
- 217, /* (219) expr ::= LP select RP */
166095
- 217, /* (220) expr ::= expr in_op LP select RP */
166096
- 217, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */
166097
- 217, /* (222) expr ::= EXISTS LP select RP */
166098
- 217, /* (223) expr ::= CASE case_operand case_exprlist case_else END */
166099
- 279, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166100
- 279, /* (225) case_exprlist ::= WHEN expr THEN expr */
166101
- 280, /* (226) case_else ::= ELSE expr */
166102
- 280, /* (227) case_else ::= */
166103
- 278, /* (228) case_operand ::= expr */
166104
- 278, /* (229) case_operand ::= */
166105
- 261, /* (230) exprlist ::= */
166106
- 253, /* (231) nexprlist ::= nexprlist COMMA expr */
166107
- 253, /* (232) nexprlist ::= expr */
166108
- 277, /* (233) paren_exprlist ::= */
166109
- 277, /* (234) paren_exprlist ::= LP exprlist RP */
166110
- 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166111
- 281, /* (236) uniqueflag ::= UNIQUE */
166112
- 281, /* (237) uniqueflag ::= */
166113
- 221, /* (238) eidlist_opt ::= */
166114
- 221, /* (239) eidlist_opt ::= LP eidlist RP */
166115
- 232, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */
166116
- 232, /* (241) eidlist ::= nm collate sortorder */
166117
- 282, /* (242) collate ::= */
166118
- 282, /* (243) collate ::= COLLATE ID|STRING */
166119
- 190, /* (244) cmd ::= DROP INDEX ifexists fullname */
166120
- 190, /* (245) cmd ::= VACUUM vinto */
166121
- 190, /* (246) cmd ::= VACUUM nm vinto */
166122
- 283, /* (247) vinto ::= INTO expr */
166123
- 283, /* (248) vinto ::= */
166124
- 190, /* (249) cmd ::= PRAGMA nm dbnm */
166125
- 190, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */
166126
- 190, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166127
- 190, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */
166128
- 190, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166129
- 211, /* (254) plus_num ::= PLUS INTEGER|FLOAT */
166130
- 212, /* (255) minus_num ::= MINUS INTEGER|FLOAT */
166131
- 190, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166132
- 285, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166133
- 287, /* (258) trigger_time ::= BEFORE|AFTER */
166134
- 287, /* (259) trigger_time ::= INSTEAD OF */
166135
- 287, /* (260) trigger_time ::= */
166136
- 288, /* (261) trigger_event ::= DELETE|INSERT */
166137
- 288, /* (262) trigger_event ::= UPDATE */
166138
- 288, /* (263) trigger_event ::= UPDATE OF idlist */
166139
- 290, /* (264) when_clause ::= */
166140
- 290, /* (265) when_clause ::= WHEN expr */
166141
- 286, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166142
- 286, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */
166143
- 292, /* (268) trnm ::= nm DOT nm */
166144
- 293, /* (269) tridxby ::= INDEXED BY nm */
166145
- 293, /* (270) tridxby ::= NOT INDEXED */
166146
- 291, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166147
- 291, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166148
- 291, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166149
- 291, /* (274) trigger_cmd ::= scanpt select scanpt */
166150
- 217, /* (275) expr ::= RAISE LP IGNORE RP */
166151
- 217, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */
166152
- 236, /* (277) raisetype ::= ROLLBACK */
166153
- 236, /* (278) raisetype ::= ABORT */
166154
- 236, /* (279) raisetype ::= FAIL */
166155
- 190, /* (280) cmd ::= DROP TRIGGER ifexists fullname */
166156
- 190, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166157
- 190, /* (282) cmd ::= DETACH database_kw_opt expr */
166158
- 295, /* (283) key_opt ::= */
166159
- 295, /* (284) key_opt ::= KEY expr */
166160
- 190, /* (285) cmd ::= REINDEX */
166161
- 190, /* (286) cmd ::= REINDEX nm dbnm */
166162
- 190, /* (287) cmd ::= ANALYZE */
166163
- 190, /* (288) cmd ::= ANALYZE nm dbnm */
166164
- 190, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */
166165
- 190, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166166
- 190, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166167
- 296, /* (292) add_column_fullname ::= fullname */
166168
- 190, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166169
- 190, /* (294) cmd ::= create_vtab */
166170
- 190, /* (295) cmd ::= create_vtab LP vtabarglist RP */
166171
- 298, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166172
- 300, /* (297) vtabarg ::= */
166173
- 301, /* (298) vtabargtoken ::= ANY */
166174
- 301, /* (299) vtabargtoken ::= lp anylist RP */
166175
- 302, /* (300) lp ::= LP */
166176
- 266, /* (301) with ::= WITH wqlist */
166177
- 266, /* (302) with ::= WITH RECURSIVE wqlist */
166178
- 305, /* (303) wqas ::= AS */
166179
- 305, /* (304) wqas ::= AS MATERIALIZED */
166180
- 305, /* (305) wqas ::= AS NOT MATERIALIZED */
166181
- 304, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */
166182
- 241, /* (307) wqlist ::= wqitem */
166183
- 241, /* (308) wqlist ::= wqlist COMMA wqitem */
166184
- 306, /* (309) windowdefn_list ::= windowdefn */
166185
- 306, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166186
- 307, /* (311) windowdefn ::= nm AS LP window RP */
166187
- 308, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166188
- 308, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166189
- 308, /* (314) window ::= ORDER BY sortlist frame_opt */
166190
- 308, /* (315) window ::= nm ORDER BY sortlist frame_opt */
166191
- 308, /* (316) window ::= frame_opt */
166192
- 308, /* (317) window ::= nm frame_opt */
166193
- 309, /* (318) frame_opt ::= */
166194
- 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166195
- 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166196
- 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
166197
- 315, /* (322) frame_bound_s ::= frame_bound */
166198
- 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
166199
- 316, /* (324) frame_bound_e ::= frame_bound */
166200
- 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
166201
- 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
166202
- 314, /* (327) frame_bound ::= CURRENT ROW */
166203
- 317, /* (328) frame_exclude_opt ::= */
166204
- 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
166205
- 318, /* (330) frame_exclude ::= NO OTHERS */
166206
- 318, /* (331) frame_exclude ::= CURRENT ROW */
166207
- 318, /* (332) frame_exclude ::= GROUP|TIES */
166208
- 251, /* (333) window_clause ::= WINDOW windowdefn_list */
166209
- 273, /* (334) filter_over ::= filter_clause over_clause */
166210
- 273, /* (335) filter_over ::= over_clause */
166211
- 273, /* (336) filter_over ::= filter_clause */
166212
- 312, /* (337) over_clause ::= OVER LP window RP */
166213
- 312, /* (338) over_clause ::= OVER nm */
166214
- 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */
166215
- 185, /* (340) input ::= cmdlist */
166216
- 186, /* (341) cmdlist ::= cmdlist ecmd */
166217
- 186, /* (342) cmdlist ::= ecmd */
166218
- 187, /* (343) ecmd ::= SEMI */
166219
- 187, /* (344) ecmd ::= cmdx SEMI */
166220
- 187, /* (345) ecmd ::= explain cmdx SEMI */
166221
- 192, /* (346) trans_opt ::= */
166222
- 192, /* (347) trans_opt ::= TRANSACTION */
166223
- 192, /* (348) trans_opt ::= TRANSACTION nm */
166224
- 194, /* (349) savepoint_opt ::= SAVEPOINT */
166225
- 194, /* (350) savepoint_opt ::= */
166226
- 190, /* (351) cmd ::= create_table create_table_args */
166227
- 203, /* (352) table_option_set ::= table_option */
166228
- 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */
166229
- 201, /* (354) columnlist ::= columnname carglist */
166230
- 193, /* (355) nm ::= ID|INDEXED */
166231
- 193, /* (356) nm ::= STRING */
166232
- 193, /* (357) nm ::= JOIN_KW */
166233
- 208, /* (358) typetoken ::= typename */
166234
- 209, /* (359) typename ::= ID|STRING */
166235
- 210, /* (360) signed ::= plus_num */
166236
- 210, /* (361) signed ::= minus_num */
166237
- 207, /* (362) carglist ::= carglist ccons */
166238
- 207, /* (363) carglist ::= */
166239
- 215, /* (364) ccons ::= NULL onconf */
166240
- 215, /* (365) ccons ::= GENERATED ALWAYS AS generated */
166241
- 215, /* (366) ccons ::= AS generated */
166242
- 202, /* (367) conslist_opt ::= COMMA conslist */
166243
- 228, /* (368) conslist ::= conslist tconscomma tcons */
166244
- 228, /* (369) conslist ::= tcons */
166245
- 229, /* (370) tconscomma ::= */
166246
- 233, /* (371) defer_subclause_opt ::= defer_subclause */
166247
- 235, /* (372) resolvetype ::= raisetype */
166248
- 239, /* (373) selectnowith ::= oneselect */
166249
- 240, /* (374) oneselect ::= values */
166250
- 254, /* (375) sclp ::= selcollist COMMA */
166251
- 255, /* (376) as ::= ID|STRING */
166252
- 264, /* (377) indexed_opt ::= indexed_by */
166253
- 272, /* (378) returning ::= */
166254
- 217, /* (379) expr ::= term */
166255
- 274, /* (380) likeop ::= LIKE_KW|MATCH */
166256
- 261, /* (381) exprlist ::= nexprlist */
166257
- 284, /* (382) nmnum ::= plus_num */
166258
- 284, /* (383) nmnum ::= nm */
166259
- 284, /* (384) nmnum ::= ON */
166260
- 284, /* (385) nmnum ::= DELETE */
166261
- 284, /* (386) nmnum ::= DEFAULT */
166262
- 211, /* (387) plus_num ::= INTEGER|FLOAT */
166263
- 289, /* (388) foreach_clause ::= */
166264
- 289, /* (389) foreach_clause ::= FOR EACH ROW */
166265
- 292, /* (390) trnm ::= nm */
166266
- 293, /* (391) tridxby ::= */
166267
- 294, /* (392) database_kw_opt ::= DATABASE */
166268
- 294, /* (393) database_kw_opt ::= */
166269
- 297, /* (394) kwcolumn_opt ::= */
166270
- 297, /* (395) kwcolumn_opt ::= COLUMNKW */
166271
- 299, /* (396) vtabarglist ::= vtabarg */
166272
- 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
166273
- 300, /* (398) vtabarg ::= vtabarg vtabargtoken */
166274
- 303, /* (399) anylist ::= */
166275
- 303, /* (400) anylist ::= anylist LP anylist RP */
166276
- 303, /* (401) anylist ::= anylist ANY */
166277
- 266, /* (402) with ::= */
166315
+ 217, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */
166316
+ 217, /* (210) expr ::= expr IS DISTINCT FROM expr */
166317
+ 217, /* (211) expr ::= NOT expr */
166318
+ 217, /* (212) expr ::= BITNOT expr */
166319
+ 217, /* (213) expr ::= PLUS|MINUS expr */
166320
+ 217, /* (214) expr ::= expr PTR expr */
166321
+ 275, /* (215) between_op ::= BETWEEN */
166322
+ 275, /* (216) between_op ::= NOT BETWEEN */
166323
+ 217, /* (217) expr ::= expr between_op expr AND expr */
166324
+ 276, /* (218) in_op ::= IN */
166325
+ 276, /* (219) in_op ::= NOT IN */
166326
+ 217, /* (220) expr ::= expr in_op LP exprlist RP */
166327
+ 217, /* (221) expr ::= LP select RP */
166328
+ 217, /* (222) expr ::= expr in_op LP select RP */
166329
+ 217, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */
166330
+ 217, /* (224) expr ::= EXISTS LP select RP */
166331
+ 217, /* (225) expr ::= CASE case_operand case_exprlist case_else END */
166332
+ 279, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166333
+ 279, /* (227) case_exprlist ::= WHEN expr THEN expr */
166334
+ 280, /* (228) case_else ::= ELSE expr */
166335
+ 280, /* (229) case_else ::= */
166336
+ 278, /* (230) case_operand ::= expr */
166337
+ 278, /* (231) case_operand ::= */
166338
+ 261, /* (232) exprlist ::= */
166339
+ 253, /* (233) nexprlist ::= nexprlist COMMA expr */
166340
+ 253, /* (234) nexprlist ::= expr */
166341
+ 277, /* (235) paren_exprlist ::= */
166342
+ 277, /* (236) paren_exprlist ::= LP exprlist RP */
166343
+ 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166344
+ 281, /* (238) uniqueflag ::= UNIQUE */
166345
+ 281, /* (239) uniqueflag ::= */
166346
+ 221, /* (240) eidlist_opt ::= */
166347
+ 221, /* (241) eidlist_opt ::= LP eidlist RP */
166348
+ 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
166349
+ 232, /* (243) eidlist ::= nm collate sortorder */
166350
+ 282, /* (244) collate ::= */
166351
+ 282, /* (245) collate ::= COLLATE ID|STRING */
166352
+ 190, /* (246) cmd ::= DROP INDEX ifexists fullname */
166353
+ 190, /* (247) cmd ::= VACUUM vinto */
166354
+ 190, /* (248) cmd ::= VACUUM nm vinto */
166355
+ 283, /* (249) vinto ::= INTO expr */
166356
+ 283, /* (250) vinto ::= */
166357
+ 190, /* (251) cmd ::= PRAGMA nm dbnm */
166358
+ 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
166359
+ 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166360
+ 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
166361
+ 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166362
+ 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */
166363
+ 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */
166364
+ 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166365
+ 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166366
+ 287, /* (260) trigger_time ::= BEFORE|AFTER */
166367
+ 287, /* (261) trigger_time ::= INSTEAD OF */
166368
+ 287, /* (262) trigger_time ::= */
166369
+ 288, /* (263) trigger_event ::= DELETE|INSERT */
166370
+ 288, /* (264) trigger_event ::= UPDATE */
166371
+ 288, /* (265) trigger_event ::= UPDATE OF idlist */
166372
+ 290, /* (266) when_clause ::= */
166373
+ 290, /* (267) when_clause ::= WHEN expr */
166374
+ 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166375
+ 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
166376
+ 292, /* (270) trnm ::= nm DOT nm */
166377
+ 293, /* (271) tridxby ::= INDEXED BY nm */
166378
+ 293, /* (272) tridxby ::= NOT INDEXED */
166379
+ 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166380
+ 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166381
+ 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166382
+ 291, /* (276) trigger_cmd ::= scanpt select scanpt */
166383
+ 217, /* (277) expr ::= RAISE LP IGNORE RP */
166384
+ 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
166385
+ 236, /* (279) raisetype ::= ROLLBACK */
166386
+ 236, /* (280) raisetype ::= ABORT */
166387
+ 236, /* (281) raisetype ::= FAIL */
166388
+ 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */
166389
+ 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166390
+ 190, /* (284) cmd ::= DETACH database_kw_opt expr */
166391
+ 295, /* (285) key_opt ::= */
166392
+ 295, /* (286) key_opt ::= KEY expr */
166393
+ 190, /* (287) cmd ::= REINDEX */
166394
+ 190, /* (288) cmd ::= REINDEX nm dbnm */
166395
+ 190, /* (289) cmd ::= ANALYZE */
166396
+ 190, /* (290) cmd ::= ANALYZE nm dbnm */
166397
+ 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
166398
+ 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166399
+ 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166400
+ 296, /* (294) add_column_fullname ::= fullname */
166401
+ 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166402
+ 190, /* (296) cmd ::= create_vtab */
166403
+ 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */
166404
+ 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166405
+ 300, /* (299) vtabarg ::= */
166406
+ 301, /* (300) vtabargtoken ::= ANY */
166407
+ 301, /* (301) vtabargtoken ::= lp anylist RP */
166408
+ 302, /* (302) lp ::= LP */
166409
+ 266, /* (303) with ::= WITH wqlist */
166410
+ 266, /* (304) with ::= WITH RECURSIVE wqlist */
166411
+ 305, /* (305) wqas ::= AS */
166412
+ 305, /* (306) wqas ::= AS MATERIALIZED */
166413
+ 305, /* (307) wqas ::= AS NOT MATERIALIZED */
166414
+ 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
166415
+ 241, /* (309) wqlist ::= wqitem */
166416
+ 241, /* (310) wqlist ::= wqlist COMMA wqitem */
166417
+ 306, /* (311) windowdefn_list ::= windowdefn */
166418
+ 306, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166419
+ 307, /* (313) windowdefn ::= nm AS LP window RP */
166420
+ 308, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166421
+ 308, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166422
+ 308, /* (316) window ::= ORDER BY sortlist frame_opt */
166423
+ 308, /* (317) window ::= nm ORDER BY sortlist frame_opt */
166424
+ 308, /* (318) window ::= frame_opt */
166425
+ 308, /* (319) window ::= nm frame_opt */
166426
+ 309, /* (320) frame_opt ::= */
166427
+ 309, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166428
+ 309, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166429
+ 313, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */
166430
+ 315, /* (324) frame_bound_s ::= frame_bound */
166431
+ 315, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */
166432
+ 316, /* (326) frame_bound_e ::= frame_bound */
166433
+ 316, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */
166434
+ 314, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */
166435
+ 314, /* (329) frame_bound ::= CURRENT ROW */
166436
+ 317, /* (330) frame_exclude_opt ::= */
166437
+ 317, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */
166438
+ 318, /* (332) frame_exclude ::= NO OTHERS */
166439
+ 318, /* (333) frame_exclude ::= CURRENT ROW */
166440
+ 318, /* (334) frame_exclude ::= GROUP|TIES */
166441
+ 251, /* (335) window_clause ::= WINDOW windowdefn_list */
166442
+ 273, /* (336) filter_over ::= filter_clause over_clause */
166443
+ 273, /* (337) filter_over ::= over_clause */
166444
+ 273, /* (338) filter_over ::= filter_clause */
166445
+ 312, /* (339) over_clause ::= OVER LP window RP */
166446
+ 312, /* (340) over_clause ::= OVER nm */
166447
+ 311, /* (341) filter_clause ::= FILTER LP WHERE expr RP */
166448
+ 185, /* (342) input ::= cmdlist */
166449
+ 186, /* (343) cmdlist ::= cmdlist ecmd */
166450
+ 186, /* (344) cmdlist ::= ecmd */
166451
+ 187, /* (345) ecmd ::= SEMI */
166452
+ 187, /* (346) ecmd ::= cmdx SEMI */
166453
+ 187, /* (347) ecmd ::= explain cmdx SEMI */
166454
+ 192, /* (348) trans_opt ::= */
166455
+ 192, /* (349) trans_opt ::= TRANSACTION */
166456
+ 192, /* (350) trans_opt ::= TRANSACTION nm */
166457
+ 194, /* (351) savepoint_opt ::= SAVEPOINT */
166458
+ 194, /* (352) savepoint_opt ::= */
166459
+ 190, /* (353) cmd ::= create_table create_table_args */
166460
+ 203, /* (354) table_option_set ::= table_option */
166461
+ 201, /* (355) columnlist ::= columnlist COMMA columnname carglist */
166462
+ 201, /* (356) columnlist ::= columnname carglist */
166463
+ 193, /* (357) nm ::= ID|INDEXED */
166464
+ 193, /* (358) nm ::= STRING */
166465
+ 193, /* (359) nm ::= JOIN_KW */
166466
+ 208, /* (360) typetoken ::= typename */
166467
+ 209, /* (361) typename ::= ID|STRING */
166468
+ 210, /* (362) signed ::= plus_num */
166469
+ 210, /* (363) signed ::= minus_num */
166470
+ 207, /* (364) carglist ::= carglist ccons */
166471
+ 207, /* (365) carglist ::= */
166472
+ 215, /* (366) ccons ::= NULL onconf */
166473
+ 215, /* (367) ccons ::= GENERATED ALWAYS AS generated */
166474
+ 215, /* (368) ccons ::= AS generated */
166475
+ 202, /* (369) conslist_opt ::= COMMA conslist */
166476
+ 228, /* (370) conslist ::= conslist tconscomma tcons */
166477
+ 228, /* (371) conslist ::= tcons */
166478
+ 229, /* (372) tconscomma ::= */
166479
+ 233, /* (373) defer_subclause_opt ::= defer_subclause */
166480
+ 235, /* (374) resolvetype ::= raisetype */
166481
+ 239, /* (375) selectnowith ::= oneselect */
166482
+ 240, /* (376) oneselect ::= values */
166483
+ 254, /* (377) sclp ::= selcollist COMMA */
166484
+ 255, /* (378) as ::= ID|STRING */
166485
+ 264, /* (379) indexed_opt ::= indexed_by */
166486
+ 272, /* (380) returning ::= */
166487
+ 217, /* (381) expr ::= term */
166488
+ 274, /* (382) likeop ::= LIKE_KW|MATCH */
166489
+ 261, /* (383) exprlist ::= nexprlist */
166490
+ 284, /* (384) nmnum ::= plus_num */
166491
+ 284, /* (385) nmnum ::= nm */
166492
+ 284, /* (386) nmnum ::= ON */
166493
+ 284, /* (387) nmnum ::= DELETE */
166494
+ 284, /* (388) nmnum ::= DEFAULT */
166495
+ 211, /* (389) plus_num ::= INTEGER|FLOAT */
166496
+ 289, /* (390) foreach_clause ::= */
166497
+ 289, /* (391) foreach_clause ::= FOR EACH ROW */
166498
+ 292, /* (392) trnm ::= nm */
166499
+ 293, /* (393) tridxby ::= */
166500
+ 294, /* (394) database_kw_opt ::= DATABASE */
166501
+ 294, /* (395) database_kw_opt ::= */
166502
+ 297, /* (396) kwcolumn_opt ::= */
166503
+ 297, /* (397) kwcolumn_opt ::= COLUMNKW */
166504
+ 299, /* (398) vtabarglist ::= vtabarg */
166505
+ 299, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */
166506
+ 300, /* (400) vtabarg ::= vtabarg vtabargtoken */
166507
+ 303, /* (401) anylist ::= */
166508
+ 303, /* (402) anylist ::= anylist LP anylist RP */
166509
+ 303, /* (403) anylist ::= anylist ANY */
166510
+ 266, /* (404) with ::= */
166278166511
};
166279166512
166280166513
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
166281166514
** of symbols on the right-hand side of that rule. */
166282166515
static const signed char yyRuleInfoNRhs[] = {
@@ -166487,204 +166720,206 @@
166487166720
-5, /* (204) expr ::= expr likeop expr ESCAPE expr */
166488166721
-2, /* (205) expr ::= expr ISNULL|NOTNULL */
166489166722
-3, /* (206) expr ::= expr NOT NULL */
166490166723
-3, /* (207) expr ::= expr IS expr */
166491166724
-4, /* (208) expr ::= expr IS NOT expr */
166492
- -2, /* (209) expr ::= NOT expr */
166493
- -2, /* (210) expr ::= BITNOT expr */
166494
- -2, /* (211) expr ::= PLUS|MINUS expr */
166495
- -3, /* (212) expr ::= expr PTR expr */
166496
- -1, /* (213) between_op ::= BETWEEN */
166497
- -2, /* (214) between_op ::= NOT BETWEEN */
166498
- -5, /* (215) expr ::= expr between_op expr AND expr */
166499
- -1, /* (216) in_op ::= IN */
166500
- -2, /* (217) in_op ::= NOT IN */
166501
- -5, /* (218) expr ::= expr in_op LP exprlist RP */
166502
- -3, /* (219) expr ::= LP select RP */
166503
- -5, /* (220) expr ::= expr in_op LP select RP */
166504
- -5, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */
166505
- -4, /* (222) expr ::= EXISTS LP select RP */
166506
- -5, /* (223) expr ::= CASE case_operand case_exprlist case_else END */
166507
- -5, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166508
- -4, /* (225) case_exprlist ::= WHEN expr THEN expr */
166509
- -2, /* (226) case_else ::= ELSE expr */
166510
- 0, /* (227) case_else ::= */
166511
- -1, /* (228) case_operand ::= expr */
166512
- 0, /* (229) case_operand ::= */
166513
- 0, /* (230) exprlist ::= */
166514
- -3, /* (231) nexprlist ::= nexprlist COMMA expr */
166515
- -1, /* (232) nexprlist ::= expr */
166516
- 0, /* (233) paren_exprlist ::= */
166517
- -3, /* (234) paren_exprlist ::= LP exprlist RP */
166518
- -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166519
- -1, /* (236) uniqueflag ::= UNIQUE */
166520
- 0, /* (237) uniqueflag ::= */
166521
- 0, /* (238) eidlist_opt ::= */
166522
- -3, /* (239) eidlist_opt ::= LP eidlist RP */
166523
- -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */
166524
- -3, /* (241) eidlist ::= nm collate sortorder */
166525
- 0, /* (242) collate ::= */
166526
- -2, /* (243) collate ::= COLLATE ID|STRING */
166527
- -4, /* (244) cmd ::= DROP INDEX ifexists fullname */
166528
- -2, /* (245) cmd ::= VACUUM vinto */
166529
- -3, /* (246) cmd ::= VACUUM nm vinto */
166530
- -2, /* (247) vinto ::= INTO expr */
166531
- 0, /* (248) vinto ::= */
166532
- -3, /* (249) cmd ::= PRAGMA nm dbnm */
166533
- -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */
166534
- -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166535
- -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */
166536
- -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166537
- -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */
166538
- -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */
166539
- -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166540
- -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166541
- -1, /* (258) trigger_time ::= BEFORE|AFTER */
166542
- -2, /* (259) trigger_time ::= INSTEAD OF */
166543
- 0, /* (260) trigger_time ::= */
166544
- -1, /* (261) trigger_event ::= DELETE|INSERT */
166545
- -1, /* (262) trigger_event ::= UPDATE */
166546
- -3, /* (263) trigger_event ::= UPDATE OF idlist */
166547
- 0, /* (264) when_clause ::= */
166548
- -2, /* (265) when_clause ::= WHEN expr */
166549
- -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166550
- -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */
166551
- -3, /* (268) trnm ::= nm DOT nm */
166552
- -3, /* (269) tridxby ::= INDEXED BY nm */
166553
- -2, /* (270) tridxby ::= NOT INDEXED */
166554
- -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166555
- -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166556
- -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166557
- -3, /* (274) trigger_cmd ::= scanpt select scanpt */
166558
- -4, /* (275) expr ::= RAISE LP IGNORE RP */
166559
- -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */
166560
- -1, /* (277) raisetype ::= ROLLBACK */
166561
- -1, /* (278) raisetype ::= ABORT */
166562
- -1, /* (279) raisetype ::= FAIL */
166563
- -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */
166564
- -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166565
- -3, /* (282) cmd ::= DETACH database_kw_opt expr */
166566
- 0, /* (283) key_opt ::= */
166567
- -2, /* (284) key_opt ::= KEY expr */
166568
- -1, /* (285) cmd ::= REINDEX */
166569
- -3, /* (286) cmd ::= REINDEX nm dbnm */
166570
- -1, /* (287) cmd ::= ANALYZE */
166571
- -3, /* (288) cmd ::= ANALYZE nm dbnm */
166572
- -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */
166573
- -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166574
- -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166575
- -1, /* (292) add_column_fullname ::= fullname */
166576
- -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166577
- -1, /* (294) cmd ::= create_vtab */
166578
- -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */
166579
- -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166580
- 0, /* (297) vtabarg ::= */
166581
- -1, /* (298) vtabargtoken ::= ANY */
166582
- -3, /* (299) vtabargtoken ::= lp anylist RP */
166583
- -1, /* (300) lp ::= LP */
166584
- -2, /* (301) with ::= WITH wqlist */
166585
- -3, /* (302) with ::= WITH RECURSIVE wqlist */
166586
- -1, /* (303) wqas ::= AS */
166587
- -2, /* (304) wqas ::= AS MATERIALIZED */
166588
- -3, /* (305) wqas ::= AS NOT MATERIALIZED */
166589
- -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */
166590
- -1, /* (307) wqlist ::= wqitem */
166591
- -3, /* (308) wqlist ::= wqlist COMMA wqitem */
166592
- -1, /* (309) windowdefn_list ::= windowdefn */
166593
- -3, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166594
- -5, /* (311) windowdefn ::= nm AS LP window RP */
166595
- -5, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166596
- -6, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166597
- -4, /* (314) window ::= ORDER BY sortlist frame_opt */
166598
- -5, /* (315) window ::= nm ORDER BY sortlist frame_opt */
166599
- -1, /* (316) window ::= frame_opt */
166600
- -2, /* (317) window ::= nm frame_opt */
166601
- 0, /* (318) frame_opt ::= */
166602
- -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166603
- -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166604
- -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
166605
- -1, /* (322) frame_bound_s ::= frame_bound */
166606
- -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
166607
- -1, /* (324) frame_bound_e ::= frame_bound */
166608
- -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
166609
- -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
166610
- -2, /* (327) frame_bound ::= CURRENT ROW */
166611
- 0, /* (328) frame_exclude_opt ::= */
166612
- -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
166613
- -2, /* (330) frame_exclude ::= NO OTHERS */
166614
- -2, /* (331) frame_exclude ::= CURRENT ROW */
166615
- -1, /* (332) frame_exclude ::= GROUP|TIES */
166616
- -2, /* (333) window_clause ::= WINDOW windowdefn_list */
166617
- -2, /* (334) filter_over ::= filter_clause over_clause */
166618
- -1, /* (335) filter_over ::= over_clause */
166619
- -1, /* (336) filter_over ::= filter_clause */
166620
- -4, /* (337) over_clause ::= OVER LP window RP */
166621
- -2, /* (338) over_clause ::= OVER nm */
166622
- -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */
166623
- -1, /* (340) input ::= cmdlist */
166624
- -2, /* (341) cmdlist ::= cmdlist ecmd */
166625
- -1, /* (342) cmdlist ::= ecmd */
166626
- -1, /* (343) ecmd ::= SEMI */
166627
- -2, /* (344) ecmd ::= cmdx SEMI */
166628
- -3, /* (345) ecmd ::= explain cmdx SEMI */
166629
- 0, /* (346) trans_opt ::= */
166630
- -1, /* (347) trans_opt ::= TRANSACTION */
166631
- -2, /* (348) trans_opt ::= TRANSACTION nm */
166632
- -1, /* (349) savepoint_opt ::= SAVEPOINT */
166633
- 0, /* (350) savepoint_opt ::= */
166634
- -2, /* (351) cmd ::= create_table create_table_args */
166635
- -1, /* (352) table_option_set ::= table_option */
166636
- -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */
166637
- -2, /* (354) columnlist ::= columnname carglist */
166638
- -1, /* (355) nm ::= ID|INDEXED */
166639
- -1, /* (356) nm ::= STRING */
166640
- -1, /* (357) nm ::= JOIN_KW */
166641
- -1, /* (358) typetoken ::= typename */
166642
- -1, /* (359) typename ::= ID|STRING */
166643
- -1, /* (360) signed ::= plus_num */
166644
- -1, /* (361) signed ::= minus_num */
166645
- -2, /* (362) carglist ::= carglist ccons */
166646
- 0, /* (363) carglist ::= */
166647
- -2, /* (364) ccons ::= NULL onconf */
166648
- -4, /* (365) ccons ::= GENERATED ALWAYS AS generated */
166649
- -2, /* (366) ccons ::= AS generated */
166650
- -2, /* (367) conslist_opt ::= COMMA conslist */
166651
- -3, /* (368) conslist ::= conslist tconscomma tcons */
166652
- -1, /* (369) conslist ::= tcons */
166653
- 0, /* (370) tconscomma ::= */
166654
- -1, /* (371) defer_subclause_opt ::= defer_subclause */
166655
- -1, /* (372) resolvetype ::= raisetype */
166656
- -1, /* (373) selectnowith ::= oneselect */
166657
- -1, /* (374) oneselect ::= values */
166658
- -2, /* (375) sclp ::= selcollist COMMA */
166659
- -1, /* (376) as ::= ID|STRING */
166660
- -1, /* (377) indexed_opt ::= indexed_by */
166661
- 0, /* (378) returning ::= */
166662
- -1, /* (379) expr ::= term */
166663
- -1, /* (380) likeop ::= LIKE_KW|MATCH */
166664
- -1, /* (381) exprlist ::= nexprlist */
166665
- -1, /* (382) nmnum ::= plus_num */
166666
- -1, /* (383) nmnum ::= nm */
166667
- -1, /* (384) nmnum ::= ON */
166668
- -1, /* (385) nmnum ::= DELETE */
166669
- -1, /* (386) nmnum ::= DEFAULT */
166670
- -1, /* (387) plus_num ::= INTEGER|FLOAT */
166671
- 0, /* (388) foreach_clause ::= */
166672
- -3, /* (389) foreach_clause ::= FOR EACH ROW */
166673
- -1, /* (390) trnm ::= nm */
166674
- 0, /* (391) tridxby ::= */
166675
- -1, /* (392) database_kw_opt ::= DATABASE */
166676
- 0, /* (393) database_kw_opt ::= */
166677
- 0, /* (394) kwcolumn_opt ::= */
166678
- -1, /* (395) kwcolumn_opt ::= COLUMNKW */
166679
- -1, /* (396) vtabarglist ::= vtabarg */
166680
- -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
166681
- -2, /* (398) vtabarg ::= vtabarg vtabargtoken */
166682
- 0, /* (399) anylist ::= */
166683
- -4, /* (400) anylist ::= anylist LP anylist RP */
166684
- -2, /* (401) anylist ::= anylist ANY */
166685
- 0, /* (402) with ::= */
166725
+ -6, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */
166726
+ -5, /* (210) expr ::= expr IS DISTINCT FROM expr */
166727
+ -2, /* (211) expr ::= NOT expr */
166728
+ -2, /* (212) expr ::= BITNOT expr */
166729
+ -2, /* (213) expr ::= PLUS|MINUS expr */
166730
+ -3, /* (214) expr ::= expr PTR expr */
166731
+ -1, /* (215) between_op ::= BETWEEN */
166732
+ -2, /* (216) between_op ::= NOT BETWEEN */
166733
+ -5, /* (217) expr ::= expr between_op expr AND expr */
166734
+ -1, /* (218) in_op ::= IN */
166735
+ -2, /* (219) in_op ::= NOT IN */
166736
+ -5, /* (220) expr ::= expr in_op LP exprlist RP */
166737
+ -3, /* (221) expr ::= LP select RP */
166738
+ -5, /* (222) expr ::= expr in_op LP select RP */
166739
+ -5, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */
166740
+ -4, /* (224) expr ::= EXISTS LP select RP */
166741
+ -5, /* (225) expr ::= CASE case_operand case_exprlist case_else END */
166742
+ -5, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166743
+ -4, /* (227) case_exprlist ::= WHEN expr THEN expr */
166744
+ -2, /* (228) case_else ::= ELSE expr */
166745
+ 0, /* (229) case_else ::= */
166746
+ -1, /* (230) case_operand ::= expr */
166747
+ 0, /* (231) case_operand ::= */
166748
+ 0, /* (232) exprlist ::= */
166749
+ -3, /* (233) nexprlist ::= nexprlist COMMA expr */
166750
+ -1, /* (234) nexprlist ::= expr */
166751
+ 0, /* (235) paren_exprlist ::= */
166752
+ -3, /* (236) paren_exprlist ::= LP exprlist RP */
166753
+ -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166754
+ -1, /* (238) uniqueflag ::= UNIQUE */
166755
+ 0, /* (239) uniqueflag ::= */
166756
+ 0, /* (240) eidlist_opt ::= */
166757
+ -3, /* (241) eidlist_opt ::= LP eidlist RP */
166758
+ -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
166759
+ -3, /* (243) eidlist ::= nm collate sortorder */
166760
+ 0, /* (244) collate ::= */
166761
+ -2, /* (245) collate ::= COLLATE ID|STRING */
166762
+ -4, /* (246) cmd ::= DROP INDEX ifexists fullname */
166763
+ -2, /* (247) cmd ::= VACUUM vinto */
166764
+ -3, /* (248) cmd ::= VACUUM nm vinto */
166765
+ -2, /* (249) vinto ::= INTO expr */
166766
+ 0, /* (250) vinto ::= */
166767
+ -3, /* (251) cmd ::= PRAGMA nm dbnm */
166768
+ -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
166769
+ -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166770
+ -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
166771
+ -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166772
+ -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */
166773
+ -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */
166774
+ -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166775
+ -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166776
+ -1, /* (260) trigger_time ::= BEFORE|AFTER */
166777
+ -2, /* (261) trigger_time ::= INSTEAD OF */
166778
+ 0, /* (262) trigger_time ::= */
166779
+ -1, /* (263) trigger_event ::= DELETE|INSERT */
166780
+ -1, /* (264) trigger_event ::= UPDATE */
166781
+ -3, /* (265) trigger_event ::= UPDATE OF idlist */
166782
+ 0, /* (266) when_clause ::= */
166783
+ -2, /* (267) when_clause ::= WHEN expr */
166784
+ -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166785
+ -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
166786
+ -3, /* (270) trnm ::= nm DOT nm */
166787
+ -3, /* (271) tridxby ::= INDEXED BY nm */
166788
+ -2, /* (272) tridxby ::= NOT INDEXED */
166789
+ -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166790
+ -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166791
+ -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166792
+ -3, /* (276) trigger_cmd ::= scanpt select scanpt */
166793
+ -4, /* (277) expr ::= RAISE LP IGNORE RP */
166794
+ -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
166795
+ -1, /* (279) raisetype ::= ROLLBACK */
166796
+ -1, /* (280) raisetype ::= ABORT */
166797
+ -1, /* (281) raisetype ::= FAIL */
166798
+ -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */
166799
+ -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166800
+ -3, /* (284) cmd ::= DETACH database_kw_opt expr */
166801
+ 0, /* (285) key_opt ::= */
166802
+ -2, /* (286) key_opt ::= KEY expr */
166803
+ -1, /* (287) cmd ::= REINDEX */
166804
+ -3, /* (288) cmd ::= REINDEX nm dbnm */
166805
+ -1, /* (289) cmd ::= ANALYZE */
166806
+ -3, /* (290) cmd ::= ANALYZE nm dbnm */
166807
+ -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
166808
+ -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166809
+ -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166810
+ -1, /* (294) add_column_fullname ::= fullname */
166811
+ -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166812
+ -1, /* (296) cmd ::= create_vtab */
166813
+ -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */
166814
+ -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166815
+ 0, /* (299) vtabarg ::= */
166816
+ -1, /* (300) vtabargtoken ::= ANY */
166817
+ -3, /* (301) vtabargtoken ::= lp anylist RP */
166818
+ -1, /* (302) lp ::= LP */
166819
+ -2, /* (303) with ::= WITH wqlist */
166820
+ -3, /* (304) with ::= WITH RECURSIVE wqlist */
166821
+ -1, /* (305) wqas ::= AS */
166822
+ -2, /* (306) wqas ::= AS MATERIALIZED */
166823
+ -3, /* (307) wqas ::= AS NOT MATERIALIZED */
166824
+ -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
166825
+ -1, /* (309) wqlist ::= wqitem */
166826
+ -3, /* (310) wqlist ::= wqlist COMMA wqitem */
166827
+ -1, /* (311) windowdefn_list ::= windowdefn */
166828
+ -3, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166829
+ -5, /* (313) windowdefn ::= nm AS LP window RP */
166830
+ -5, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166831
+ -6, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166832
+ -4, /* (316) window ::= ORDER BY sortlist frame_opt */
166833
+ -5, /* (317) window ::= nm ORDER BY sortlist frame_opt */
166834
+ -1, /* (318) window ::= frame_opt */
166835
+ -2, /* (319) window ::= nm frame_opt */
166836
+ 0, /* (320) frame_opt ::= */
166837
+ -3, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166838
+ -6, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166839
+ -1, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */
166840
+ -1, /* (324) frame_bound_s ::= frame_bound */
166841
+ -2, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */
166842
+ -1, /* (326) frame_bound_e ::= frame_bound */
166843
+ -2, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */
166844
+ -2, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */
166845
+ -2, /* (329) frame_bound ::= CURRENT ROW */
166846
+ 0, /* (330) frame_exclude_opt ::= */
166847
+ -2, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */
166848
+ -2, /* (332) frame_exclude ::= NO OTHERS */
166849
+ -2, /* (333) frame_exclude ::= CURRENT ROW */
166850
+ -1, /* (334) frame_exclude ::= GROUP|TIES */
166851
+ -2, /* (335) window_clause ::= WINDOW windowdefn_list */
166852
+ -2, /* (336) filter_over ::= filter_clause over_clause */
166853
+ -1, /* (337) filter_over ::= over_clause */
166854
+ -1, /* (338) filter_over ::= filter_clause */
166855
+ -4, /* (339) over_clause ::= OVER LP window RP */
166856
+ -2, /* (340) over_clause ::= OVER nm */
166857
+ -5, /* (341) filter_clause ::= FILTER LP WHERE expr RP */
166858
+ -1, /* (342) input ::= cmdlist */
166859
+ -2, /* (343) cmdlist ::= cmdlist ecmd */
166860
+ -1, /* (344) cmdlist ::= ecmd */
166861
+ -1, /* (345) ecmd ::= SEMI */
166862
+ -2, /* (346) ecmd ::= cmdx SEMI */
166863
+ -3, /* (347) ecmd ::= explain cmdx SEMI */
166864
+ 0, /* (348) trans_opt ::= */
166865
+ -1, /* (349) trans_opt ::= TRANSACTION */
166866
+ -2, /* (350) trans_opt ::= TRANSACTION nm */
166867
+ -1, /* (351) savepoint_opt ::= SAVEPOINT */
166868
+ 0, /* (352) savepoint_opt ::= */
166869
+ -2, /* (353) cmd ::= create_table create_table_args */
166870
+ -1, /* (354) table_option_set ::= table_option */
166871
+ -4, /* (355) columnlist ::= columnlist COMMA columnname carglist */
166872
+ -2, /* (356) columnlist ::= columnname carglist */
166873
+ -1, /* (357) nm ::= ID|INDEXED */
166874
+ -1, /* (358) nm ::= STRING */
166875
+ -1, /* (359) nm ::= JOIN_KW */
166876
+ -1, /* (360) typetoken ::= typename */
166877
+ -1, /* (361) typename ::= ID|STRING */
166878
+ -1, /* (362) signed ::= plus_num */
166879
+ -1, /* (363) signed ::= minus_num */
166880
+ -2, /* (364) carglist ::= carglist ccons */
166881
+ 0, /* (365) carglist ::= */
166882
+ -2, /* (366) ccons ::= NULL onconf */
166883
+ -4, /* (367) ccons ::= GENERATED ALWAYS AS generated */
166884
+ -2, /* (368) ccons ::= AS generated */
166885
+ -2, /* (369) conslist_opt ::= COMMA conslist */
166886
+ -3, /* (370) conslist ::= conslist tconscomma tcons */
166887
+ -1, /* (371) conslist ::= tcons */
166888
+ 0, /* (372) tconscomma ::= */
166889
+ -1, /* (373) defer_subclause_opt ::= defer_subclause */
166890
+ -1, /* (374) resolvetype ::= raisetype */
166891
+ -1, /* (375) selectnowith ::= oneselect */
166892
+ -1, /* (376) oneselect ::= values */
166893
+ -2, /* (377) sclp ::= selcollist COMMA */
166894
+ -1, /* (378) as ::= ID|STRING */
166895
+ -1, /* (379) indexed_opt ::= indexed_by */
166896
+ 0, /* (380) returning ::= */
166897
+ -1, /* (381) expr ::= term */
166898
+ -1, /* (382) likeop ::= LIKE_KW|MATCH */
166899
+ -1, /* (383) exprlist ::= nexprlist */
166900
+ -1, /* (384) nmnum ::= plus_num */
166901
+ -1, /* (385) nmnum ::= nm */
166902
+ -1, /* (386) nmnum ::= ON */
166903
+ -1, /* (387) nmnum ::= DELETE */
166904
+ -1, /* (388) nmnum ::= DEFAULT */
166905
+ -1, /* (389) plus_num ::= INTEGER|FLOAT */
166906
+ 0, /* (390) foreach_clause ::= */
166907
+ -3, /* (391) foreach_clause ::= FOR EACH ROW */
166908
+ -1, /* (392) trnm ::= nm */
166909
+ 0, /* (393) tridxby ::= */
166910
+ -1, /* (394) database_kw_opt ::= DATABASE */
166911
+ 0, /* (395) database_kw_opt ::= */
166912
+ 0, /* (396) kwcolumn_opt ::= */
166913
+ -1, /* (397) kwcolumn_opt ::= COLUMNKW */
166914
+ -1, /* (398) vtabarglist ::= vtabarg */
166915
+ -3, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */
166916
+ -2, /* (400) vtabarg ::= vtabarg vtabargtoken */
166917
+ 0, /* (401) anylist ::= */
166918
+ -4, /* (402) anylist ::= anylist LP anylist RP */
166919
+ -2, /* (403) anylist ::= anylist ANY */
166920
+ 0, /* (404) with ::= */
166686166921
};
166687166922
166688166923
static void yy_accept(yyParser*); /* Forward Declaration */
166689166924
166690166925
/*
@@ -166740,11 +166975,11 @@
166740166975
{yymsp[1].minor.yy394 = TK_DEFERRED;}
166741166976
break;
166742166977
case 5: /* transtype ::= DEFERRED */
166743166978
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
166744166979
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
166745
- case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321);
166980
+ case 323: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==323);
166746166981
{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/}
166747166982
break;
166748166983
case 8: /* cmd ::= COMMIT|END trans_opt */
166749166984
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
166750166985
{sqlite3EndTransaction(pParse,yymsp[-1].major);}
@@ -166777,11 +167012,11 @@
166777167012
case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
166778167013
case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
166779167014
case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
166780167015
case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
166781167016
case 98: /* distinct ::= */ yytestcase(yyruleno==98);
166782
- case 242: /* collate ::= */ yytestcase(yyruleno==242);
167017
+ case 244: /* collate ::= */ yytestcase(yyruleno==244);
166783167018
{yymsp[1].minor.yy394 = 0;}
166784167019
break;
166785167020
case 16: /* ifnotexists ::= IF NOT EXISTS */
166786167021
{yymsp[-2].minor.yy394 = 1;}
166787167022
break;
@@ -166961,13 +167196,13 @@
166961167196
case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171);
166962167197
{yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;}
166963167198
break;
166964167199
case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
166965167200
case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
166966
- case 214: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==214);
166967
- case 217: /* in_op ::= NOT IN */ yytestcase(yyruleno==217);
166968
- case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243);
167201
+ case 216: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==216);
167202
+ case 219: /* in_op ::= NOT IN */ yytestcase(yyruleno==219);
167203
+ case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245);
166969167204
{yymsp[-1].minor.yy394 = 1;}
166970167205
break;
166971167206
case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
166972167207
{yymsp[-1].minor.yy394 = 0;}
166973167208
break;
@@ -167113,13 +167348,13 @@
167113167348
{yymsp[0].minor.yy394 = SF_All;}
167114167349
break;
167115167350
case 99: /* sclp ::= */
167116167351
case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132);
167117167352
case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142);
167118
- case 230: /* exprlist ::= */ yytestcase(yyruleno==230);
167119
- case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233);
167120
- case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238);
167353
+ case 232: /* exprlist ::= */ yytestcase(yyruleno==232);
167354
+ case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235);
167355
+ case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240);
167121167356
{yymsp[1].minor.yy322 = 0;}
167122167357
break;
167123167358
case 100: /* selcollist ::= sclp scanpt expr scanpt as */
167124167359
{
167125167360
yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
@@ -167141,12 +167376,12 @@
167141167376
yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
167142167377
}
167143167378
break;
167144167379
case 103: /* as ::= AS nm */
167145167380
case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115);
167146
- case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
167147
- case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255);
167381
+ case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256);
167382
+ case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257);
167148167383
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
167149167384
break;
167150167385
case 105: /* from ::= */
167151167386
case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108);
167152167387
{yymsp[1].minor.yy131 = 0;}
@@ -167314,20 +167549,20 @@
167314167549
break;
167315167550
case 144: /* having_opt ::= */
167316167551
case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
167317167552
case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
167318167553
case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
167319
- case 227: /* case_else ::= */ yytestcase(yyruleno==227);
167320
- case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
167321
- case 248: /* vinto ::= */ yytestcase(yyruleno==248);
167554
+ case 229: /* case_else ::= */ yytestcase(yyruleno==229);
167555
+ case 231: /* case_operand ::= */ yytestcase(yyruleno==231);
167556
+ case 250: /* vinto ::= */ yytestcase(yyruleno==250);
167322167557
{yymsp[1].minor.yy528 = 0;}
167323167558
break;
167324167559
case 145: /* having_opt ::= HAVING expr */
167325167560
case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
167326167561
case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
167327
- case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226);
167328
- case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
167562
+ case 228: /* case_else ::= ELSE expr */ yytestcase(yyruleno==228);
167563
+ case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249);
167329167564
{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
167330167565
break;
167331167566
case 147: /* limit_opt ::= LIMIT expr */
167332167567
{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
167333167568
break;
@@ -167351,11 +167586,22 @@
167351167586
break;
167352167587
case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
167353167588
{
167354167589
sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0);
167355167590
sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list");
167356
- yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, yymsp[-1].minor.yy131);
167591
+ if( yymsp[-1].minor.yy131 ){
167592
+ SrcList *pFromClause = yymsp[-1].minor.yy131;
167593
+ if( pFromClause->nSrc>1 ){
167594
+ Select *pSubquery;
167595
+ Token as;
167596
+ pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0);
167597
+ as.n = 0;
167598
+ as.z = 0;
167599
+ pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
167600
+ }
167601
+ yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause);
167602
+ }
167357167603
sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0);
167358167604
}
167359167605
break;
167360167606
case 158: /* setlist ::= setlist COMMA nm EQ expr */
167361167607
{
@@ -167597,33 +167843,45 @@
167597167843
{
167598167844
yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528);
167599167845
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL);
167600167846
}
167601167847
break;
167602
- case 209: /* expr ::= NOT expr */
167603
- case 210: /* expr ::= BITNOT expr */ yytestcase(yyruleno==210);
167848
+ case 209: /* expr ::= expr IS NOT DISTINCT FROM expr */
167849
+{
167850
+ yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528);
167851
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL);
167852
+}
167853
+ break;
167854
+ case 210: /* expr ::= expr IS DISTINCT FROM expr */
167855
+{
167856
+ yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528);
167857
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL);
167858
+}
167859
+ break;
167860
+ case 211: /* expr ::= NOT expr */
167861
+ case 212: /* expr ::= BITNOT expr */ yytestcase(yyruleno==212);
167604167862
{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/}
167605167863
break;
167606
- case 211: /* expr ::= PLUS|MINUS expr */
167864
+ case 213: /* expr ::= PLUS|MINUS expr */
167607167865
{
167608167866
yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0);
167609167867
/*A-overwrites-B*/
167610167868
}
167611167869
break;
167612
- case 212: /* expr ::= expr PTR expr */
167870
+ case 214: /* expr ::= expr PTR expr */
167613167871
{
167614167872
ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528);
167615167873
pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528);
167616167874
yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
167617167875
}
167618167876
yymsp[-2].minor.yy528 = yylhsminor.yy528;
167619167877
break;
167620
- case 213: /* between_op ::= BETWEEN */
167621
- case 216: /* in_op ::= IN */ yytestcase(yyruleno==216);
167878
+ case 215: /* between_op ::= BETWEEN */
167879
+ case 218: /* in_op ::= IN */ yytestcase(yyruleno==218);
167622167880
{yymsp[0].minor.yy394 = 0;}
167623167881
break;
167624
- case 215: /* expr ::= expr between_op expr AND expr */
167882
+ case 217: /* expr ::= expr between_op expr AND expr */
167625167883
{
167626167884
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
167627167885
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528);
167628167886
yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0);
167629167887
if( yymsp[-4].minor.yy528 ){
@@ -167632,11 +167890,11 @@
167632167890
sqlite3ExprListDelete(pParse->db, pList);
167633167891
}
167634167892
if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167635167893
}
167636167894
break;
167637
- case 218: /* expr ::= expr in_op LP exprlist RP */
167895
+ case 220: /* expr ::= expr in_op LP exprlist RP */
167638167896
{
167639167897
if( yymsp[-1].minor.yy322==0 ){
167640167898
/* Expressions of the form
167641167899
**
167642167900
** expr1 IN ()
@@ -167644,11 +167902,12 @@
167644167902
**
167645167903
** simplify to constants 0 (false) and 1 (true), respectively,
167646167904
** regardless of the value of expr1.
167647167905
*/
167648167906
sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528);
167649
- yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy394 ? "1" : "0");
167907
+ yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false");
167908
+ if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528);
167650167909
}else{
167651167910
Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
167652167911
if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){
167653167912
yymsp[-1].minor.yy322->a[0].pExpr = 0;
167654167913
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
@@ -167672,41 +167931,41 @@
167672167931
}
167673167932
if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167674167933
}
167675167934
}
167676167935
break;
167677
- case 219: /* expr ::= LP select RP */
167936
+ case 221: /* expr ::= LP select RP */
167678167937
{
167679167938
yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
167680167939
sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47);
167681167940
}
167682167941
break;
167683
- case 220: /* expr ::= expr in_op LP select RP */
167942
+ case 222: /* expr ::= expr in_op LP select RP */
167684167943
{
167685167944
yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
167686167945
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47);
167687167946
if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167688167947
}
167689167948
break;
167690
- case 221: /* expr ::= expr in_op nm dbnm paren_exprlist */
167949
+ case 223: /* expr ::= expr in_op nm dbnm paren_exprlist */
167691167950
{
167692167951
SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
167693167952
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
167694167953
if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322);
167695167954
yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
167696167955
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect);
167697167956
if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167698167957
}
167699167958
break;
167700
- case 222: /* expr ::= EXISTS LP select RP */
167959
+ case 224: /* expr ::= EXISTS LP select RP */
167701167960
{
167702167961
Expr *p;
167703167962
p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
167704167963
sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47);
167705167964
}
167706167965
break;
167707
- case 223: /* expr ::= CASE case_operand case_exprlist case_else END */
167966
+ case 225: /* expr ::= CASE case_operand case_exprlist case_else END */
167708167967
{
167709167968
yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0);
167710167969
if( yymsp[-4].minor.yy528 ){
167711167970
yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322;
167712167971
sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528);
@@ -167714,406 +167973,406 @@
167714167973
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
167715167974
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
167716167975
}
167717167976
}
167718167977
break;
167719
- case 224: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
167978
+ case 226: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
167720167979
{
167721167980
yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
167722167981
yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528);
167723167982
}
167724167983
break;
167725
- case 225: /* case_exprlist ::= WHEN expr THEN expr */
167984
+ case 227: /* case_exprlist ::= WHEN expr THEN expr */
167726167985
{
167727167986
yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
167728167987
yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528);
167729167988
}
167730167989
break;
167731
- case 228: /* case_operand ::= expr */
167990
+ case 230: /* case_operand ::= expr */
167732167991
{yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/}
167733167992
break;
167734
- case 231: /* nexprlist ::= nexprlist COMMA expr */
167993
+ case 233: /* nexprlist ::= nexprlist COMMA expr */
167735167994
{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);}
167736167995
break;
167737
- case 232: /* nexprlist ::= expr */
167996
+ case 234: /* nexprlist ::= expr */
167738167997
{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/}
167739167998
break;
167740
- case 234: /* paren_exprlist ::= LP exprlist RP */
167741
- case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239);
167999
+ case 236: /* paren_exprlist ::= LP exprlist RP */
168000
+ case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241);
167742168001
{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
167743168002
break;
167744
- case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
168003
+ case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
167745168004
{
167746168005
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
167747168006
sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394,
167748168007
&yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF);
167749168008
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
167750168009
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
167751168010
}
167752168011
}
167753168012
break;
167754
- case 236: /* uniqueflag ::= UNIQUE */
167755
- case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278);
168013
+ case 238: /* uniqueflag ::= UNIQUE */
168014
+ case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280);
167756168015
{yymsp[0].minor.yy394 = OE_Abort;}
167757168016
break;
167758
- case 237: /* uniqueflag ::= */
168017
+ case 239: /* uniqueflag ::= */
167759168018
{yymsp[1].minor.yy394 = OE_None;}
167760168019
break;
167761
- case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */
168020
+ case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */
167762168021
{
167763168022
yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394);
167764168023
}
167765168024
break;
167766
- case 241: /* eidlist ::= nm collate sortorder */
168025
+ case 243: /* eidlist ::= nm collate sortorder */
167767168026
{
167768168027
yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/
167769168028
}
167770168029
break;
167771
- case 244: /* cmd ::= DROP INDEX ifexists fullname */
168030
+ case 246: /* cmd ::= DROP INDEX ifexists fullname */
167772168031
{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);}
167773168032
break;
167774
- case 245: /* cmd ::= VACUUM vinto */
168033
+ case 247: /* cmd ::= VACUUM vinto */
167775168034
{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);}
167776168035
break;
167777
- case 246: /* cmd ::= VACUUM nm vinto */
168036
+ case 248: /* cmd ::= VACUUM nm vinto */
167778168037
{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);}
167779168038
break;
167780
- case 249: /* cmd ::= PRAGMA nm dbnm */
168039
+ case 251: /* cmd ::= PRAGMA nm dbnm */
167781168040
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
167782168041
break;
167783
- case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
168042
+ case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
167784168043
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
167785168044
break;
167786
- case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
168045
+ case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
167787168046
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
167788168047
break;
167789
- case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
168048
+ case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
167790168049
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
167791168050
break;
167792
- case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
168051
+ case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
167793168052
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
167794168053
break;
167795
- case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
168054
+ case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
167796168055
{
167797168056
Token all;
167798168057
all.z = yymsp[-3].minor.yy0.z;
167799168058
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
167800168059
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all);
167801168060
}
167802168061
break;
167803
- case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
168062
+ case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
167804168063
{
167805168064
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394);
167806168065
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
167807168066
}
167808168067
break;
167809
- case 258: /* trigger_time ::= BEFORE|AFTER */
168068
+ case 260: /* trigger_time ::= BEFORE|AFTER */
167810168069
{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ }
167811168070
break;
167812
- case 259: /* trigger_time ::= INSTEAD OF */
168071
+ case 261: /* trigger_time ::= INSTEAD OF */
167813168072
{ yymsp[-1].minor.yy394 = TK_INSTEAD;}
167814168073
break;
167815
- case 260: /* trigger_time ::= */
168074
+ case 262: /* trigger_time ::= */
167816168075
{ yymsp[1].minor.yy394 = TK_BEFORE; }
167817168076
break;
167818
- case 261: /* trigger_event ::= DELETE|INSERT */
167819
- case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262);
168077
+ case 263: /* trigger_event ::= DELETE|INSERT */
168078
+ case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264);
167820168079
{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;}
167821168080
break;
167822
- case 263: /* trigger_event ::= UPDATE OF idlist */
168081
+ case 265: /* trigger_event ::= UPDATE OF idlist */
167823168082
{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;}
167824168083
break;
167825
- case 264: /* when_clause ::= */
167826
- case 283: /* key_opt ::= */ yytestcase(yyruleno==283);
168084
+ case 266: /* when_clause ::= */
168085
+ case 285: /* key_opt ::= */ yytestcase(yyruleno==285);
167827168086
{ yymsp[1].minor.yy528 = 0; }
167828168087
break;
167829
- case 265: /* when_clause ::= WHEN expr */
167830
- case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284);
168088
+ case 267: /* when_clause ::= WHEN expr */
168089
+ case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286);
167831168090
{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; }
167832168091
break;
167833
- case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
168092
+ case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
167834168093
{
167835168094
assert( yymsp[-2].minor.yy33!=0 );
167836168095
yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33;
167837168096
yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33;
167838168097
}
167839168098
break;
167840
- case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */
168099
+ case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */
167841168100
{
167842168101
assert( yymsp[-1].minor.yy33!=0 );
167843168102
yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33;
167844168103
}
167845168104
break;
167846
- case 268: /* trnm ::= nm DOT nm */
168105
+ case 270: /* trnm ::= nm DOT nm */
167847168106
{
167848168107
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
167849168108
sqlite3ErrorMsg(pParse,
167850168109
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
167851168110
"statements within triggers");
167852168111
}
167853168112
break;
167854
- case 269: /* tridxby ::= INDEXED BY nm */
168113
+ case 271: /* tridxby ::= INDEXED BY nm */
167855168114
{
167856168115
sqlite3ErrorMsg(pParse,
167857168116
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
167858168117
"within triggers");
167859168118
}
167860168119
break;
167861
- case 270: /* tridxby ::= NOT INDEXED */
168120
+ case 272: /* tridxby ::= NOT INDEXED */
167862168121
{
167863168122
sqlite3ErrorMsg(pParse,
167864168123
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
167865168124
"within triggers");
167866168125
}
167867168126
break;
167868
- case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
168127
+ case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
167869168128
{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);}
167870168129
yymsp[-8].minor.yy33 = yylhsminor.yy33;
167871168130
break;
167872
- case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
168131
+ case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
167873168132
{
167874168133
yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/
167875168134
}
167876168135
yymsp[-7].minor.yy33 = yylhsminor.yy33;
167877168136
break;
167878
- case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
168137
+ case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
167879168138
{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);}
167880168139
yymsp[-5].minor.yy33 = yylhsminor.yy33;
167881168140
break;
167882
- case 274: /* trigger_cmd ::= scanpt select scanpt */
168141
+ case 276: /* trigger_cmd ::= scanpt select scanpt */
167883168142
{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/}
167884168143
yymsp[-2].minor.yy33 = yylhsminor.yy33;
167885168144
break;
167886
- case 275: /* expr ::= RAISE LP IGNORE RP */
168145
+ case 277: /* expr ::= RAISE LP IGNORE RP */
167887168146
{
167888168147
yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
167889168148
if( yymsp[-3].minor.yy528 ){
167890168149
yymsp[-3].minor.yy528->affExpr = OE_Ignore;
167891168150
}
167892168151
}
167893168152
break;
167894
- case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */
168153
+ case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */
167895168154
{
167896168155
yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
167897168156
if( yymsp[-5].minor.yy528 ) {
167898168157
yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394;
167899168158
}
167900168159
}
167901168160
break;
167902
- case 277: /* raisetype ::= ROLLBACK */
168161
+ case 279: /* raisetype ::= ROLLBACK */
167903168162
{yymsp[0].minor.yy394 = OE_Rollback;}
167904168163
break;
167905
- case 279: /* raisetype ::= FAIL */
168164
+ case 281: /* raisetype ::= FAIL */
167906168165
{yymsp[0].minor.yy394 = OE_Fail;}
167907168166
break;
167908
- case 280: /* cmd ::= DROP TRIGGER ifexists fullname */
168167
+ case 282: /* cmd ::= DROP TRIGGER ifexists fullname */
167909168168
{
167910168169
sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394);
167911168170
}
167912168171
break;
167913
- case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
168172
+ case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
167914168173
{
167915168174
sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528);
167916168175
}
167917168176
break;
167918
- case 282: /* cmd ::= DETACH database_kw_opt expr */
168177
+ case 284: /* cmd ::= DETACH database_kw_opt expr */
167919168178
{
167920168179
sqlite3Detach(pParse, yymsp[0].minor.yy528);
167921168180
}
167922168181
break;
167923
- case 285: /* cmd ::= REINDEX */
168182
+ case 287: /* cmd ::= REINDEX */
167924168183
{sqlite3Reindex(pParse, 0, 0);}
167925168184
break;
167926
- case 286: /* cmd ::= REINDEX nm dbnm */
168185
+ case 288: /* cmd ::= REINDEX nm dbnm */
167927168186
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
167928168187
break;
167929
- case 287: /* cmd ::= ANALYZE */
168188
+ case 289: /* cmd ::= ANALYZE */
167930168189
{sqlite3Analyze(pParse, 0, 0);}
167931168190
break;
167932
- case 288: /* cmd ::= ANALYZE nm dbnm */
168191
+ case 290: /* cmd ::= ANALYZE nm dbnm */
167933168192
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
167934168193
break;
167935
- case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
168194
+ case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
167936168195
{
167937168196
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0);
167938168197
}
167939168198
break;
167940
- case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
168199
+ case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
167941168200
{
167942168201
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
167943168202
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
167944168203
}
167945168204
break;
167946
- case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
168205
+ case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
167947168206
{
167948168207
sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0);
167949168208
}
167950168209
break;
167951
- case 292: /* add_column_fullname ::= fullname */
168210
+ case 294: /* add_column_fullname ::= fullname */
167952168211
{
167953168212
disableLookaside(pParse);
167954168213
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131);
167955168214
}
167956168215
break;
167957
- case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
168216
+ case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
167958168217
{
167959168218
sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
167960168219
}
167961168220
break;
167962
- case 294: /* cmd ::= create_vtab */
168221
+ case 296: /* cmd ::= create_vtab */
167963168222
{sqlite3VtabFinishParse(pParse,0);}
167964168223
break;
167965
- case 295: /* cmd ::= create_vtab LP vtabarglist RP */
168224
+ case 297: /* cmd ::= create_vtab LP vtabarglist RP */
167966168225
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
167967168226
break;
167968
- case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
168227
+ case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
167969168228
{
167970168229
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394);
167971168230
}
167972168231
break;
167973
- case 297: /* vtabarg ::= */
168232
+ case 299: /* vtabarg ::= */
167974168233
{sqlite3VtabArgInit(pParse);}
167975168234
break;
167976
- case 298: /* vtabargtoken ::= ANY */
167977
- case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299);
167978
- case 300: /* lp ::= LP */ yytestcase(yyruleno==300);
168235
+ case 300: /* vtabargtoken ::= ANY */
168236
+ case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301);
168237
+ case 302: /* lp ::= LP */ yytestcase(yyruleno==302);
167979168238
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
167980168239
break;
167981
- case 301: /* with ::= WITH wqlist */
167982
- case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302);
168240
+ case 303: /* with ::= WITH wqlist */
168241
+ case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304);
167983168242
{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); }
167984168243
break;
167985
- case 303: /* wqas ::= AS */
168244
+ case 305: /* wqas ::= AS */
167986168245
{yymsp[0].minor.yy516 = M10d_Any;}
167987168246
break;
167988
- case 304: /* wqas ::= AS MATERIALIZED */
168247
+ case 306: /* wqas ::= AS MATERIALIZED */
167989168248
{yymsp[-1].minor.yy516 = M10d_Yes;}
167990168249
break;
167991
- case 305: /* wqas ::= AS NOT MATERIALIZED */
168250
+ case 307: /* wqas ::= AS NOT MATERIALIZED */
167992168251
{yymsp[-2].minor.yy516 = M10d_No;}
167993168252
break;
167994
- case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */
168253
+ case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */
167995168254
{
167996168255
yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/
167997168256
}
167998168257
break;
167999
- case 307: /* wqlist ::= wqitem */
168258
+ case 309: /* wqlist ::= wqitem */
168000168259
{
168001168260
yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/
168002168261
}
168003168262
break;
168004
- case 308: /* wqlist ::= wqlist COMMA wqitem */
168263
+ case 310: /* wqlist ::= wqlist COMMA wqitem */
168005168264
{
168006168265
yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385);
168007168266
}
168008168267
break;
168009
- case 309: /* windowdefn_list ::= windowdefn */
168268
+ case 311: /* windowdefn_list ::= windowdefn */
168010168269
{ yylhsminor.yy41 = yymsp[0].minor.yy41; }
168011168270
yymsp[0].minor.yy41 = yylhsminor.yy41;
168012168271
break;
168013
- case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
168272
+ case 312: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
168014168273
{
168015168274
assert( yymsp[0].minor.yy41!=0 );
168016168275
sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41);
168017168276
yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41;
168018168277
yylhsminor.yy41 = yymsp[0].minor.yy41;
168019168278
}
168020168279
yymsp[-2].minor.yy41 = yylhsminor.yy41;
168021168280
break;
168022
- case 311: /* windowdefn ::= nm AS LP window RP */
168281
+ case 313: /* windowdefn ::= nm AS LP window RP */
168023168282
{
168024168283
if( ALWAYS(yymsp[-1].minor.yy41) ){
168025168284
yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
168026168285
}
168027168286
yylhsminor.yy41 = yymsp[-1].minor.yy41;
168028168287
}
168029168288
yymsp[-4].minor.yy41 = yylhsminor.yy41;
168030168289
break;
168031
- case 312: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
168290
+ case 314: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
168032168291
{
168033168292
yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0);
168034168293
}
168035168294
break;
168036
- case 313: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
168295
+ case 315: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
168037168296
{
168038168297
yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0);
168039168298
}
168040168299
yymsp[-5].minor.yy41 = yylhsminor.yy41;
168041168300
break;
168042
- case 314: /* window ::= ORDER BY sortlist frame_opt */
168301
+ case 316: /* window ::= ORDER BY sortlist frame_opt */
168043168302
{
168044168303
yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0);
168045168304
}
168046168305
break;
168047
- case 315: /* window ::= nm ORDER BY sortlist frame_opt */
168306
+ case 317: /* window ::= nm ORDER BY sortlist frame_opt */
168048168307
{
168049168308
yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
168050168309
}
168051168310
yymsp[-4].minor.yy41 = yylhsminor.yy41;
168052168311
break;
168053
- case 316: /* window ::= frame_opt */
168054
- case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335);
168312
+ case 318: /* window ::= frame_opt */
168313
+ case 337: /* filter_over ::= over_clause */ yytestcase(yyruleno==337);
168055168314
{
168056168315
yylhsminor.yy41 = yymsp[0].minor.yy41;
168057168316
}
168058168317
yymsp[0].minor.yy41 = yylhsminor.yy41;
168059168318
break;
168060
- case 317: /* window ::= nm frame_opt */
168319
+ case 319: /* window ::= nm frame_opt */
168061168320
{
168062168321
yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0);
168063168322
}
168064168323
yymsp[-1].minor.yy41 = yylhsminor.yy41;
168065168324
break;
168066
- case 318: /* frame_opt ::= */
168325
+ case 320: /* frame_opt ::= */
168067168326
{
168068168327
yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
168069168328
}
168070168329
break;
168071
- case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
168330
+ case 321: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
168072168331
{
168073168332
yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516);
168074168333
}
168075168334
yymsp[-2].minor.yy41 = yylhsminor.yy41;
168076168335
break;
168077
- case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
168336
+ case 322: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
168078168337
{
168079168338
yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516);
168080168339
}
168081168340
yymsp[-5].minor.yy41 = yylhsminor.yy41;
168082168341
break;
168083
- case 322: /* frame_bound_s ::= frame_bound */
168084
- case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324);
168342
+ case 324: /* frame_bound_s ::= frame_bound */
168343
+ case 326: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==326);
168085168344
{yylhsminor.yy595 = yymsp[0].minor.yy595;}
168086168345
yymsp[0].minor.yy595 = yylhsminor.yy595;
168087168346
break;
168088
- case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */
168089
- case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325);
168090
- case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327);
168347
+ case 325: /* frame_bound_s ::= UNBOUNDED PRECEDING */
168348
+ case 327: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==327);
168349
+ case 329: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==329);
168091168350
{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;}
168092168351
yymsp[-1].minor.yy595 = yylhsminor.yy595;
168093168352
break;
168094
- case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */
168353
+ case 328: /* frame_bound ::= expr PRECEDING|FOLLOWING */
168095168354
{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;}
168096168355
yymsp[-1].minor.yy595 = yylhsminor.yy595;
168097168356
break;
168098
- case 328: /* frame_exclude_opt ::= */
168357
+ case 330: /* frame_exclude_opt ::= */
168099168358
{yymsp[1].minor.yy516 = 0;}
168100168359
break;
168101
- case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
168360
+ case 331: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
168102168361
{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;}
168103168362
break;
168104
- case 330: /* frame_exclude ::= NO OTHERS */
168105
- case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331);
168363
+ case 332: /* frame_exclude ::= NO OTHERS */
168364
+ case 333: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==333);
168106168365
{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/}
168107168366
break;
168108
- case 332: /* frame_exclude ::= GROUP|TIES */
168367
+ case 334: /* frame_exclude ::= GROUP|TIES */
168109168368
{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/}
168110168369
break;
168111
- case 333: /* window_clause ::= WINDOW windowdefn_list */
168370
+ case 335: /* window_clause ::= WINDOW windowdefn_list */
168112168371
{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; }
168113168372
break;
168114
- case 334: /* filter_over ::= filter_clause over_clause */
168373
+ case 336: /* filter_over ::= filter_clause over_clause */
168115168374
{
168116168375
if( yymsp[0].minor.yy41 ){
168117168376
yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528;
168118168377
}else{
168119168378
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
@@ -168120,11 +168379,11 @@
168120168379
}
168121168380
yylhsminor.yy41 = yymsp[0].minor.yy41;
168122168381
}
168123168382
yymsp[-1].minor.yy41 = yylhsminor.yy41;
168124168383
break;
168125
- case 336: /* filter_over ::= filter_clause */
168384
+ case 338: /* filter_over ::= filter_clause */
168126168385
{
168127168386
yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
168128168387
if( yylhsminor.yy41 ){
168129168388
yylhsminor.yy41->eFrmType = TK_FILTER;
168130168389
yylhsminor.yy41->pFilter = yymsp[0].minor.yy528;
@@ -168132,91 +168391,91 @@
168132168391
sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528);
168133168392
}
168134168393
}
168135168394
yymsp[0].minor.yy41 = yylhsminor.yy41;
168136168395
break;
168137
- case 337: /* over_clause ::= OVER LP window RP */
168396
+ case 339: /* over_clause ::= OVER LP window RP */
168138168397
{
168139168398
yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41;
168140168399
assert( yymsp[-3].minor.yy41!=0 );
168141168400
}
168142168401
break;
168143
- case 338: /* over_clause ::= OVER nm */
168402
+ case 340: /* over_clause ::= OVER nm */
168144168403
{
168145168404
yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
168146168405
if( yymsp[-1].minor.yy41 ){
168147168406
yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
168148168407
}
168149168408
}
168150168409
break;
168151
- case 339: /* filter_clause ::= FILTER LP WHERE expr RP */
168410
+ case 341: /* filter_clause ::= FILTER LP WHERE expr RP */
168152168411
{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; }
168153168412
break;
168154168413
default:
168155
- /* (340) input ::= cmdlist */ yytestcase(yyruleno==340);
168156
- /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341);
168157
- /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342);
168158
- /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343);
168159
- /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344);
168160
- /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345);
168161
- /* (346) trans_opt ::= */ yytestcase(yyruleno==346);
168162
- /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347);
168163
- /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348);
168164
- /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349);
168165
- /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350);
168166
- /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351);
168167
- /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352);
168168
- /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353);
168169
- /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354);
168170
- /* (355) nm ::= ID|INDEXED */ yytestcase(yyruleno==355);
168171
- /* (356) nm ::= STRING */ yytestcase(yyruleno==356);
168172
- /* (357) nm ::= JOIN_KW */ yytestcase(yyruleno==357);
168173
- /* (358) typetoken ::= typename */ yytestcase(yyruleno==358);
168174
- /* (359) typename ::= ID|STRING */ yytestcase(yyruleno==359);
168175
- /* (360) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=360);
168176
- /* (361) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=361);
168177
- /* (362) carglist ::= carglist ccons */ yytestcase(yyruleno==362);
168178
- /* (363) carglist ::= */ yytestcase(yyruleno==363);
168179
- /* (364) ccons ::= NULL onconf */ yytestcase(yyruleno==364);
168180
- /* (365) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==365);
168181
- /* (366) ccons ::= AS generated */ yytestcase(yyruleno==366);
168182
- /* (367) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==367);
168183
- /* (368) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==368);
168184
- /* (369) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=369);
168185
- /* (370) tconscomma ::= */ yytestcase(yyruleno==370);
168186
- /* (371) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=371);
168187
- /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372);
168188
- /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373);
168189
- /* (374) oneselect ::= values */ yytestcase(yyruleno==374);
168190
- /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375);
168191
- /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376);
168192
- /* (377) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=377);
168193
- /* (378) returning ::= */ yytestcase(yyruleno==378);
168194
- /* (379) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=379);
168195
- /* (380) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==380);
168196
- /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381);
168197
- /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382);
168198
- /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383);
168199
- /* (384) nmnum ::= ON */ yytestcase(yyruleno==384);
168200
- /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385);
168201
- /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386);
168202
- /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387);
168203
- /* (388) foreach_clause ::= */ yytestcase(yyruleno==388);
168204
- /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389);
168205
- /* (390) trnm ::= nm */ yytestcase(yyruleno==390);
168206
- /* (391) tridxby ::= */ yytestcase(yyruleno==391);
168207
- /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392);
168208
- /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393);
168209
- /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394);
168210
- /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395);
168211
- /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396);
168212
- /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397);
168213
- /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398);
168214
- /* (399) anylist ::= */ yytestcase(yyruleno==399);
168215
- /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400);
168216
- /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401);
168217
- /* (402) with ::= */ yytestcase(yyruleno==402);
168414
+ /* (342) input ::= cmdlist */ yytestcase(yyruleno==342);
168415
+ /* (343) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==343);
168416
+ /* (344) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=344);
168417
+ /* (345) ecmd ::= SEMI */ yytestcase(yyruleno==345);
168418
+ /* (346) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==346);
168419
+ /* (347) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=347);
168420
+ /* (348) trans_opt ::= */ yytestcase(yyruleno==348);
168421
+ /* (349) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==349);
168422
+ /* (350) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==350);
168423
+ /* (351) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==351);
168424
+ /* (352) savepoint_opt ::= */ yytestcase(yyruleno==352);
168425
+ /* (353) cmd ::= create_table create_table_args */ yytestcase(yyruleno==353);
168426
+ /* (354) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=354);
168427
+ /* (355) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==355);
168428
+ /* (356) columnlist ::= columnname carglist */ yytestcase(yyruleno==356);
168429
+ /* (357) nm ::= ID|INDEXED */ yytestcase(yyruleno==357);
168430
+ /* (358) nm ::= STRING */ yytestcase(yyruleno==358);
168431
+ /* (359) nm ::= JOIN_KW */ yytestcase(yyruleno==359);
168432
+ /* (360) typetoken ::= typename */ yytestcase(yyruleno==360);
168433
+ /* (361) typename ::= ID|STRING */ yytestcase(yyruleno==361);
168434
+ /* (362) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=362);
168435
+ /* (363) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=363);
168436
+ /* (364) carglist ::= carglist ccons */ yytestcase(yyruleno==364);
168437
+ /* (365) carglist ::= */ yytestcase(yyruleno==365);
168438
+ /* (366) ccons ::= NULL onconf */ yytestcase(yyruleno==366);
168439
+ /* (367) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==367);
168440
+ /* (368) ccons ::= AS generated */ yytestcase(yyruleno==368);
168441
+ /* (369) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==369);
168442
+ /* (370) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==370);
168443
+ /* (371) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=371);
168444
+ /* (372) tconscomma ::= */ yytestcase(yyruleno==372);
168445
+ /* (373) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=373);
168446
+ /* (374) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=374);
168447
+ /* (375) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=375);
168448
+ /* (376) oneselect ::= values */ yytestcase(yyruleno==376);
168449
+ /* (377) sclp ::= selcollist COMMA */ yytestcase(yyruleno==377);
168450
+ /* (378) as ::= ID|STRING */ yytestcase(yyruleno==378);
168451
+ /* (379) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=379);
168452
+ /* (380) returning ::= */ yytestcase(yyruleno==380);
168453
+ /* (381) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=381);
168454
+ /* (382) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==382);
168455
+ /* (383) exprlist ::= nexprlist */ yytestcase(yyruleno==383);
168456
+ /* (384) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=384);
168457
+ /* (385) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=385);
168458
+ /* (386) nmnum ::= ON */ yytestcase(yyruleno==386);
168459
+ /* (387) nmnum ::= DELETE */ yytestcase(yyruleno==387);
168460
+ /* (388) nmnum ::= DEFAULT */ yytestcase(yyruleno==388);
168461
+ /* (389) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==389);
168462
+ /* (390) foreach_clause ::= */ yytestcase(yyruleno==390);
168463
+ /* (391) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==391);
168464
+ /* (392) trnm ::= nm */ yytestcase(yyruleno==392);
168465
+ /* (393) tridxby ::= */ yytestcase(yyruleno==393);
168466
+ /* (394) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==394);
168467
+ /* (395) database_kw_opt ::= */ yytestcase(yyruleno==395);
168468
+ /* (396) kwcolumn_opt ::= */ yytestcase(yyruleno==396);
168469
+ /* (397) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==397);
168470
+ /* (398) vtabarglist ::= vtabarg */ yytestcase(yyruleno==398);
168471
+ /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==399);
168472
+ /* (400) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==400);
168473
+ /* (401) anylist ::= */ yytestcase(yyruleno==401);
168474
+ /* (402) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==402);
168475
+ /* (403) anylist ::= anylist ANY */ yytestcase(yyruleno==403);
168476
+ /* (404) with ::= */ yytestcase(yyruleno==404);
168218168477
break;
168219168478
/********** End reduce actions ************************************************/
168220168479
};
168221168480
assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
168222168481
yygoto = yyRuleInfoLhs[yyruleno];
@@ -174912,10 +175171,28 @@
174912175171
*/
174913175172
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
174914175173
int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
174915175174
return iDb<0 ? 0 : db->aDb[iDb].pBt;
174916175175
}
175176
+
175177
+/*
175178
+** Return the name of the N-th database schema. Return NULL if N is out
175179
+** of range.
175180
+*/
175181
+SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){
175182
+#ifdef SQLITE_ENABLE_API_ARMOR
175183
+ if( !sqlite3SafetyCheckOk(db) ){
175184
+ (void)SQLITE_MISUSE_BKPT;
175185
+ return 0;
175186
+ }
175187
+#endif
175188
+ if( N<0 || N>=db->nDb ){
175189
+ return 0;
175190
+ }else{
175191
+ return db->aDb[N].zDbSName;
175192
+ }
175193
+}
174917175194
174918175195
/*
174919175196
** Return the filename of the database associated with a database
174920175197
** connection.
174921175198
*/
@@ -190551,10 +190828,12 @@
190551190828
if( rc==SQLITE_OK ){
190552190829
if( pNode->key.n ){
190553190830
pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix);
190554190831
}
190555190832
pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix);
190833
+ assert( nPrefix+nSuffix<=nTerm );
190834
+ assert( nPrefix>=0 );
190556190835
memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix);
190557190836
pBlk->n += nSuffix;
190558190837
190559190838
memcpy(pNode->key.a, zTerm, nTerm);
190560190839
pNode->key.n = nTerm;
@@ -190673,10 +190952,11 @@
190673190952
NodeWriter *pLeaf; /* Object used to write leaf nodes */
190674190953
190675190954
pLeaf = &pWriter->aNodeWriter[0];
190676190955
nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm);
190677190956
nSuffix = nTerm - nPrefix;
190957
+ if(nSuffix<=0 ) return FTS_CORRUPT_VTAB;
190678190958
190679190959
nSpace = sqlite3Fts3VarintLen(nPrefix);
190680190960
nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
190681190961
nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
190682190962
@@ -236295,11 +236575,11 @@
236295236575
int nArg, /* Number of args */
236296236576
sqlite3_value **apUnused /* Function arguments */
236297236577
){
236298236578
assert( nArg==0 );
236299236579
UNUSED_PARAM2(nArg, apUnused);
236300
- sqlite3_result_text(pCtx, "fts5: 2022-05-10 00:24:01 c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527", -1, SQLITE_TRANSIENT);
236580
+ sqlite3_result_text(pCtx, "fts5: 2022-06-15 16:26:37 56c60a35ea457f06db58ec3f694a1ae16fd03e6625da1d7879d63d72bbcb1c62", -1, SQLITE_TRANSIENT);
236301236581
}
236302236582
236303236583
/*
236304236584
** Return true if zName is the extension on one of the shadow tables used
236305236585
** by this module.
236306236586
--- 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-05-10 00:24:01 c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -6580,10 +6580,32 @@
6580 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
6581 ** create the statement in the first place.
6582 */
6583 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
6584
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6585 /*
6586 ** CAPI3REF: Return The Filename For A Database Connection
6587 ** METHOD: sqlite3
6588 **
6589 ** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
@@ -15702,17 +15724,18 @@
15702 #define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */
15703 #define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */
15704 #define OP_VRename 176
15705 #define OP_Pagecount 177
15706 #define OP_MaxPgcnt 178
15707 #define OP_FilterAdd 179 /* synopsis: filter(P1) += key(P3@P4) */
15708 #define OP_Trace 180
15709 #define OP_CursorHint 181
15710 #define OP_ReleaseReg 182 /* synopsis: release r[P1@P2] mask P3 */
15711 #define OP_Noop 183
15712 #define OP_Explain 184
15713 #define OP_Abortable 185
 
15714
15715 /* Properties such as "out2" or "jump" that are specified in
15716 ** comments following the "case" for each opcode in the vdbe.c
15717 ** are encoded into bitvectors as follows:
15718 */
@@ -15743,12 +15766,12 @@
15743 /* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
15744 /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
15745 /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
15746 /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15747 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15748 /* 176 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15749 /* 184 */ 0x00, 0x00,}
15750
15751 /* The resolve3P2Values() routine is able to run faster if it knows
15752 ** the value of the largest JUMP opcode. The smaller the maximum
15753 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15754 ** generated this include file strives to group all JUMP opcodes
@@ -16285,10 +16308,17 @@
16285 /* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h
16286 */
16287 #ifndef SQLITE_MAX_PATHLEN
16288 # define SQLITE_MAX_PATHLEN FILENAME_MAX
16289 #endif
 
 
 
 
 
 
 
16290
16291 /*
16292 ** The default size of a disk sector
16293 */
16294 #ifndef SQLITE_DEFAULT_SECTOR_SIZE
@@ -17157,11 +17187,11 @@
17157 #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
17158 #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
17159 #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
17160 ** single query - might change over time */
17161 #define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
17162 #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
17163 #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
17164 #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
17165 #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
17166 #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
17167 #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
@@ -17174,10 +17204,11 @@
17174 #define INLINEFUNC_implies_nonnull_row 1
17175 #define INLINEFUNC_expr_implies_expr 2
17176 #define INLINEFUNC_expr_compare 3
17177 #define INLINEFUNC_affinity 4
17178 #define INLINEFUNC_iif 5
 
17179 #define INLINEFUNC_unlikely 99 /* Default case */
17180
17181 /*
17182 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
17183 ** used to create the initializers for the FuncDef structures.
@@ -18120,11 +18151,11 @@
18120 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
18121 ** TK_VARIABLE: variable number (always >= 1).
18122 ** TK_SELECT_COLUMN: column of the result vector */
18123 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
18124 union {
18125 int iJoin; /* If EP_FromJoin, the right table of the join */
18126 int iOfst; /* else: start of token from start of statement */
18127 } w;
18128 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
18129 union {
18130 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@@ -18141,33 +18172,33 @@
18141 ** Value restrictions:
18142 **
18143 ** EP_Agg == NC_HasAgg == SF_HasAgg
18144 ** EP_Win == NC_HasWin
18145 */
18146 #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
18147 #define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
18148 #define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
18149 #define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
18150 #define EP_Agg 0x000010 /* Contains one or more aggregate functions */
18151 #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
18152 #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
18153 #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
18154 #define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
18155 #define EP_Commuted 0x000200 /* Comparison operator has been commuted */
18156 #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
18157 #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
18158 #define EP_Skip 0x001000 /* Operator does not contribute to affinity */
18159 #define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
18160 #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
18161 #define EP_Win 0x008000 /* Contains window functions */
18162 #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
18163 #define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */
18164 #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
18165 #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
18166 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
18167 #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
18168 #define EP_InnerJoin 0x400000 /* Originates in ON/USING of an inner join */
18169 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
18170 #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
18171 #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
18172 #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
18173 #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
@@ -18186,12 +18217,12 @@
18186 */
18187 #define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
18188 #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
18189 #define ExprSetProperty(E,P) (E)->flags|=(P)
18190 #define ExprClearProperty(E,P) (E)->flags&=~(P)
18191 #define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
18192 #define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
18193
18194 /* Macros used to ensure that the correct members of unions are accessed
18195 ** in Expr.
18196 */
18197 #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
@@ -18366,16 +18397,18 @@
18366 u8 jointype; /* Type of join between this table and the previous */
18367 unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
18368 unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
18369 unsigned isTabFunc :1; /* True if table-valued-function syntax */
18370 unsigned isCorrelated :1; /* True if sub-query is correlated */
 
18371 unsigned viaCoroutine :1; /* Implemented as a co-routine */
18372 unsigned isRecursive :1; /* True for recursive reference in WITH */
18373 unsigned fromDDL :1; /* Comes from sqlite_schema */
18374 unsigned isCte :1; /* This is a CTE */
18375 unsigned notCte :1; /* This item may not match a CTE */
18376 unsigned isUsing :1; /* u3.pUsing is valid */
 
18377 unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */
18378 unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
18379 } fg;
18380 int iCursor; /* The VDBE cursor number used to access this table */
18381 union {
@@ -20595,11 +20628,10 @@
20595 ** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
20596 */
20597 #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */
20598 #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */
20599 #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
20600 #define IN_INDEX_REUSE_CUR 0x0008 /* Reuse prior table cursor */
20601 SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);
20602
20603 SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
20604 SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
20605 #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
@@ -22224,11 +22256,11 @@
22224 u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
22225 #endif
22226 Bool isEphemeral:1; /* True for an ephemeral table */
22227 Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
22228 Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
22229 Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */
22230 u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
22231 union { /* pBtx for isEphermeral. pAltMap otherwise */
22232 Btree *pBtx; /* Separate file holding temporary table */
22233 u32 *aAltMap; /* Mapping from table to index column numbers */
22234 } ub;
@@ -30545,11 +30577,13 @@
30545 /*
30546 ** If pExpr has a byte offset for the start of a token, record that as
30547 ** as the error offset.
30548 */
30549 SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
30550 while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
 
 
30551 pExpr = pExpr->pLeft;
30552 }
30553 if( pExpr==0 ) return;
30554 db->errByteOffset = pExpr->w.iOfst;
30555 }
@@ -31196,10 +31230,13 @@
31196 sqlite3_str_appendf(&x, " DDL");
31197 }
31198 if( pItem->fg.isCte ){
31199 sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
31200 }
 
 
 
31201 sqlite3StrAccumFinish(&x);
31202 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
31203 n = 0;
31204 if( pItem->pSelect ) n++;
31205 if( pItem->fg.isTabFunc ) n++;
@@ -31470,12 +31507,15 @@
31470 if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
31471 StrAccum x;
31472 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
31473 sqlite3_str_appendf(&x, " fg.af=%x.%c",
31474 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
31475 if( ExprHasProperty(pExpr, EP_FromJoin) ){
31476 sqlite3_str_appendf(&x, " iJoin=%d", pExpr->w.iJoin);
 
 
 
31477 }
31478 if( ExprHasProperty(pExpr, EP_FromDDL) ){
31479 sqlite3_str_appendf(&x, " DDL");
31480 }
31481 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -35398,17 +35438,18 @@
35398 /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
35399 /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
35400 /* 176 */ "VRename" OpHelp(""),
35401 /* 177 */ "Pagecount" OpHelp(""),
35402 /* 178 */ "MaxPgcnt" OpHelp(""),
35403 /* 179 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
35404 /* 180 */ "Trace" OpHelp(""),
35405 /* 181 */ "CursorHint" OpHelp(""),
35406 /* 182 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
35407 /* 183 */ "Noop" OpHelp(""),
35408 /* 184 */ "Explain" OpHelp(""),
35409 /* 185 */ "Abortable" OpHelp(""),
 
35410 };
35411 return azName[i];
35412 }
35413 #endif
35414
@@ -41837,90 +41878,103 @@
41837 }
41838 return SQLITE_OK;
41839 }
41840
41841 /*
41842 ** If the last component of the pathname in z[0]..z[j-1] is something
41843 ** other than ".." then back it out and return true. If the last
41844 ** component is empty or if it is ".." then return false.
41845 */
41846 static int unixBackupDir(const char *z, int *pJ){
41847 int j = *pJ;
41848 int i;
41849 if( j<=0 ) return 0;
41850 for(i=j-1; i>0 && z[i-1]!='/'; i--){}
41851 if( i==0 ) return 0;
41852 if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0;
41853 *pJ = i-1;
41854 return 1;
41855 }
41856
41857 /*
41858 ** Convert a relative pathname into a full pathname. Also
41859 ** simplify the pathname as follows:
41860 **
41861 ** Remove all instances of /./
41862 ** Remove all isntances of /X/../ for any X
41863 */
41864 static int mkFullPathname(
41865 const char *zPath, /* Input path */
41866 char *zOut, /* Output buffer */
41867 int nOut /* Allocated size of buffer zOut */
41868 ){
41869 int nPath = sqlite3Strlen30(zPath);
41870 int iOff = 0;
41871 int i, j;
41872 if( zPath[0]!='/' ){
41873 if( osGetcwd(zOut, nOut-2)==0 ){
41874 return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
41875 }
41876 iOff = sqlite3Strlen30(zOut);
41877 zOut[iOff++] = '/';
41878 }
41879 if( (iOff+nPath+1)>nOut ){
41880 /* SQLite assumes that xFullPathname() nul-terminates the output buffer
41881 ** even if it returns an error. */
41882 zOut[iOff] = '\0';
41883 return SQLITE_CANTOPEN_BKPT;
41884 }
41885 sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
41886
41887 /* Remove duplicate '/' characters. Except, two // at the beginning
41888 ** of a pathname is allowed since this is important on windows. */
41889 for(i=j=1; zOut[i]; i++){
41890 zOut[j++] = zOut[i];
41891 while( zOut[i]=='/' && zOut[i+1]=='/' ) i++;
41892 }
41893 zOut[j] = 0;
41894
41895 assert( zOut[0]=='/' );
41896 for(i=j=0; zOut[i]; i++){
41897 if( zOut[i]=='/' ){
41898 /* Skip over internal "/." directory components */
41899 if( zOut[i+1]=='.' && zOut[i+2]=='/' ){
41900 i += 1;
41901 continue;
41902 }
41903
41904 /* If this is a "/.." directory component then back out the
41905 ** previous term of the directory if it is something other than "..".
41906 */
41907 if( zOut[i+1]=='.'
41908 && zOut[i+2]=='.'
41909 && zOut[i+3]=='/'
41910 && unixBackupDir(zOut, &j)
41911 ){
41912 i += 2;
41913 continue;
41914 }
41915 }
41916 if( ALWAYS(j>=0) ) zOut[j] = zOut[i];
41917 j++;
41918 }
41919 if( NEVER(j==0) ) zOut[j++] = '/';
41920 zOut[j] = 0;
41921 return SQLITE_OK;
 
 
 
 
 
 
 
 
 
 
 
 
 
41922 }
41923
41924 /*
41925 ** Turn a relative pathname into a full pathname. The relative path
41926 ** is stored as a nul-terminated string in the buffer pointed to by
@@ -41934,89 +41988,30 @@
41934 sqlite3_vfs *pVfs, /* Pointer to vfs object */
41935 const char *zPath, /* Possibly relative input path */
41936 int nOut, /* Size of output buffer in bytes */
41937 char *zOut /* Output buffer */
41938 ){
41939 #if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
41940 return mkFullPathname(zPath, zOut, nOut);
41941 #else
41942 int rc = SQLITE_OK;
41943 int nByte;
41944 int nLink = 0; /* Number of symbolic links followed so far */
41945 const char *zIn = zPath; /* Input path for each iteration of loop */
41946 char *zDel = 0;
41947
41948 assert( pVfs->mxPathname==MAX_PATHNAME );
41949 UNUSED_PARAMETER(pVfs);
41950
41951 /* It's odd to simulate an io-error here, but really this is just
41952 ** using the io-error infrastructure to test that SQLite handles this
41953 ** function failing. This function could fail if, for example, the
41954 ** current working directory has been unlinked.
41955 */
41956 SimulateIOError( return SQLITE_ERROR );
41957
41958 do {
41959
41960 /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
41961 ** link, or false otherwise. */
41962 int bLink = 0;
41963 struct stat buf;
41964 if( osLstat(zIn, &buf)!=0 ){
41965 if( errno!=ENOENT ){
41966 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
41967 }
41968 }else{
41969 bLink = S_ISLNK(buf.st_mode);
41970 }
41971
41972 if( bLink ){
41973 nLink++;
41974 if( zDel==0 ){
41975 zDel = sqlite3_malloc(nOut);
41976 if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
41977 }else if( nLink>=SQLITE_MAX_SYMLINKS ){
41978 rc = SQLITE_CANTOPEN_BKPT;
41979 }
41980
41981 if( rc==SQLITE_OK ){
41982 nByte = osReadlink(zIn, zDel, nOut-1);
41983 if( nByte<0 ){
41984 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
41985 }else{
41986 if( zDel[0]!='/' ){
41987 int n;
41988 for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
41989 if( nByte+n+1>nOut ){
41990 rc = SQLITE_CANTOPEN_BKPT;
41991 }else{
41992 memmove(&zDel[n], zDel, nByte+1);
41993 memcpy(zDel, zIn, n);
41994 nByte += n;
41995 }
41996 }
41997 zDel[nByte] = '\0';
41998 }
41999 }
42000
42001 zIn = zDel;
42002 }
42003
42004 assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
42005 if( rc==SQLITE_OK && zIn!=zOut ){
42006 rc = mkFullPathname(zIn, zOut, nOut);
42007 }
42008 if( bLink==0 ) break;
42009 zIn = zOut;
42010 }while( rc==SQLITE_OK );
42011
42012 sqlite3_free(zDel);
42013 if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
42014 return rc;
42015 #endif /* HAVE_READLINK && HAVE_LSTAT */
42016 }
42017
42018
42019 #ifndef SQLITE_OMIT_LOAD_EXTENSION
42020 /*
42021 ** Interfaces for opening a shared library, finding entry points
42022 ** within the shared library, and closing the shared library.
@@ -56473,10 +56468,11 @@
56473 }else if( (currentSize+szPage)<=newSize ){
56474 char *pTmp = pPager->pTmpSpace;
56475 memset(pTmp, 0, szPage);
56476 testcase( (newSize-szPage) == currentSize );
56477 testcase( (newSize-szPage) > currentSize );
 
56478 rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
56479 }
56480 if( rc==SQLITE_OK ){
56481 pPager->dbFileSize = nPage;
56482 }
@@ -70725,16 +70721,21 @@
70725 eMode = BTALLOC_LE;
70726 iNear = nFin;
70727 }
70728 do {
70729 MemPage *pFreePg;
 
70730 rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
70731 if( rc!=SQLITE_OK ){
70732 releasePage(pLastPg);
70733 return rc;
70734 }
70735 releasePage(pFreePg);
 
 
 
 
70736 }while( bCommit && iFreePg>nFin );
70737 assert( iFreePg<iLastPg );
70738
70739 rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, bCommit);
70740 releasePage(pLastPg);
@@ -75957,11 +75958,11 @@
75957 }
75958
75959 TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
75960 pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
75961 loc==0 ? "overwrite" : "new entry"));
75962 assert( pPage->isInit );
75963 newCell = pBt->pTmpSpace;
75964 assert( newCell!=0 );
75965 if( flags & BTREE_PREFORMAT ){
75966 rc = SQLITE_OK;
75967 szNew = pBt->nPreformatSize;
@@ -80239,12 +80240,12 @@
80239 assert( !ExprHasProperty(pExpr, EP_IntValue) );
80240 aff = sqlite3AffinityType(pExpr->u.zToken,0);
80241 rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
80242 testcase( rc!=SQLITE_OK );
80243 if( *ppVal ){
80244 sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
80245 sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
80246 }
80247 return rc;
80248 }
80249
80250 /* Handle negative integers in a single step. This is needed in the
@@ -82215,15 +82216,13 @@
82215 if( c=='4' ){
82216 sqlite3_str_appendall(&x, zP4);
82217 }else if( c=='X' ){
82218 if( pOp->zComment && pOp->zComment[0] ){
82219 sqlite3_str_appendall(&x, pOp->zComment);
82220 }else{
82221 sqlite3_str_appendall(&x, zSynopsis+1);
82222 }
82223 seenCom = 1;
82224 break;
82225 }else{
82226 int v1 = translateP(c, pOp);
82227 int v2;
82228 if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
82229 ii += 3;
@@ -89770,14 +89769,19 @@
89770 pOut++;
89771 }while( --n );
89772 break;
89773 }
89774
89775 /* Opcode: Copy P1 P2 P3 * *
89776 ** Synopsis: r[P2@P3+1]=r[P1@P3+1]
89777 **
89778 ** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
 
 
 
 
 
89779 **
89780 ** This instruction makes a deep copy of the value. A duplicate
89781 ** is made of any string or blob constant. See also OP_SCopy.
89782 */
89783 case OP_Copy: {
@@ -89789,10 +89793,13 @@
89789 assert( pOut!=pIn1 );
89790 while( 1 ){
89791 memAboutToChange(p, pOut);
89792 sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
89793 Deephemeralize(pOut);
 
 
 
89794 #ifdef SQLITE_DEBUG
89795 pOut->pScopyFrom = 0;
89796 #endif
89797 REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
89798 if( (n--)==0 ) break;
@@ -92171,10 +92178,15 @@
92171 if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
92172 sqlite3ResetOneSchema(db, pOp->p1);
92173 }
92174 p->expired = 1;
92175 rc = SQLITE_SCHEMA;
 
 
 
 
 
92176 }
92177 if( rc ) goto abort_due_to_error;
92178 break;
92179 }
92180
@@ -92470,12 +92482,12 @@
92470 pCx->pKeyInfo = pOrig->pKeyInfo;
92471 pCx->isTable = pOrig->isTable;
92472 pCx->pgnoRoot = pOrig->pgnoRoot;
92473 pCx->isOrdered = pOrig->isOrdered;
92474 pCx->ub.pBtx = pOrig->ub.pBtx;
92475 pCx->hasBeenDuped = 1;
92476 pOrig->hasBeenDuped = 1;
92477 rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR,
92478 pCx->pKeyInfo, pCx->uc.pCursor);
92479 /* The sqlite3BtreeCursor() routine can only fail for the first cursor
92480 ** opened for a database. Since there is already an open cursor when this
92481 ** opcode is run, the sqlite3BtreeCursor() cannot fail */
@@ -92538,11 +92550,11 @@
92538 assert( aMem[pOp->p3].flags & MEM_Null );
92539 aMem[pOp->p3].n = 0;
92540 aMem[pOp->p3].z = "";
92541 }
92542 pCx = p->apCsr[pOp->p1];
92543 if( pCx && !pCx->hasBeenDuped && ALWAYS(pOp->p2<=pCx->nField) ){
92544 /* If the ephermeral table is already open and has no duplicates from
92545 ** OP_OpenDup, then erase all existing content so that the table is
92546 ** empty again, rather than creating a new table. */
92547 assert( pCx->isEphemeral );
92548 pCx->seqCount = 0;
@@ -94125,10 +94137,11 @@
94125 ** pseudo-cursor that always gives null rows. */
94126 pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO);
94127 if( pC==0 ) goto no_mem;
94128 pC->seekResult = 0;
94129 pC->isTable = 1;
 
94130 pC->uc.pCursor = sqlite3BtreeFakeValidCursor();
94131 }
94132 pC->nullRow = 1;
94133 pC->cacheStatus = CACHE_STALE;
94134 if( pC->eCurType==CURTYPE_BTREE ){
@@ -96257,18 +96270,18 @@
96257 Mem *pDest;
96258 sqlite3_context sContext;
96259
96260 VdbeCursor *pCur = p->apCsr[pOp->p1];
96261 assert( pCur!=0 );
96262 assert( pCur->eCurType==CURTYPE_VTAB );
96263 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
96264 pDest = &aMem[pOp->p3];
96265 memAboutToChange(p, pDest);
96266 if( pCur->nullRow ){
96267 sqlite3VdbeMemSetNull(pDest);
96268 break;
96269 }
 
96270 pVtab = pCur->uc.pVCur->pVtab;
96271 pModule = pVtab->pModule;
96272 assert( pModule->xColumn );
96273 memset(&sContext, 0, sizeof(sContext));
96274 sContext.pOut = pDest;
@@ -96591,10 +96604,21 @@
96591
96592 REGISTER_TRACE(pOp->p3, pOut);
96593 UPDATE_MAX_BLOBSIZE(pOut);
96594 break;
96595 }
 
 
 
 
 
 
 
 
 
 
 
96596
96597 /* Opcode: FilterAdd P1 * P3 P4 *
96598 ** Synopsis: filter(P1) += key(P3@P4)
96599 **
96600 ** Compute a hash on the P4 registers starting with r[P3] and
@@ -102345,11 +102369,11 @@
102345 for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
102346 anRef[i] = p->nRef;
102347 }
102348 sqlite3WalkExpr(pWalker, pExpr->pLeft);
102349 if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
102350 testcase( ExprHasProperty(pExpr, EP_FromJoin) );
102351 assert( !ExprHasProperty(pExpr, EP_IntValue) );
102352 if( pExpr->op==TK_NOTNULL ){
102353 pExpr->u.zToken = "true";
102354 ExprSetProperty(pExpr, EP_IsTrue);
102355 }else{
@@ -104636,10 +104660,11 @@
104636 pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
104637 if( pNew==0 ){
104638 sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
104639 return 0;
104640 }
 
104641 pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
104642 if( pList
104643 && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
104644 && !pParse->nested
104645 ){
@@ -104914,11 +104939,11 @@
104914 #endif
104915 ){
104916 nSize = EXPR_FULLSIZE;
104917 }else{
104918 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
104919 assert( !ExprHasProperty(p, EP_FromJoin) );
104920 assert( !ExprHasProperty(p, EP_MemToken) );
104921 assert( !ExprHasVVAProperty(p, EP_NoReduce) );
104922 if( p->pLeft || p->x.pList ){
104923 nSize = EXPR_REDUCEDSIZE | EP_Reduced;
104924 }else{
@@ -105740,11 +105765,11 @@
105740 static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
105741
105742 /* If pWalker->eCode is 2 then any term of the expression that comes from
105743 ** the ON or USING clauses of an outer join disqualifies the expression
105744 ** from being considered constant. */
105745 if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
105746 pWalker->eCode = 0;
105747 return WRC_Abort;
105748 }
105749
105750 switch( pExpr->op ){
@@ -105887,14 +105912,14 @@
105887 SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){
105888 if( pSrc->fg.jointype & JT_LTORJ ){
105889 return 0; /* rule (3) */
105890 }
105891 if( pSrc->fg.jointype & JT_LEFT ){
105892 if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */
105893 if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */
105894 }else{
105895 if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */
105896 }
105897 return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
105898 }
105899
105900
@@ -106312,15 +106337,11 @@
106312 int mustBeUnique; /* True if RHS must be unique */
106313 Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
106314
106315 assert( pX->op==TK_IN );
106316 mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
106317 if( pX->iTable && (inFlags & IN_INDEX_REUSE_CUR)!=0 ){
106318 iTab = pX->iTable;
106319 }else{
106320 iTab = pParse->nTab++;
106321 }
106322
106323 /* If the RHS of this IN(...) operator is a SELECT, and if it matters
106324 ** whether or not the SELECT result contains NULL values, check whether
106325 ** or not NULL is actually possible (it may not be, for example, due
106326 ** to NOT NULL constraints in the schema). If no NULL values are possible,
@@ -106650,13 +106671,12 @@
106650 pExpr->x.pSelect->selId));
106651 }
106652 assert( ExprUseYSub(pExpr) );
106653 sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
106654 pExpr->y.sub.iAddr);
106655 if( iTab!=pExpr->iTable ){
106656 sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
106657 }
106658 sqlite3VdbeJumpHere(v, addrOnce);
106659 return;
106660 }
106661
106662 /* Begin coding the subroutine */
@@ -107526,11 +107546,21 @@
107526 memset(&caseExpr, 0, sizeof(caseExpr));
107527 caseExpr.op = TK_CASE;
107528 caseExpr.x.pList = pFarg;
107529 return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
107530 }
107531
 
 
 
 
 
 
 
 
 
 
107532 default: {
107533 /* The UNLIKELY() function is a no-op. The result is the value
107534 ** of the first argument.
107535 */
107536 assert( nFarg==1 || nFarg==2 );
@@ -108065,24 +108095,12 @@
108065 #endif
108066 if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
108067 if( !pColl ) pColl = db->pDfltColl;
108068 sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
108069 }
108070 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
108071 if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){
108072 Expr *pArg = pFarg->a[0].pExpr;
108073 if( pArg->op==TK_COLUMN ){
108074 sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
108075 }else{
108076 sqlite3VdbeAddOp2(v, OP_Null, 0, target);
108077 }
108078 }else
108079 #endif
108080 {
108081 sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
108082 pDef, pExpr->op2);
108083 }
108084 if( nFarg ){
108085 if( constMask==0 ){
108086 sqlite3ReleaseTempRange(pParse, r1, nFarg);
108087 }else{
108088 sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
@@ -108149,13 +108167,29 @@
108149 ** Z is stored in pExpr->pList->a[1].pExpr.
108150 */
108151 case TK_BETWEEN: {
108152 exprCodeBetween(pParse, pExpr, target, 0, 0);
108153 return target;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108154 }
108155 case TK_SPAN:
108156 case TK_COLLATE:
108157 case TK_UPLUS: {
108158 pExpr = pExpr->pLeft;
108159 goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */
108160 }
108161
@@ -108645,12 +108679,12 @@
108645 }else{
108646 /* Mark the expression is being from the ON or USING clause of a join
108647 ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
108648 ** it into the Parse.pConstExpr list. We should use a new bit for this,
108649 ** for clarity, but we are out of bits in the Expr.flags field so we
108650 ** have to reuse the EP_FromJoin bit. Bummer. */
108651 pDel->flags |= EP_FromJoin;
108652 sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
108653 }
108654 sqlite3ReleaseTempReg(pParse, regFree1);
108655 }
108656 sqlite3ExprDelete(db, pDel);
@@ -109331,11 +109365,11 @@
109331 ** (never setting pWalker->eCode) is a harmless missed optimization.
109332 */
109333 static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
109334 testcase( pExpr->op==TK_AGG_COLUMN );
109335 testcase( pExpr->op==TK_AGG_FUNCTION );
109336 if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
109337 switch( pExpr->op ){
109338 case TK_ISNOT:
109339 case TK_ISNULL:
109340 case TK_NOTNULL:
109341 case TK_IS:
@@ -109428,11 +109462,11 @@
109428 ** is NULL. A false negative is merely a missed optimization opportunity.
109429 **
109430 ** False positives are not allowed, however. A false positive may result
109431 ** in an incorrect answer.
109432 **
109433 ** Terms of p that are marked with EP_FromJoin (and hence that come from
109434 ** the ON or USING clauses of OUTER JOINS) are excluded from the analysis.
109435 **
109436 ** This routine is used to check if a LEFT JOIN can be converted into
109437 ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
109438 ** clause requires that some column of the right table of the LEFT JOIN
@@ -111302,31 +111336,37 @@
111302 if( pParse->nErr ) rc = pParse->rc;
111303 }
111304 if( rc==SQLITE_OK && pStep->zTarget ){
111305 SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep);
111306 if( pSrc ){
111307 int i;
111308 for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){
111309 SrcItem *p = &pSrc->a[i];
111310 p->iCursor = pParse->nTab++;
111311 if( p->pSelect ){
111312 sqlite3SelectPrep(pParse, p->pSelect, 0);
111313 sqlite3ExpandSubquery(pParse, p);
111314 assert( i>0 );
111315 assert( pStep->pFrom->a[i-1].pSelect );
111316 sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0);
111317 }else{
111318 p->pTab = sqlite3LocateTableItem(pParse, 0, p);
111319 if( p->pTab==0 ){
111320 rc = SQLITE_ERROR;
111321 }else{
111322 p->pTab->nTabRef++;
111323 rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
 
 
 
 
 
111324 }
111325 }
111326 }
111327 if( rc==SQLITE_OK && db->mallocFailed ){
 
111328 rc = SQLITE_NOMEM;
111329 }
111330 sNC.pSrcList = pSrc;
111331 if( rc==SQLITE_OK && pStep->pWhere ){
111332 rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
@@ -111773,10 +111813,19 @@
111773 if( rc==SQLITE_OK ){
111774 renameWalkTrigger(&sWalker, pTrigger);
111775 for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
111776 if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
111777 renameTokenFind(&sParse, &sCtx, pStep->zTarget);
 
 
 
 
 
 
 
 
 
111778 }
111779 }
111780 }
111781 }
111782 }
@@ -124372,15 +124421,15 @@
124372 }else{
124373 ans = log(x);
124374 switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){
124375 case 1:
124376 /* Convert from natural logarithm to log base 10 */
124377 ans *= 1.0/M_LN10;
124378 break;
124379 case 2:
124380 /* Convert from natural logarithm to log base 2 */
124381 ans *= 1.0/M_LN2;
124382 break;
124383 default:
124384 break;
124385 }
124386 }
@@ -124515,12 +124564,11 @@
124515 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
124516 INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124517 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124518 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124519 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
124520 {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
124521 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
124522 #endif
124523 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
124524 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
124525 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
124526 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -129800,10 +129848,11 @@
129800 /* Version 3.39.0 and later */
129801 int (*deserialize)(sqlite3*,const char*,unsigned char*,
129802 sqlite3_int64,sqlite3_int64,unsigned);
129803 unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
129804 unsigned int);
 
129805 };
129806
129807 /*
129808 ** This is the function signature used for all extension entry points. It
129809 ** is also defined in the file "loadext.c".
@@ -130118,14 +130167,16 @@
130118 #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
130119 #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
130120 #define sqlite3_vtab_in sqlite3_api->vtab_in
130121 #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
130122 #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
 
130123 #ifndef SQLITE_OMIT_DESERIALIZE
130124 #define sqlite3_deserialize sqlite3_api->deserialize
130125 #define sqlite3_serialize sqlite3_api->serialize
130126 #endif
 
130127 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
130128
130129 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
130130 /* This case when the file really is being compiled as a loadable
130131 ** extension */
@@ -130629,15 +130680,16 @@
130629 0,
130630 #endif
130631 /* Version 3.39.0 and later */
130632 #ifndef SQLITE_OMIT_DESERIALIZE
130633 sqlite3_deserialize,
130634 sqlite3_serialize
130635 #else
 
130636 0,
130637 0
130638 #endif
 
130639 };
130640
130641 /* True if x is the directory separator character
130642 */
130643 #if SQLITE_OS_WIN
@@ -135849,15 +135901,15 @@
135849 }
135850 return 0;
135851 }
135852
135853 /*
135854 ** Set the EP_FromJoin property on all terms of the given expression.
135855 ** And set the Expr.w.iJoin to iTable for every term in the
135856 ** expression.
135857 **
135858 ** The EP_FromJoin property is used on terms of an expression to tell
135859 ** the OUTER JOIN processing logic that this term is part of the
135860 ** join restriction specified in the ON or USING clause and not a part
135861 ** of the more general WHERE clause. These terms are moved over to the
135862 ** WHERE clause during join processing but we need to remember that they
135863 ** originated in the ON or USING clause.
@@ -135875,11 +135927,11 @@
135875 ** defer the handling of t1.x=5, it will be processed immediately
135876 ** after the t1 loop and rows with t1.x!=5 will never appear in
135877 ** the output, which is incorrect.
135878 */
135879 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){
135880 assert( joinFlag==EP_FromJoin || joinFlag==EP_InnerJoin );
135881 while( p ){
135882 ExprSetProperty(p, joinFlag);
135883 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
135884 ExprSetVVAProperty(p, EP_NoReduce);
135885 p->w.iJoin = iTable;
@@ -135896,35 +135948,41 @@
135896 p = p->pRight;
135897 }
135898 }
135899
135900 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
135901 ** term that is marked with EP_FromJoin and w.iJoin==iTable into
135902 ** an ordinary term that omits the EP_FromJoin mark.
135903 **
135904 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
 
 
 
 
 
 
135905 */
135906 static void unsetJoinExpr(Expr *p, int iTable){
135907 while( p ){
135908 if( ExprHasProperty(p, EP_FromJoin)
135909 && (iTable<0 || p->w.iJoin==iTable) ){
135910 ExprClearProperty(p, EP_FromJoin);
135911 ExprSetProperty(p, EP_InnerJoin);
135912 }
135913 if( p->op==TK_COLUMN && p->iTable==iTable ){
135914 ExprClearProperty(p, EP_CanBeNull);
135915 }
135916 if( p->op==TK_FUNCTION ){
135917 assert( ExprUseXList(p) );
135918 if( p->x.pList ){
135919 int i;
135920 for(i=0; i<p->x.pList->nExpr; i++){
135921 unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
135922 }
135923 }
135924 }
135925 unsetJoinExpr(p->pLeft, iTable);
135926 p = p->pRight;
135927 }
135928 }
135929
135930 /*
@@ -135934,12 +135992,12 @@
135934 ** do not need to be concerned with NATURAL joins and we only have
135935 ** think about USING joins.
135936 **
135937 ** * ON and USING clauses result in extra terms being added to the
135938 ** WHERE clause to enforce the specified constraints. The extra
135939 ** WHERE clause terms will be tagged with EP_FromJoin or
135940 ** EP_InnerJoin so that we know that they originated in ON/USING.
135941 **
135942 ** The terms of a FROM clause are contained in the Select.pSrc structure.
135943 ** The left most table is the first entry in Select.pSrc. The right-most
135944 ** table is the last entry. The join operator is held in the entry to
135945 ** the right. Thus entry 1 contains the join operator for the join between
@@ -135960,11 +136018,11 @@
135960 for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
135961 Table *pRightTab = pRight->pTab;
135962 u32 joinType;
135963
135964 if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
135965 joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_FromJoin : EP_InnerJoin;
135966
135967 /* If this is a NATURAL join, synthesize an approprate USING clause
135968 ** to specify which columns should be joined.
135969 */
135970 if( pRight->fg.jointype & JT_NATURAL ){
@@ -136081,10 +136139,11 @@
136081 */
136082 else if( pRight->u3.pOn ){
136083 sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
136084 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
136085 pRight->u3.pOn = 0;
 
136086 }
136087 }
136088 return 0;
136089 }
136090
@@ -137664,14 +137723,15 @@
137664 pColExpr = pColExpr->pRight;
137665 assert( pColExpr!=0 );
137666 }
137667 if( pColExpr->op==TK_COLUMN
137668 && ALWAYS( ExprUseYTab(pColExpr) )
137669 && (pTab = pColExpr->y.pTab)!=0
137670 ){
137671 /* For columns use the column name name */
137672 int iCol = pColExpr->iColumn;
 
137673 if( iCol<0 ) iCol = pTab->iPKey;
137674 zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
137675 }else if( pColExpr->op==TK_ID ){
137676 assert( !ExprHasProperty(pColExpr, EP_IntValue) );
137677 zName = pColExpr->u.zToken;
@@ -139233,13 +139293,14 @@
139233 static Expr *substExpr(
139234 SubstContext *pSubst, /* Description of the substitution */
139235 Expr *pExpr /* Expr in which substitution occurs */
139236 ){
139237 if( pExpr==0 ) return 0;
139238 if( ExprHasProperty(pExpr, EP_FromJoin)
139239 && pExpr->w.iJoin==pSubst->iTable
139240 ){
 
139241 pExpr->w.iJoin = pSubst->iNewTable;
139242 }
139243 if( pExpr->op==TK_COLUMN
139244 && pExpr->iTable==pSubst->iTable
139245 && !ExprHasProperty(pExpr, EP_FixedCol)
@@ -139274,16 +139335,21 @@
139274 return pExpr;
139275 }
139276 if( pSubst->isOuterJoin ){
139277 ExprSetProperty(pNew, EP_CanBeNull);
139278 }
139279 if( ExprHasProperty(pExpr,EP_FromJoin|EP_InnerJoin) ){
139280 sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
139281 pExpr->flags & (EP_FromJoin|EP_InnerJoin));
139282 }
139283 sqlite3ExprDelete(db, pExpr);
139284 pExpr = pNew;
 
 
 
 
 
139285
139286 /* Ensure that the expression now has an implicit collation sequence,
139287 ** just as it did when it was a column of a view or sub-query. */
139288 if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){
139289 CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
@@ -139440,11 +139506,11 @@
139440 static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){
139441 int op = pExpr->op;
139442 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
139443 renumberCursorDoMapping(pWalker, &pExpr->iTable);
139444 }
139445 if( ExprHasProperty(pExpr, EP_FromJoin) ){
139446 renumberCursorDoMapping(pWalker, &pExpr->w.iJoin);
139447 }
139448 return WRC_Continue;
139449 }
139450
@@ -139633,10 +139699,15 @@
139633 ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
139634 ** is the first element of the parent query.
139635 **
139636 ** (28) The subquery is not a MATERIALIZED CTE.
139637 **
 
 
 
 
 
139638 **
139639 ** In this routine, the "p" parameter is a pointer to the outer query.
139640 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
139641 ** uses aggregates.
139642 **
@@ -139759,10 +139830,39 @@
139759 return 0; /* Restriction (27) */
139760 }
139761 if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
139762 return 0; /* (28) */
139763 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139764
139765 /* Restriction (17): If the sub-query is a compound SELECT, then it must
139766 ** use only the UNION ALL operator. And none of the simple select queries
139767 ** that make up the compound SELECT are allowed to be aggregate or distinct
139768 ** queries.
@@ -140018,11 +140118,11 @@
140018 pSub->pOrderBy = 0;
140019 }
140020 pWhere = pSub->pWhere;
140021 pSub->pWhere = 0;
140022 if( isOuterJoin>0 ){
140023 sqlite3SetJoinExpr(pWhere, iNewParent, EP_FromJoin);
140024 }
140025 if( pWhere ){
140026 if( pParent->pWhere ){
140027 pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
140028 }else{
@@ -140151,11 +140251,15 @@
140151 ** found, add it to the pConst structure.
140152 */
140153 static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
140154 Expr *pRight, *pLeft;
140155 if( NEVER(pExpr==0) ) return;
140156 if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
 
 
 
 
140157 if( pExpr->op==TK_AND ){
140158 findConstInWhere(pConst, pExpr->pRight);
140159 findConstInWhere(pConst, pExpr->pLeft);
140160 return;
140161 }
@@ -140187,13 +140291,13 @@
140187 int bIgnoreAffBlob
140188 ){
140189 int i;
140190 if( pConst->pOomFault[0] ) return WRC_Prune;
140191 if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
140192 if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
140193 testcase( ExprHasProperty(pExpr, EP_FixedCol) );
140194 testcase( ExprHasProperty(pExpr, EP_FromJoin) );
140195 return WRC_Continue;
140196 }
140197 for(i=0; i<pConst->nConst; i++){
140198 Expr *pColumn = pConst->apExpr[i*2];
140199 if( pColumn==pExpr ) continue;
@@ -140474,16 +140578,16 @@
140474 pWhere = pWhere->pLeft;
140475 }
140476
140477 #if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */
140478 if( isLeftJoin
140479 && (ExprHasProperty(pWhere,EP_FromJoin)==0
140480 || pWhere->w.iJoin!=iCursor)
140481 ){
140482 return 0; /* restriction (4) */
140483 }
140484 if( ExprHasProperty(pWhere,EP_FromJoin)
140485 && pWhere->w.iJoin!=iCursor
140486 ){
140487 return 0; /* restriction (5) */
140488 }
140489 #endif
@@ -140492,11 +140596,11 @@
140492 nChng++;
140493 pSubq->selFlags |= SF_PushDown;
140494 while( pSubq ){
140495 SubstContext x;
140496 pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
140497 unsetJoinExpr(pNew, -1);
140498 x.pParse = pParse;
140499 x.iTable = pSrc->iCursor;
140500 x.iNewTable = pSrc->iCursor;
140501 x.isOuterJoin = 0;
140502 x.pEList = pSubq->pEList;
@@ -141988,10 +142092,33 @@
141988 }
141989 #endif
141990 return 1;
141991 }
141992 #endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141993
141994 /*
141995 ** Generate code for the SELECT statement given in the p argument.
141996 **
141997 ** The results are returned according to the SelectDest structure.
@@ -142093,19 +142220,16 @@
142093 ** systems handle this case differently, and not all the same way,
142094 ** which is just confusing. To avoid this, we follow PG's lead and
142095 ** disallow it altogether. */
142096 if( p->selFlags & SF_UFSrcCheck ){
142097 SrcItem *p0 = &p->pSrc->a[0];
142098 for(i=1; i<p->pSrc->nSrc; i++){
142099 SrcItem *p1 = &p->pSrc->a[i];
142100 if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
142101 sqlite3ErrorMsg(pParse,
142102 "target object/alias may not appear in FROM clause: %s",
142103 p0->zAlias ? p0->zAlias : p0->pTab->zName
142104 );
142105 goto select_end;
142106 }
142107 }
142108
142109 /* Clear the SF_UFSrcCheck flag. The check has already been performed,
142110 ** and leaving this flag set can cause errors if a compound sub-query
142111 ** in p->pSrc is flattened into this query and this function called
@@ -142156,11 +142280,12 @@
142156 && OptimizationEnabled(db, SQLITE_SimplifyJoin)
142157 ){
142158 SELECTTRACE(0x100,pParse,p,
142159 ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
142160 pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
142161 unsetJoinExpr(p->pWhere, pItem->iCursor);
 
142162 }
142163
142164 /* No futher action if this term of the FROM clause is no a subquery */
142165 if( pSub==0 ) continue;
142166
@@ -142376,11 +142501,11 @@
142376 zSavedAuthContext = pParse->zAuthContext;
142377 pParse->zAuthContext = pItem->zName;
142378
142379 /* Generate code to implement the subquery
142380 **
142381 ** The subquery is implemented as a co-routine all of the following are
142382 ** true:
142383 **
142384 ** (1) the subquery is guaranteed to be the outer loop (so that
142385 ** it does not need to be computed more than once), and
142386 ** (2) the subquery is not a CTE that should be materialized
@@ -142434,15 +142559,15 @@
142434 /* Materialize the view. If the view is not correlated, generate a
142435 ** subroutine to do the materialization so that subsequent uses of
142436 ** the same view can reuse the materialization. */
142437 int topAddr;
142438 int onceAddr = 0;
142439 int retAddr;
142440
142441 pItem->regReturn = ++pParse->nMem;
142442 topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
142443 pItem->addrFillSub = topAddr+1;
 
142444 if( pItem->fg.isCorrelated==0 ){
142445 /* If the subquery is not correlated and if we are not inside of
142446 ** a trigger, then we only need to compute the value of the subquery
142447 ** once. */
142448 onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
@@ -142453,13 +142578,13 @@
142453 sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
142454 ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem));
142455 sqlite3Select(pParse, pSub, &dest);
142456 pItem->pTab->nRowLogEst = pSub->nSelectRow;
142457 if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
142458 retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
142459 VdbeComment((v, "end %!S", pItem));
142460 sqlite3VdbeChangeP1(v, topAddr, retAddr);
142461 sqlite3ClearTempRegCache(pParse);
142462 if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
142463 CteUse *pCteUse = pItem->u2.pCteUse;
142464 pCteUse->addrM9e = pItem->addrFillSub;
142465 pCteUse->regRtn = pItem->regReturn;
@@ -143178,11 +143303,11 @@
143178 }
143179 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
143180 eDist = sqlite3WhereIsDistinct(pWInfo);
143181 updateAccumulator(pParse, regAcc, pAggInfo, eDist);
143182 if( eDist!=WHERE_DISTINCT_NOOP ){
143183 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
143184 if( pF ){
143185 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
143186 }
143187 }
143188
@@ -143977,11 +144102,11 @@
143977 ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
143978 */
143979 SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
143980 Parse *pParse, /* Parser */
143981 Token *pTableName, /* Name of the table to be updated */
143982 SrcList *pFrom,
143983 ExprList *pEList, /* The SET clause: list of column and new values */
143984 Expr *pWhere, /* The WHERE clause */
143985 u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
143986 const char *zStart, /* Start of SQL text */
143987 const char *zEnd /* End of SQL text */
@@ -144313,10 +144438,18 @@
144313 if( pSchema!=db->aDb[1].pSchema ){
144314 pSrc->a[0].pSchema = pSchema;
144315 }
144316 if( pStep->pFrom ){
144317 SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
 
 
 
 
 
 
 
 
144318 pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup);
144319 }
144320 }else{
144321 sqlite3DbFree(db, zName);
144322 }
@@ -145944,11 +146077,11 @@
145944 if( pPk ){
145945 sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
145946 }else{
145947 sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
145948 }
145949 VdbeCoverageNeverTaken(v);
145950 }
145951
145952 /* Do FK constraint checks. */
145953 if( hasFK ){
145954 sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
@@ -148402,11 +148535,11 @@
148402 ** This object is a header on a block of allocated memory that will be
148403 ** automatically freed when its WInfo oject is destructed.
148404 */
148405 struct WhereMemBlock {
148406 WhereMemBlock *pNext; /* Next block in the chain */
148407 u8 sz; /* Bytes of space */
148408 };
148409
148410 /*
148411 ** Extra information attached to a WhereLevel that is a RIGHT JOIN.
148412 */
@@ -148973,12 +149106,13 @@
148973 #define WO_ISNULL 0x0100
148974 #define WO_OR 0x0200 /* Two or more OR-connected terms */
148975 #define WO_AND 0x0400 /* Two or more AND-connected terms */
148976 #define WO_EQUIV 0x0800 /* Of the form A==B, both columns */
148977 #define WO_NOOP 0x1000 /* This term does not restrict search space */
 
148978
148979 #define WO_ALL 0x1fff /* Mask of all possible WO_* values */
148980 #define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */
148981
148982 /*
148983 ** These are definitions of bits in the WhereLoop.wsFlags field.
148984 ** The particular combination of bits in each WhereLoop help to
@@ -149344,11 +149478,11 @@
149344 */
149345 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
149346 int nLoop = 0;
149347 assert( pTerm!=0 );
149348 while( (pTerm->wtFlags & TERM_CODED)==0
149349 && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
149350 && (pLevel->notReady & pTerm->prereqAll)==0
149351 ){
149352 if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
149353 pTerm->wtFlags |= TERM_LIKECOND;
149354 }else{
@@ -149617,12 +149751,11 @@
149617 pExpr->iTable = iTab;
149618 }
149619 sqlite3ExprDelete(db, pX);
149620 }else{
149621 aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
149622 eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP|IN_INDEX_REUSE_CUR, 0, aiMap,&iTab);
149623 iTab = pExpr->iTable;
149624 }
149625 pX = pExpr;
149626 }
149627
149628 if( eType==IN_INDEX_INDEX_DESC ){
@@ -150066,20 +150199,20 @@
150066 **
150067 ** are also excluded. See codeCursorHintIsOrFunction() for details.
150068 */
150069 if( pTabItem->fg.jointype & JT_LEFT ){
150070 Expr *pExpr = pTerm->pExpr;
150071 if( !ExprHasProperty(pExpr, EP_FromJoin)
150072 || pExpr->w.iJoin!=pTabItem->iCursor
150073 ){
150074 sWalker.eCode = 0;
150075 sWalker.xExprCallback = codeCursorHintIsOrFunction;
150076 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
150077 if( sWalker.eCode ) continue;
150078 }
150079 }else{
150080 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
150081 }
150082
150083 /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
150084 ** the cursor. These terms are not needed as hints for a pure range
150085 ** scan (that has no == terms) so omit them. */
@@ -151406,11 +151539,11 @@
151406 WhereInfo *pSubWInfo; /* Info for single OR-term scan */
151407 Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
151408 Expr *pDelete; /* Local copy of OR clause term */
151409 int jmp1 = 0; /* Address of jump operation */
151410 testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
151411 && !ExprHasProperty(pOrExpr, EP_FromJoin)
151412 ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
151413 pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0);
151414 if( db->mallocFailed ){
151415 sqlite3ExprDelete(db, pDelete);
151416 continue;
@@ -151614,16 +151747,26 @@
151614 pWInfo->untestedTerms = 1;
151615 continue;
151616 }
151617 pE = pTerm->pExpr;
151618 assert( pE!=0 );
151619 if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ))
151620 && !ExprHasProperty(pE,EP_FromJoin|EP_InnerJoin)
151621 ){
151622 continue;
 
 
 
 
 
 
 
 
 
 
 
151623 }
151624
151625 if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
151626 iNext = 2;
151627 continue;
151628 }
151629 if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){
@@ -151678,19 +151821,19 @@
151678 WhereTerm *pAlt;
151679 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151680 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
151681 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
151682 if( pTerm->leftCursor!=iCur ) continue;
151683 if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue;
151684 pE = pTerm->pExpr;
151685 #ifdef WHERETRACE_ENABLED /* 0x800 */
151686 if( sqlite3WhereTrace & 0x800 ){
151687 sqlite3DebugPrintf("Coding transitive constraint:\n");
151688 sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
151689 }
151690 #endif
151691 assert( !ExprHasProperty(pE, EP_FromJoin) );
151692 assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
151693 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151694 pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
151695 WO_EQ|WO_IN|WO_IS, 0);
151696 if( pAlt==0 ) continue;
@@ -151757,22 +151900,12 @@
151757 */
151758 if( pLevel->iLeftJoin ){
151759 pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
151760 sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
151761 VdbeComment((v, "record LEFT JOIN hit"));
151762 for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
151763 testcase( pTerm->wtFlags & TERM_VIRTUAL );
151764 testcase( pTerm->wtFlags & TERM_CODED );
151765 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151766 if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
151767 assert( pWInfo->untestedTerms );
151768 continue;
151769 }
151770 if( pTabItem->fg.jointype & JT_LTORJ ) continue;
151771 assert( pTerm->pExpr );
151772 sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
151773 pTerm->wtFlags |= TERM_CODED;
151774 }
151775 }
151776
151777 if( pLevel->pRJ ){
151778 /* Create a subroutine used to process all interior loops and code
@@ -151784,10 +151917,30 @@
151784 WhereRightJoin *pRJ = pLevel->pRJ;
151785 sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn);
151786 pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v);
151787 assert( pParse->withinRJSubrtn < 255 );
151788 pParse->withinRJSubrtn++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151789 }
151790
151791 #if WHERETRACE_ENABLED /* 0x20800 */
151792 if( sqlite3WhereTrace & 0x20000 ){
151793 sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
@@ -151837,13 +151990,17 @@
151837 }
151838 if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){
151839 mAll |= pLoop->maskSelf;
151840 for(k=0; k<pWC->nTerm; k++){
151841 WhereTerm *pTerm = &pWC->a[k];
151842 if( pTerm->wtFlags & TERM_VIRTUAL ) break;
 
 
 
 
151843 if( pTerm->prereqAll & ~mAll ) continue;
151844 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue;
151845 pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
151846 sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
151847 }
151848 }
151849 sFrom.nSrc = 1;
@@ -152351,12 +152508,12 @@
152351 /*
152352 ** If the pBase expression originated in the ON or USING clause of
152353 ** a join, then transfer the appropriate markings over to derived.
152354 */
152355 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
152356 if( pDerived ){
152357 pDerived->flags |= pBase->flags & EP_FromJoin;
152358 pDerived->w.iJoin = pBase->w.iJoin;
152359 }
152360 }
152361
152362 /*
@@ -152807,11 +152964,11 @@
152807 static int termIsEquivalence(Parse *pParse, Expr *pExpr){
152808 char aff1, aff2;
152809 CollSeq *pColl;
152810 if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
152811 if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
152812 if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
152813 aff1 = sqlite3ExprAffinity(pExpr->pLeft);
152814 aff2 = sqlite3ExprAffinity(pExpr->pRight);
152815 if( aff1!=aff2
152816 && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
152817 ){
@@ -152995,22 +153152,30 @@
152995
152996 #ifdef SQLITE_DEBUG
152997 if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){
152998 printf("\n*** Incorrect prereqAll computed for:\n");
152999 sqlite3TreeViewExpr(0,pExpr,0);
153000 abort();
153001 }
153002 #endif
153003
153004 if( ExprHasProperty(pExpr, EP_FromJoin) ){
153005 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
153006 prereqAll |= x;
153007 extraRight = x-1; /* ON clause terms may not be used with an index
153008 ** on left table of a LEFT JOIN. Ticket #3015 */
153009 if( (prereqAll>>1)>=x ){
153010 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
153011 return;
 
 
 
 
 
 
 
 
153012 }
153013 }
153014 pTerm->prereqAll = prereqAll;
153015 pTerm->leftCursor = -1;
153016 pTerm->iParent = -1;
@@ -153074,11 +153239,11 @@
153074 pNew->prereqRight = prereqLeft | extraRight;
153075 pNew->prereqAll = prereqAll;
153076 pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
153077 }else
153078 if( op==TK_ISNULL
153079 && !ExprHasProperty(pExpr,EP_FromJoin)
153080 && 0==sqlite3ExprCanBeNull(pLeft)
153081 ){
153082 assert( !ExprHasProperty(pExpr, EP_IntValue) );
153083 pExpr->op = TK_TRUEFALSE;
153084 pExpr->u.zToken = "false";
@@ -153145,11 +153310,11 @@
153145 ** The virtual term must be tagged with TERM_VNULL.
153146 */
153147 else if( pExpr->op==TK_NOTNULL ){
153148 if( pExpr->pLeft->op==TK_COLUMN
153149 && pExpr->pLeft->iColumn>=0
153150 && !ExprHasProperty(pExpr, EP_FromJoin)
153151 ){
153152 Expr *pNewExpr;
153153 Expr *pLeft = pExpr->pLeft;
153154 int idxNew;
153155 WhereTerm *pNewTerm;
@@ -153293,11 +153458,11 @@
153293 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
153294 exprAnalyze(pSrc, pWC, idxNew);
153295 }
153296 pTerm = &pWC->a[idxTerm];
153297 pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
153298 pTerm->eOperator = 0;
153299 }
153300
153301 /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
153302 ** a virtual term for each vector component. The expression object
153303 ** used by each such virtual term is pExpr (the full vector IN(...)
@@ -153349,12 +153514,12 @@
153349 prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
153350 if( (prereqExpr & prereqColumn)==0 ){
153351 Expr *pNewExpr;
153352 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
153353 0, sqlite3ExprDup(db, pRight, 0));
153354 if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
153355 ExprSetProperty(pNewExpr, EP_FromJoin);
153356 pNewExpr->w.iJoin = pExpr->w.iJoin;
153357 }
153358 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
153359 testcase( idxNew==0 );
153360 pNewTerm = &pWC->a[idxNew];
@@ -153494,11 +153659,11 @@
153494 for(ii=0; ii<pWC->nTerm; ii++){
153495 if( pWC->a[ii].wtFlags & TERM_CODED ){
153496 /* This term is a vector operation that has been decomposed into
153497 ** other, subsequent terms. It can be ignored. See tag-20220128a */
153498 assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
153499 assert( pWC->a[ii].eOperator==0 );
153500 continue;
153501 }
153502 if( pWC->a[ii].leftCursor!=iCsr ) return;
153503 }
153504
@@ -153717,13 +153882,13 @@
153717 pItem->colUsed |= sqlite3ExprColUsed(pColRef);
153718 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
153719 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
153720 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
153721 if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){
153722 joinType = EP_FromJoin;
153723 }else{
153724 joinType = EP_InnerJoin;
153725 }
153726 sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType);
153727 whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
153728 }
153729 }
@@ -154060,11 +154225,11 @@
154060 if( pTerm->leftCursor==iCur
154061 && pTerm->u.x.leftColumn==iColumn
154062 && (iColumn!=XN_EXPR
154063 || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
154064 pScan->pIdxExpr,iCur)==0)
154065 && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
154066 ){
154067 if( (pTerm->eOperator & WO_EQUIV)!=0
154068 && pScan->nEquiv<ArraySize(pScan->aiCur)
154069 && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0
154070 ){
@@ -154412,10 +154577,11 @@
154412 if( pOp->opcode==OP_Column ){
154413 pOp->opcode = OP_Copy;
154414 pOp->p1 = pOp->p2 + iRegister;
154415 pOp->p2 = pOp->p3;
154416 pOp->p3 = 0;
 
154417 }else if( pOp->opcode==OP_Rowid ){
154418 pOp->opcode = OP_Sequence;
154419 pOp->p1 = iAutoidxCur;
154420 #ifdef SQLITE_ALLOW_ROWID_IN_VIEW
154421 if( iAutoidxCur==0 ){
@@ -154486,18 +154652,21 @@
154486 const Bitmask notReady /* Tables in outer loops of the join */
154487 ){
154488 char aff;
154489 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
154490 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
154491 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
154492 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
154493 && (pTerm->eOperator & WO_IS)
154494 ){
154495 /* Cannot use an IS term from the WHERE clause as an index driver for
154496 ** the RHS of a LEFT JOIN or for the LHS of a RIGHT JOIN. Such a term
154497 ** can only be used if it is from the ON clause. */
154498 return 0;
 
 
 
154499 }
154500 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
154501 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
154502 if( pTerm->u.x.leftColumn<0 ) return 0;
154503 aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
@@ -154907,17 +155076,24 @@
154907 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
154908 assert( pTerm->u.x.leftColumn>=XN_ROWID );
154909 assert( pTerm->u.x.leftColumn<pTab->nCol );
154910
154911 /* tag-20191211-002: WHERE-clause constraints are not useful to the
154912 ** right-hand table of a LEFT JOIN nor to the left-hand table of a
154913 ** RIGHT JOIN. See tag-20191211-001 for the
154914 ** equivalent restriction for ordinary tables. */
154915 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
154916 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
154917 ){
154918 continue;
 
 
 
 
 
 
 
154919 }
154920 nTerm++;
154921 pTerm->wtFlags |= TERM_OK;
154922 }
154923
@@ -155789,11 +155965,11 @@
155789 char zType[8];
155790 char zLeft[50];
155791 memcpy(zType, "....", 5);
155792 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
155793 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
155794 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
155795 if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
155796 if( pTerm->eOperator & WO_SINGLE ){
155797 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155798 sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
155799 pTerm->leftCursor, pTerm->u.x.leftColumn);
@@ -156563,16 +156739,32 @@
156563 ** to mix with a lower range bound from some other source */
156564 if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
156565
156566 /* tag-20191211-001: Do not allow constraints from the WHERE clause to
156567 ** be used by the right table of a LEFT JOIN nor by the left table of a
156568 ** RIGHT JOIN. Only constraints in the
156569 ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */
156570 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
156571 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin)
156572 ){
156573 continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156574 }
156575
156576 if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
156577 pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
156578 }else{
@@ -156920,27 +157112,30 @@
156920 /* Check to see if a partial index with pPartIndexWhere can be used
156921 ** in the current query. Return true if it can be and false if not.
156922 */
156923 static int whereUsablePartialIndex(
156924 int iTab, /* The table for which we want an index */
156925 int isLeft, /* True if iTab is the right table of a LEFT JOIN */
156926 WhereClause *pWC, /* The WHERE clause of the query */
156927 Expr *pWhere /* The WHERE clause from the partial index */
156928 ){
156929 int i;
156930 WhereTerm *pTerm;
156931 Parse *pParse = pWC->pWInfo->pParse;
 
 
 
156932 while( pWhere->op==TK_AND ){
156933 if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0;
156934 pWhere = pWhere->pRight;
156935 }
156936 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
156937 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
156938 Expr *pExpr;
156939 pExpr = pTerm->pExpr;
156940 if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iJoin==iTab)
156941 && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
156942 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
156943 && (pTerm->wtFlags & TERM_VNULL)==0
156944 ){
156945 return 1;
156946 }
@@ -157102,13 +157297,12 @@
157102 /* Loop over all indices. If there was an INDEXED BY clause, then only
157103 ** consider index pProbe. */
157104 for(; rc==SQLITE_OK && pProbe;
157105 pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++
157106 ){
157107 int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0;
157108 if( pProbe->pPartIdxWhere!=0
157109 && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC,
157110 pProbe->pPartIdxWhere)
157111 ){
157112 testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
157113 continue; /* Partial index inappropriate for this query */
157114 }
@@ -157212,11 +157406,18 @@
157212
157213 pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup);
157214 }
157215 ApplyCostMultiplier(pNew->rRun, pTab->costMult);
157216 whereLoopOutputAdjust(pWC, pNew, rSize);
157217 rc = whereLoopInsert(pBuilder, pNew);
 
 
 
 
 
 
 
157218 pNew->nOut = rSize;
157219 if( rc ) break;
157220 }
157221 }
157222
@@ -157387,10 +157588,11 @@
157387 pIdxInfo->orderByConsumed = 0;
157388 pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
157389 *pbIn = 1; assert( (mExclude & WO_IN)==0 );
157390 }
157391
 
157392 if( isLimitTerm(pTerm) && *pbIn ){
157393 /* If there is an IN(...) term handled as an == (separate call to
157394 ** xFilter for each value on the RHS of the IN) and a LIMIT or
157395 ** OFFSET term handled as well, the plan is unusable. Set output
157396 ** variable *pbRetryLimit to true to tell the caller to retry with
@@ -157860,11 +158062,13 @@
157860 SrcList *pTabList = pWInfo->pTabList;
157861 SrcItem *pItem;
157862 SrcItem *pEnd = &pTabList->a[pWInfo->nLevel];
157863 sqlite3 *db = pWInfo->pParse->db;
157864 int rc = SQLITE_OK;
 
157865 WhereLoop *pNew;
 
157866
157867 /* Loop over the tables in the join, from left to right */
157868 pNew = pBuilder->pNew;
157869 whereLoopInit(pNew);
157870 pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
@@ -157871,14 +158075,17 @@
157871 for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
157872 Bitmask mUnusable = 0;
157873 pNew->iTab = iTab;
157874 pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
157875 pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
157876 if( (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
157877 /* This condition is true when pItem is the FROM clause term on the
157878 ** right-hand-side of a OUTER or CROSS JOIN. */
 
 
157879 mPrereq |= mPrior;
 
157880 }
157881 #ifndef SQLITE_OMIT_VIRTUALTABLE
157882 if( IsVirtual(pItem->pTab) ){
157883 SrcItem *p;
157884 for(p=&pItem[1]; p<pEnd; p++){
@@ -158944,11 +159151,11 @@
158944 }
158945 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
158946 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
158947 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
158948 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
158949 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
158950 || pTerm->pExpr->w.iJoin!=pItem->iCursor
158951 ){
158952 break;
158953 }
158954 }
@@ -159570,10 +159777,11 @@
159570 op = OP_ReopenIdx;
159571 }else{
159572 iIndexCur = pParse->nTab++;
159573 }
159574 pLevel->iIdxCur = iIndexCur;
 
159575 assert( pIx->pSchema==pTab->pSchema );
159576 assert( iIndexCur>=0 );
159577 if( op ){
159578 sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
159579 sqlite3VdbeSetP4KeyInfo(pParse, pIx);
@@ -159645,13 +159853,24 @@
159645 ** program.
159646 */
159647 for(ii=0; ii<nTabList; ii++){
159648 int addrExplain;
159649 int wsFlags;
 
159650 if( pParse->nErr ) goto whereBeginError;
159651 pLevel = &pWInfo->a[ii];
159652 wsFlags = pLevel->pWLoop->wsFlags;
 
 
 
 
 
 
 
 
 
 
159653 if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
159654 if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
159655 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
159656 constructAutomaticIndex(pParse, &pWInfo->sWC,
159657 &pTabList->a[pLevel->iFrom], notReady, pLevel);
@@ -159739,10 +159958,11 @@
159739 WhereLevel *pLevel;
159740 WhereLoop *pLoop;
159741 SrcList *pTabList = pWInfo->pTabList;
159742 sqlite3 *db = pParse->db;
159743 int iEnd = sqlite3VdbeCurrentAddr(v);
 
159744
159745 /* Generate loop termination code.
159746 */
159747 VdbeModuleComment((v, "End WHERE-core"));
159748 for(i=pWInfo->nLevel-1; i>=0; i--){
@@ -159755,12 +159975,11 @@
159755 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159756 pLevel->addrCont = 0;
159757 pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v);
159758 sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
159759 VdbeCoverage(v);
159760 assert( pParse->withinRJSubrtn>0 );
159761 pParse->withinRJSubrtn--;
159762 }
159763 pLoop = pLevel->pWLoop;
159764 if( pLevel->op!=OP_Noop ){
159765 #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
159766 int addrSeek = 0;
@@ -159898,10 +160117,11 @@
159898 VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
159899 pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
159900 }
159901
159902 assert( pWInfo->nLevel<=pTabList->nSrc );
 
159903 for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
159904 int k, last;
159905 VdbeOp *pOp, *pLastOp;
159906 Index *pIdx = 0;
159907 SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
@@ -160034,13 +160254,13 @@
160034 */
160035 sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
160036
160037 /* Final cleanup
160038 */
160039 if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
160040 pParse->nQueryLoop = pWInfo->savedNQueryLoop;
160041 whereInfoFree(db, pWInfo);
 
160042 return;
160043 }
160044
160045 /************** End of where.c ***********************************************/
160046 /************** Begin file window.c ******************************************/
@@ -163662,22 +163882,22 @@
163662 #define sqlite3ParserCTX_PDECL ,Parse *pParse
163663 #define sqlite3ParserCTX_PARAM ,pParse
163664 #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
163665 #define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
163666 #define YYFALLBACK 1
163667 #define YYNSTATE 570
163668 #define YYNRULE 403
163669 #define YYNRULE_WITH_ACTION 340
163670 #define YYNTOKEN 185
163671 #define YY_MAX_SHIFT 569
163672 #define YY_MIN_SHIFTREDUCE 829
163673 #define YY_MAX_SHIFTREDUCE 1231
163674 #define YY_ERROR_ACTION 1232
163675 #define YY_ACCEPT_ACTION 1233
163676 #define YY_NO_ACTION 1234
163677 #define YY_MIN_REDUCE 1235
163678 #define YY_MAX_REDUCE 1637
163679 /************* End control #defines *******************************************/
163680 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
163681
163682 /* Define the yytestcase() macro to be a no-op if is not already defined
163683 ** otherwise.
@@ -163740,219 +163960,222 @@
163740 ** yy_reduce_ofst[] For each state, the offset into yy_action for
163741 ** shifting non-terminals after a reduce.
163742 ** yy_default[] Default action for each state.
163743 **
163744 *********** Begin parsing tables **********************************************/
163745 #define YY_ACTTAB_COUNT (2064)
163746 static const YYACTIONTYPE yy_action[] = {
163747 /* 0 */ 562, 204, 562, 116, 112, 225, 562, 116, 112, 225,
163748 /* 10 */ 562, 1306, 373, 1285, 404, 556, 556, 556, 562, 405,
163749 /* 20 */ 374, 1306, 1268, 41, 41, 41, 41, 204, 1516, 71,
163750 /* 30 */ 71, 965, 415, 41, 41, 487, 299, 275, 299, 966,
163751 /* 40 */ 393, 71, 71, 123, 124, 114, 1209, 1209, 1042, 1045,
163752 /* 50 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 472, 405,
163753 /* 60 */ 1233, 1, 1, 569, 2, 1237, 544, 116, 112, 225,
163754 /* 70 */ 313, 476, 142, 476, 520, 116, 112, 225, 525, 1319,
163755 /* 80 */ 413, 519, 138, 123, 124, 114, 1209, 1209, 1042, 1045,
163756 /* 90 */ 1034, 1034, 121, 121, 122, 122, 122, 122, 116, 112,
163757 /* 100 */ 225, 323, 120, 120, 120, 120, 119, 119, 118, 118,
163758 /* 110 */ 118, 117, 113, 440, 280, 280, 280, 280, 438, 438,
163759 /* 120 */ 438, 1557, 372, 1559, 1184, 371, 1155, 559, 1155, 559,
163760 /* 130 */ 405, 1557, 533, 255, 222, 440, 99, 141, 445, 312,
163761 /* 140 */ 553, 236, 120, 120, 120, 120, 119, 119, 118, 118,
163762 /* 150 */ 118, 117, 113, 440, 123, 124, 114, 1209, 1209, 1042,
163763 /* 160 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 138,
163764 /* 170 */ 290, 1184, 335, 444, 118, 118, 118, 117, 113, 440,
163765 /* 180 */ 125, 1184, 1185, 1186, 144, 437, 436, 562, 117, 113,
163766 /* 190 */ 440, 122, 122, 122, 122, 115, 120, 120, 120, 120,
163767 /* 200 */ 119, 119, 118, 118, 118, 117, 113, 440, 450, 110,
163768 /* 210 */ 13, 13, 542, 120, 120, 120, 120, 119, 119, 118,
163769 /* 220 */ 118, 118, 117, 113, 440, 418, 312, 553, 1184, 1185,
163770 /* 230 */ 1186, 145, 1216, 405, 1216, 122, 122, 122, 122, 120,
163771 /* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
163772 /* 250 */ 440, 461, 338, 1031, 1031, 1043, 1046, 123, 124, 114,
163773 /* 260 */ 1209, 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122,
163774 /* 270 */ 122, 122, 1271, 518, 218, 1184, 562, 405, 220, 510,
163775 /* 280 */ 171, 80, 81, 120, 120, 120, 120, 119, 119, 118,
163776 /* 290 */ 118, 118, 117, 113, 440, 1001, 16, 16, 1184, 55,
163777 /* 300 */ 55, 123, 124, 114, 1209, 1209, 1042, 1045, 1034, 1034,
163778 /* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120,
163779 /* 320 */ 119, 119, 118, 118, 118, 117, 113, 440, 1035, 542,
163780 /* 330 */ 1184, 369, 1184, 1185, 1186, 248, 1426, 395, 500, 497,
163781 /* 340 */ 496, 108, 554, 560, 4, 920, 920, 429, 495, 336,
163782 /* 350 */ 456, 324, 356, 390, 1229, 1184, 1185, 1186, 557, 562,
163783 /* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117,
163784 /* 370 */ 113, 440, 280, 280, 365, 1570, 1597, 437, 436, 150,
163785 /* 380 */ 405, 441, 71, 71, 1278, 559, 1213, 1184, 1185, 1186,
163786 /* 390 */ 83, 1215, 267, 551, 539, 511, 1551, 562, 96, 1214,
163787 /* 400 */ 6, 1270, 468, 138, 123, 124, 114, 1209, 1209, 1042,
163788 /* 410 */ 1045, 1034, 1034, 121, 121, 122, 122, 122, 122, 544,
163789 /* 420 */ 13, 13, 1021, 503, 1216, 1184, 1216, 543, 106, 106,
163790 /* 430 */ 218, 562, 1230, 171, 562, 423, 107, 193, 441, 564,
163791 /* 440 */ 563, 426, 1542, 1011, 321, 545, 1184, 266, 283, 364,
163792 /* 450 */ 506, 359, 505, 253, 71, 71, 539, 71, 71, 355,
163793 /* 460 */ 312, 553, 1603, 120, 120, 120, 120, 119, 119, 118,
163794 /* 470 */ 118, 118, 117, 113, 440, 1011, 1011, 1013, 1014, 27,
163795 /* 480 */ 280, 280, 1184, 1185, 1186, 1150, 562, 1602, 405, 895,
163796 /* 490 */ 186, 544, 352, 559, 544, 931, 529, 513, 1150, 512,
163797 /* 500 */ 409, 1150, 546, 1184, 1185, 1186, 562, 540, 1544, 51,
163798 /* 510 */ 51, 210, 123, 124, 114, 1209, 1209, 1042, 1045, 1034,
163799 /* 520 */ 1034, 121, 121, 122, 122, 122, 122, 1184, 470, 56,
163800 /* 530 */ 56, 405, 280, 280, 1480, 501, 119, 119, 118, 118,
163801 /* 540 */ 118, 117, 113, 440, 1001, 559, 514, 213, 537, 1551,
163802 /* 550 */ 312, 553, 138, 6, 528, 123, 124, 114, 1209, 1209,
163803 /* 560 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163804 /* 570 */ 1545, 120, 120, 120, 120, 119, 119, 118, 118, 118,
163805 /* 580 */ 117, 113, 440, 481, 1184, 1185, 1186, 478, 277, 1259,
163806 /* 590 */ 951, 248, 1184, 369, 500, 497, 496, 1184, 336, 565,
163807 /* 600 */ 1184, 565, 405, 288, 495, 951, 870, 187, 476, 312,
163808 /* 610 */ 553, 380, 286, 376, 120, 120, 120, 120, 119, 119,
163809 /* 620 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163810 /* 630 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163811 /* 640 */ 122, 405, 390, 1128, 1184, 863, 98, 280, 280, 1184,
163812 /* 650 */ 1185, 1186, 369, 1085, 1184, 1185, 1186, 1184, 1185, 1186,
163813 /* 660 */ 559, 451, 32, 369, 229, 123, 124, 114, 1209, 1209,
163814 /* 670 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163815 /* 680 */ 1425, 953, 562, 224, 952, 120, 120, 120, 120, 119,
163816 /* 690 */ 119, 118, 118, 118, 117, 113, 440, 1150, 224, 1184,
163817 /* 700 */ 153, 1184, 1185, 1186, 1543, 13, 13, 297, 951, 1224,
163818 /* 710 */ 1150, 149, 405, 1150, 369, 1573, 1168, 5, 365, 1570,
163819 /* 720 */ 425, 1230, 3, 951, 120, 120, 120, 120, 119, 119,
163820 /* 730 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163821 /* 740 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163822 /* 750 */ 122, 405, 204, 561, 1184, 1022, 1184, 1185, 1186, 1184,
163823 /* 760 */ 384, 846, 151, 1542, 282, 398, 1090, 1090, 484, 562,
163824 /* 770 */ 461, 338, 1311, 1311, 1542, 123, 124, 114, 1209, 1209,
163825 /* 780 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163826 /* 790 */ 127, 562, 13, 13, 370, 120, 120, 120, 120, 119,
163827 /* 800 */ 119, 118, 118, 118, 117, 113, 440, 298, 562, 449,
163828 /* 810 */ 524, 1184, 1185, 1186, 13, 13, 1184, 1185, 1186, 1289,
163829 /* 820 */ 459, 1259, 405, 1309, 1309, 1542, 1006, 449, 448, 196,
163830 /* 830 */ 295, 71, 71, 1257, 120, 120, 120, 120, 119, 119,
163831 /* 840 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163832 /* 850 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163833 /* 860 */ 122, 405, 223, 1065, 1150, 280, 280, 415, 308, 274,
163834 /* 870 */ 274, 281, 281, 1411, 402, 401, 378, 1150, 559, 562,
163835 /* 880 */ 1150, 1188, 559, 1590, 559, 123, 124, 114, 1209, 1209,
163836 /* 890 */ 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122, 122,
163837 /* 900 */ 449, 1472, 13, 13, 1526, 120, 120, 120, 120, 119,
163838 /* 910 */ 119, 118, 118, 118, 117, 113, 440, 197, 562, 350,
163839 /* 920 */ 1576, 569, 2, 1237, 834, 835, 836, 1552, 313, 1204,
163840 /* 930 */ 142, 6, 405, 251, 250, 249, 202, 1319, 9, 1188,
163841 /* 940 */ 258, 71, 71, 420, 120, 120, 120, 120, 119, 119,
163842 /* 950 */ 118, 118, 118, 117, 113, 440, 123, 124, 114, 1209,
163843 /* 960 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163844 /* 970 */ 122, 562, 280, 280, 562, 1205, 405, 568, 309, 1237,
163845 /* 980 */ 345, 1288, 348, 415, 313, 559, 142, 487, 521, 1633,
163846 /* 990 */ 391, 367, 487, 1319, 70, 70, 1287, 71, 71, 236,
163847 /* 1000 */ 1317, 101, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121,
163848 /* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119,
163849 /* 1020 */ 119, 118, 118, 118, 117, 113, 440, 1106, 280, 280,
163850 /* 1030 */ 424, 444, 1515, 1205, 435, 280, 280, 1479, 1344, 307,
163851 /* 1040 */ 470, 559, 1107, 965, 487, 487, 213, 1255, 559, 1528,
163852 /* 1050 */ 562, 966, 203, 562, 1021, 236, 379, 1108, 515, 120,
163853 /* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113,
163854 /* 1070 */ 440, 1012, 104, 71, 71, 1011, 13, 13, 906, 562,
163855 /* 1080 */ 1485, 562, 280, 280, 95, 522, 487, 444, 907, 1318,
163856 /* 1090 */ 1314, 541, 405, 280, 280, 559, 147, 205, 1485, 1487,
163857 /* 1100 */ 258, 446, 15, 15, 43, 43, 559, 1011, 1011, 1013,
163858 /* 1110 */ 439, 328, 405, 523, 12, 291, 123, 124, 114, 1209,
163859 /* 1120 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163860 /* 1130 */ 122, 343, 405, 858, 1524, 1205, 123, 124, 114, 1209,
163861 /* 1140 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163862 /* 1150 */ 122, 1129, 1631, 470, 1631, 367, 123, 111, 114, 1209,
163863 /* 1160 */ 1209, 1042, 1045, 1034, 1034, 121, 121, 122, 122, 122,
163864 /* 1170 */ 122, 1485, 325, 470, 327, 120, 120, 120, 120, 119,
163865 /* 1180 */ 119, 118, 118, 118, 117, 113, 440, 199, 1411, 562,
163866 /* 1190 */ 1286, 858, 460, 1205, 432, 120, 120, 120, 120, 119,
163867 /* 1200 */ 119, 118, 118, 118, 117, 113, 440, 547, 1129, 1632,
163868 /* 1210 */ 535, 1632, 57, 57, 886, 120, 120, 120, 120, 119,
163869 /* 1220 */ 119, 118, 118, 118, 117, 113, 440, 562, 294, 534,
163870 /* 1230 */ 1127, 1411, 1549, 1550, 1323, 405, 6, 6, 1161, 1260,
163871 /* 1240 */ 411, 316, 280, 280, 1411, 504, 559, 521, 296, 453,
163872 /* 1250 */ 44, 44, 562, 887, 12, 559, 326, 474, 421, 403,
163873 /* 1260 */ 124, 114, 1209, 1209, 1042, 1045, 1034, 1034, 121, 121,
163874 /* 1270 */ 122, 122, 122, 122, 562, 58, 58, 284, 1184, 1411,
163875 /* 1280 */ 492, 454, 388, 388, 387, 269, 385, 1127, 1548, 843,
163876 /* 1290 */ 1161, 403, 6, 562, 317, 1150, 466, 59, 59, 1547,
163877 /* 1300 */ 1106, 422, 230, 6, 319, 252, 536, 252, 1150, 427,
163878 /* 1310 */ 562, 1150, 318, 17, 483, 1107, 60, 60, 120, 120,
163879 /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 440,
163880 /* 1330 */ 1108, 212, 477, 61, 61, 1184, 1185, 1186, 108, 554,
163881 /* 1340 */ 320, 4, 232, 452, 522, 562, 233, 452, 562, 433,
163882 /* 1350 */ 164, 550, 416, 137, 475, 557, 562, 289, 562, 1087,
163883 /* 1360 */ 562, 289, 562, 1087, 527, 562, 866, 8, 62, 62,
163884 /* 1370 */ 231, 45, 45, 562, 410, 562, 410, 562, 441, 46,
163885 /* 1380 */ 46, 47, 47, 49, 49, 50, 50, 195, 63, 63,
163886 /* 1390 */ 551, 562, 355, 562, 98, 482, 64, 64, 65, 65,
163887 /* 1400 */ 14, 14, 555, 411, 531, 406, 562, 1021, 562, 530,
163888 /* 1410 */ 312, 553, 312, 553, 66, 66, 129, 129, 562, 1021,
163889 /* 1420 */ 562, 508, 926, 866, 1012, 106, 106, 925, 1011, 67,
163890 /* 1430 */ 67, 52, 52, 107, 447, 441, 564, 563, 412, 173,
163891 /* 1440 */ 1011, 68, 68, 69, 69, 562, 463, 562, 926, 467,
163892 /* 1450 */ 1356, 279, 222, 925, 311, 1355, 403, 562, 455, 403,
163893 /* 1460 */ 1011, 1011, 1013, 235, 403, 84, 209, 1342, 53, 53,
163894 /* 1470 */ 159, 159, 1011, 1011, 1013, 1014, 27, 1575, 1172, 443,
163895 /* 1480 */ 160, 160, 284, 95, 105, 1531, 103, 388, 388, 387,
163896 /* 1490 */ 269, 385, 562, 873, 843, 877, 562, 108, 554, 462,
163897 /* 1500 */ 4, 562, 148, 30, 38, 562, 1124, 230, 392, 319,
163898 /* 1510 */ 108, 554, 523, 4, 557, 76, 76, 318, 562, 54,
163899 /* 1520 */ 54, 562, 333, 464, 72, 72, 329, 557, 130, 130,
163900 /* 1530 */ 562, 285, 1504, 562, 31, 1503, 562, 441, 334, 479,
163901 /* 1540 */ 98, 73, 73, 340, 157, 157, 292, 232, 1072, 551,
163902 /* 1550 */ 441, 873, 1352, 131, 131, 164, 132, 132, 137, 128,
163903 /* 1560 */ 128, 1564, 551, 531, 562, 315, 562, 344, 532, 1003,
163904 /* 1570 */ 469, 257, 257, 885, 884, 231, 531, 562, 1021, 562,
163905 /* 1580 */ 471, 530, 257, 363, 106, 106, 517, 158, 158, 152,
163906 /* 1590 */ 152, 1021, 107, 362, 441, 564, 563, 106, 106, 1011,
163907 /* 1600 */ 136, 136, 135, 135, 562, 107, 1072, 441, 564, 563,
163908 /* 1610 */ 406, 347, 1011, 562, 349, 312, 553, 562, 339, 562,
163909 /* 1620 */ 98, 493, 353, 254, 98, 892, 893, 133, 133, 351,
163910 /* 1630 */ 1302, 1011, 1011, 1013, 1014, 27, 134, 134, 1015, 447,
163911 /* 1640 */ 75, 75, 77, 77, 1011, 1011, 1013, 1014, 27, 1172,
163912 /* 1650 */ 443, 562, 358, 284, 108, 554, 368, 4, 388, 388,
163913 /* 1660 */ 387, 269, 385, 562, 1133, 843, 562, 1068, 956, 254,
163914 /* 1670 */ 257, 557, 968, 969, 74, 74, 549, 923, 230, 110,
163915 /* 1680 */ 319, 108, 554, 1084, 4, 1084, 42, 42, 318, 48,
163916 /* 1690 */ 48, 1083, 1365, 1083, 441, 856, 1015, 146, 557, 924,
163917 /* 1700 */ 1410, 110, 1338, 1350, 548, 1416, 551, 1267, 207, 1258,
163918 /* 1710 */ 1246, 1245, 1247, 1583, 11, 488, 272, 215, 232, 1335,
163919 /* 1720 */ 304, 441, 305, 306, 389, 228, 164, 1397, 1392, 137,
163920 /* 1730 */ 287, 331, 332, 551, 293, 1021, 1385, 337, 473, 200,
163921 /* 1740 */ 361, 106, 106, 930, 498, 1402, 231, 1401, 1285, 107,
163922 /* 1750 */ 396, 441, 564, 563, 219, 1476, 1011, 1347, 1475, 1348,
163923 /* 1760 */ 1346, 1345, 1021, 1224, 552, 1586, 261, 1221, 106, 106,
163924 /* 1770 */ 1523, 201, 383, 1521, 214, 414, 107, 83, 441, 564,
163925 /* 1780 */ 563, 406, 211, 1011, 175, 1398, 312, 553, 1011, 1011,
163926 /* 1790 */ 1013, 1014, 27, 226, 184, 169, 100, 554, 79, 4,
163927 /* 1800 */ 82, 457, 35, 179, 458, 177, 491, 238, 96, 1481,
163928 /* 1810 */ 447, 180, 1404, 557, 181, 1011, 1011, 1013, 1014, 27,
163929 /* 1820 */ 182, 1403, 394, 36, 465, 1406, 397, 188, 1470, 480,
163930 /* 1830 */ 242, 89, 1492, 486, 342, 244, 441, 273, 192, 346,
163931 /* 1840 */ 489, 245, 399, 1248, 428, 246, 507, 1296, 551, 91,
163932 /* 1850 */ 877, 1305, 1304, 220, 1601, 1295, 1303, 430, 431, 516,
163933 /* 1860 */ 1569, 259, 400, 302, 1600, 1275, 303, 260, 360, 1274,
163934 /* 1870 */ 1273, 1599, 366, 1555, 434, 1554, 1370, 1021, 1369, 542,
163935 /* 1880 */ 126, 10, 1456, 106, 106, 377, 102, 97, 310, 526,
163936 /* 1890 */ 34, 107, 566, 441, 564, 563, 1178, 271, 1011, 268,
163937 /* 1900 */ 270, 567, 1243, 1238, 206, 1328, 375, 381, 1327, 382,
163938 /* 1910 */ 407, 161, 174, 408, 1508, 1509, 143, 300, 830, 162,
163939 /* 1920 */ 1507, 1506, 163, 442, 208, 314, 227, 216, 217, 78,
163940 /* 1930 */ 1011, 1011, 1013, 1014, 27, 140, 1082, 322, 1080, 165,
163941 /* 1940 */ 176, 1204, 234, 178, 909, 330, 237, 1096, 183, 166,
163942 /* 1950 */ 167, 417, 85, 86, 419, 185, 87, 88, 168, 1099,
163943 /* 1960 */ 239, 1095, 240, 154, 18, 241, 341, 1218, 257, 1088,
163944 /* 1970 */ 243, 485, 190, 189, 37, 845, 490, 362, 247, 494,
163945 /* 1980 */ 357, 191, 875, 90, 19, 502, 354, 20, 499, 92,
163946 /* 1990 */ 170, 155, 888, 93, 301, 509, 94, 1166, 156, 1048,
163947 /* 2000 */ 1135, 39, 221, 1134, 276, 278, 256, 194, 110, 960,
163948 /* 2010 */ 954, 1156, 21, 1152, 22, 1160, 1140, 1154, 23, 33,
163949 /* 2020 */ 24, 1159, 25, 538, 26, 198, 98, 1063, 1049, 1047,
163950 /* 2030 */ 1051, 7, 1105, 262, 1104, 263, 1052, 28, 40, 558,
163951 /* 2040 */ 1016, 857, 109, 29, 919, 386, 139, 172, 264, 265,
163952 /* 2050 */ 1174, 1592, 1173, 1234, 1234, 1234, 1234, 1234, 1234, 1234,
163953 /* 2060 */ 1234, 1234, 1234, 1591,
 
 
 
163954 };
163955 static const YYCODETYPE yy_lookahead[] = {
163956 /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276,
163957 /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19,
163958 /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216,
@@ -164114,57 +164337,57 @@
164114 /* 1580 */ 23, 90, 25, 121, 106, 107, 19, 216, 217, 216,
164115 /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121,
164116 /* 1600 */ 216, 217, 216, 217, 193, 114, 117, 116, 117, 118,
164117 /* 1610 */ 133, 193, 121, 193, 193, 138, 139, 193, 23, 193,
164118 /* 1620 */ 25, 23, 23, 25, 25, 7, 8, 216, 217, 193,
164119 /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 59, 162,
164120 /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1,
164121 /* 1650 */ 2, 193, 193, 5, 19, 20, 193, 22, 10, 11,
164122 /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 23, 25,
164123 /* 1670 */ 25, 36, 83, 84, 216, 217, 236, 23, 30, 25,
164124 /* 1680 */ 32, 19, 20, 153, 22, 155, 216, 217, 40, 216,
164125 /* 1690 */ 217, 153, 193, 155, 59, 23, 117, 25, 36, 23,
164126 /* 1700 */ 193, 25, 193, 193, 193, 193, 71, 193, 242, 193,
164127 /* 1710 */ 193, 193, 193, 193, 243, 288, 287, 214, 70, 255,
164128 /* 1720 */ 255, 59, 255, 255, 191, 297, 78, 271, 267, 81,
164129 /* 1730 */ 245, 293, 246, 71, 246, 100, 267, 245, 293, 249,
164130 /* 1740 */ 219, 106, 107, 108, 220, 271, 98, 271, 225, 114,
164131 /* 1750 */ 271, 116, 117, 118, 229, 219, 121, 259, 219, 259,
164132 /* 1760 */ 259, 259, 100, 60, 280, 196, 141, 38, 106, 107,
164133 /* 1770 */ 200, 249, 245, 200, 243, 200, 114, 151, 116, 117,
164134 /* 1780 */ 118, 133, 150, 121, 297, 272, 138, 139, 153, 154,
164135 /* 1790 */ 155, 156, 157, 297, 22, 43, 19, 20, 294, 22,
164136 /* 1800 */ 294, 18, 270, 237, 200, 234, 18, 199, 149, 283,
164137 /* 1810 */ 162, 237, 272, 36, 237, 153, 154, 155, 156, 157,
164138 /* 1820 */ 237, 272, 246, 270, 246, 234, 246, 234, 246, 200,
164139 /* 1830 */ 199, 158, 290, 62, 289, 199, 59, 200, 22, 200,
164140 /* 1840 */ 221, 199, 221, 200, 64, 199, 115, 227, 71, 22,
164141 /* 1850 */ 126, 218, 218, 165, 224, 227, 218, 24, 113, 305,
164142 /* 1860 */ 312, 200, 221, 282, 224, 218, 282, 91, 218, 220,
164143 /* 1870 */ 218, 218, 221, 317, 82, 317, 265, 100, 265, 145,
164144 /* 1880 */ 148, 22, 277, 106, 107, 200, 158, 147, 279, 146,
164145 /* 1890 */ 25, 114, 202, 116, 117, 118, 13, 6, 121, 194,
164146 /* 1900 */ 194, 192, 192, 192, 248, 250, 249, 247, 250, 246,
164147 /* 1910 */ 303, 207, 300, 303, 213, 213, 222, 222, 4, 207,
164148 /* 1920 */ 213, 213, 207, 3, 22, 163, 15, 214, 214, 213,
164149 /* 1930 */ 153, 154, 155, 156, 157, 16, 23, 139, 23, 130,
164150 /* 1940 */ 151, 25, 24, 142, 20, 16, 144, 1, 142, 130,
164151 /* 1950 */ 130, 61, 53, 53, 37, 151, 53, 53, 130, 116,
164152 /* 1960 */ 34, 1, 141, 5, 22, 115, 161, 75, 25, 68,
164153 /* 1970 */ 141, 41, 115, 68, 24, 20, 19, 131, 125, 67,
164154 /* 1980 */ 24, 22, 59, 22, 22, 96, 23, 22, 67, 22,
164155 /* 1990 */ 37, 23, 28, 149, 67, 22, 25, 23, 23, 23,
164156 /* 2000 */ 23, 22, 141, 97, 23, 23, 34, 22, 25, 116,
164157 /* 2010 */ 143, 75, 34, 88, 34, 75, 23, 86, 34, 22,
164158 /* 2020 */ 34, 93, 34, 24, 34, 25, 25, 23, 23, 23,
164159 /* 2030 */ 23, 44, 23, 25, 23, 22, 11, 22, 22, 25,
164160 /* 2040 */ 23, 23, 22, 22, 135, 15, 23, 25, 141, 141,
164161 /* 2050 */ 1, 141, 1, 319, 319, 319, 319, 319, 319, 319,
164162 /* 2060 */ 319, 319, 319, 141, 319, 319, 319, 319, 319, 319,
164163 /* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164164 /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164165 /* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164166 /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164167 /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164168 /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164169 /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164170 /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
@@ -164175,77 +164398,82 @@
164175 /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164176 /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164177 /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164178 /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164179 /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164180 /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319,
 
 
 
 
164181 };
164182 #define YY_SHIFT_COUNT (569)
164183 #define YY_SHIFT_MIN (0)
164184 #define YY_SHIFT_MAX (2051)
164185 static const unsigned short int yy_shift_ofst[] = {
164186 /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1662,
164187 /* 10 */ 1662, 1662, 471, 0, 0, 214, 1093, 1662, 1662, 1662,
164188 /* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164189 /* 30 */ 271, 271, 1219, 1219, 216, 88, 1, 1, 1, 1,
164190 /* 40 */ 1, 40, 111, 258, 361, 469, 512, 583, 622, 693,
164191 /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093,
164192 /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
164193 /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662,
164194 /* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164195 /* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164196 /* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
164197 /* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662,
164198 /* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181,
164199 /* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366,
164200 /* 140 */ 533, 533, 740, 1261, 533, 533, 79, 79, 533, 412,
164201 /* 150 */ 412, 412, 77, 412, 123, 113, 113, 22, 22, 2064,
164202 /* 160 */ 2064, 328, 328, 328, 239, 468, 468, 468, 468, 1015,
164203 /* 170 */ 1015, 409, 366, 1129, 1186, 533, 533, 533, 533, 533,
164204 /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
164205 /* 190 */ 533, 533, 533, 533, 533, 969, 621, 621, 533, 642,
164206 /* 200 */ 788, 788, 1228, 1228, 822, 822, 67, 1274, 2064, 2064,
164207 /* 210 */ 2064, 2064, 2064, 2064, 2064, 1307, 954, 954, 585, 472,
164208 /* 220 */ 640, 387, 695, 538, 541, 700, 533, 533, 533, 533,
164209 /* 230 */ 533, 533, 533, 533, 533, 533, 222, 533, 533, 533,
164210 /* 240 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 1179,
164211 /* 250 */ 1179, 1179, 533, 533, 533, 565, 533, 533, 533, 916,
164212 /* 260 */ 1144, 533, 533, 1288, 533, 533, 533, 533, 533, 533,
164213 /* 270 */ 533, 533, 639, 1330, 209, 1076, 1076, 1076, 1076, 580,
164214 /* 280 */ 209, 209, 1313, 768, 917, 649, 1181, 1316, 405, 1316,
164215 /* 290 */ 1238, 249, 1181, 1181, 249, 1181, 405, 1238, 1369, 464,
164216 /* 300 */ 1259, 1012, 1012, 1012, 1368, 1368, 1368, 1368, 184, 184,
164217 /* 310 */ 1326, 904, 1287, 1480, 1703, 1703, 1625, 1625, 1729, 1729,
164218 /* 320 */ 1625, 1626, 1632, 1772, 1752, 1783, 1783, 1783, 1783, 1625,
164219 /* 330 */ 1788, 1659, 1632, 1632, 1659, 1772, 1752, 1659, 1752, 1659,
164220 /* 340 */ 1625, 1788, 1673, 1771, 1625, 1788, 1816, 1625, 1788, 1625,
164221 /* 350 */ 1788, 1816, 1731, 1731, 1731, 1780, 1827, 1827, 1816, 1731,
164222 /* 360 */ 1724, 1731, 1780, 1731, 1731, 1688, 1833, 1745, 1745, 1816,
164223 /* 370 */ 1625, 1776, 1776, 1792, 1792, 1732, 1734, 1859, 1625, 1728,
164224 /* 380 */ 1732, 1740, 1743, 1659, 1865, 1883, 1883, 1891, 1891, 1891,
164225 /* 390 */ 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064, 2064,
164226 /* 400 */ 2064, 2064, 2064, 2064, 2064, 207, 1095, 331, 620, 903,
164227 /* 410 */ 806, 1074, 1483, 1432, 1481, 1322, 1370, 1394, 1515, 1291,
164228 /* 420 */ 1546, 1547, 1557, 1595, 1598, 1599, 1434, 1453, 1618, 1462,
164229 /* 430 */ 1567, 1489, 1644, 1645, 1589, 1654, 1530, 1538, 1672, 1676,
164230 /* 440 */ 1579, 742, 1914, 1920, 1902, 1762, 1911, 1919, 1913, 1915,
164231 /* 450 */ 1798, 1789, 1809, 1916, 1916, 1918, 1801, 1924, 1802, 1929,
164232 /* 460 */ 1946, 1806, 1819, 1916, 1820, 1890, 1917, 1916, 1804, 1899,
164233 /* 470 */ 1900, 1903, 1904, 1828, 1843, 1926, 1821, 1960, 1958, 1942,
164234 /* 480 */ 1850, 1805, 1901, 1943, 1905, 1892, 1930, 1829, 1857, 1950,
164235 /* 490 */ 1955, 1957, 1846, 1853, 1959, 1912, 1961, 1962, 1963, 1965,
164236 /* 500 */ 1921, 1923, 1956, 1889, 1964, 1967, 1927, 1953, 1968, 1844,
164237 /* 510 */ 1973, 1974, 1975, 1976, 1971, 1977, 1979, 1906, 1861, 1981,
164238 /* 520 */ 1982, 1893, 1972, 1985, 1867, 1983, 1978, 1980, 1984, 1986,
164239 /* 530 */ 1925, 1936, 1931, 1987, 1940, 1928, 1988, 1993, 1997, 1999,
164240 /* 540 */ 2000, 2001, 1990, 2004, 1983, 2005, 2006, 2007, 2009, 2008,
164241 /* 550 */ 2011, 2013, 2025, 2015, 2016, 2017, 2018, 2020, 2021, 2014,
164242 /* 560 */ 1909, 1907, 1908, 1910, 1922, 2022, 2023, 2030, 2049, 2051,
 
164243 };
164244 #define YY_REDUCE_COUNT (404)
164245 #define YY_REDUCE_MIN (-271)
164246 #define YY_REDUCE_MAX (1716)
164247 static const short yy_reduce_ofst[] = {
164248 /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187,
164249 /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489,
164250 /* 20 */ 576, -175, 598, 686, 615, 725, 860, 778, 781, 857,
164251 /* 30 */ 616, 887, 87, 240, -192, 408, 626, 796, 843, 854,
@@ -164255,98 +164483,99 @@
164255 /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 80, 83,
164256 /* 80 */ 313, 886, 888, 996, 1034, 1059, 1081, 1100, 1117, 1152,
164257 /* 90 */ 1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198,
164258 /* 100 */ 1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303,
164259 /* 110 */ 1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384,
164260 /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, -271, -271,
164261 /* 130 */ -271, -271, -271, -271, -271, -271, -271, 138, 459, 396,
164262 /* 140 */ -158, 470, 302, -212, 521, 201, -195, -92, 559, 630,
164263 /* 150 */ 632, 630, -271, 632, 901, 63, 407, -271, -271, -271,
164264 /* 160 */ -271, 161, 161, 161, 251, 335, 847, 960, 980, 537,
164265 /* 170 */ 588, 618, 628, 688, 688, -166, -161, 674, 790, 794,
164266 /* 180 */ 799, 851, 852, -122, 680, -120, 995, 1038, 415, 1051,
164267 /* 190 */ 893, 798, 962, 400, 1086, 779, 923, 924, 263, 1041,
164268 /* 200 */ 979, 990, 1083, 1097, 1031, 1194, 362, 994, 1139, 1005,
164269 /* 210 */ 1037, 1202, 1205, 1195, 1210, -194, 56, 185, -135, 232,
164270 /* 220 */ 522, 560, 601, 617, 669, 683, 711, 856, 908, 941,
164271 /* 230 */ 1048, 1101, 1147, 1257, 1262, 1265, 392, 1292, 1333, 1339,
164272 /* 240 */ 1342, 1346, 1350, 1359, 1374, 1418, 1421, 1436, 1437, 593,
164273 /* 250 */ 755, 770, 997, 1459, 1463, 1209, 1499, 1507, 1509, 1132,
164274 /* 260 */ 1243, 1510, 1511, 1440, 1512, 560, 1514, 1516, 1517, 1518,
164275 /* 270 */ 1519, 1520, 1427, 1429, 1466, 1464, 1465, 1467, 1468, 1209,
164276 /* 280 */ 1466, 1466, 1471, 1503, 1533, 1428, 1456, 1461, 1485, 1469,
164277 /* 290 */ 1438, 1486, 1474, 1476, 1488, 1479, 1492, 1445, 1524, 1525,
164278 /* 300 */ 1523, 1521, 1536, 1539, 1498, 1500, 1501, 1502, 1490, 1522,
164279 /* 310 */ 1484, 1527, 1531, 1569, 1487, 1496, 1570, 1573, 1504, 1506,
164280 /* 320 */ 1575, 1526, 1513, 1532, 1571, 1566, 1574, 1577, 1583, 1604,
164281 /* 330 */ 1608, 1576, 1540, 1549, 1578, 1553, 1591, 1580, 1593, 1582,
164282 /* 340 */ 1629, 1631, 1542, 1545, 1637, 1636, 1619, 1639, 1642, 1643,
164283 /* 350 */ 1646, 1621, 1633, 1634, 1638, 1620, 1630, 1640, 1641, 1647,
164284 /* 360 */ 1649, 1650, 1628, 1652, 1653, 1548, 1554, 1581, 1584, 1651,
164285 /* 370 */ 1661, 1556, 1558, 1611, 1613, 1655, 1657, 1605, 1685, 1609,
164286 /* 380 */ 1658, 1656, 1660, 1663, 1690, 1705, 1706, 1709, 1710, 1711,
164287 /* 390 */ 1607, 1610, 1612, 1704, 1701, 1702, 1707, 1708, 1712, 1694,
164288 /* 400 */ 1695, 1713, 1714, 1716, 1715,
164289 };
164290 static const YYACTIONTYPE yy_default[] = {
164291 /* 0 */ 1637, 1637, 1637, 1465, 1232, 1343, 1232, 1232, 1232, 1465,
164292 /* 10 */ 1465, 1465, 1232, 1373, 1373, 1518, 1265, 1232, 1232, 1232,
164293 /* 20 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1464, 1232, 1232,
164294 /* 30 */ 1232, 1232, 1553, 1553, 1232, 1232, 1232, 1232, 1232, 1232,
164295 /* 40 */ 1232, 1232, 1382, 1232, 1389, 1232, 1232, 1232, 1232, 1232,
164296 /* 50 */ 1466, 1467, 1232, 1232, 1232, 1517, 1519, 1482, 1396, 1395,
164297 /* 60 */ 1394, 1393, 1500, 1361, 1387, 1380, 1384, 1460, 1461, 1459,
164298 /* 70 */ 1463, 1467, 1466, 1232, 1383, 1430, 1444, 1429, 1232, 1232,
164299 /* 80 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164300 /* 90 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164301 /* 100 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164302 /* 110 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164303 /* 120 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1438, 1443,
164304 /* 130 */ 1450, 1442, 1439, 1432, 1431, 1433, 1434, 1232, 1232, 1256,
164305 /* 140 */ 1232, 1232, 1253, 1307, 1232, 1232, 1232, 1232, 1232, 1537,
164306 /* 150 */ 1536, 1232, 1435, 1232, 1265, 1424, 1423, 1447, 1436, 1446,
164307 /* 160 */ 1445, 1525, 1589, 1588, 1483, 1232, 1232, 1232, 1232, 1232,
164308 /* 170 */ 1232, 1553, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164309 /* 180 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164310 /* 190 */ 1232, 1232, 1232, 1232, 1232, 1363, 1553, 1553, 1232, 1265,
164311 /* 200 */ 1553, 1553, 1364, 1364, 1261, 1261, 1367, 1232, 1532, 1334,
164312 /* 210 */ 1334, 1334, 1334, 1343, 1334, 1232, 1232, 1232, 1232, 1232,
164313 /* 220 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164314 /* 230 */ 1522, 1520, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164315 /* 240 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164316 /* 250 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1339,
164317 /* 260 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164318 /* 270 */ 1232, 1582, 1232, 1495, 1321, 1339, 1339, 1339, 1339, 1341,
164319 /* 280 */ 1322, 1320, 1333, 1266, 1239, 1629, 1399, 1388, 1340, 1388,
164320 /* 290 */ 1626, 1386, 1399, 1399, 1386, 1399, 1340, 1626, 1282, 1605,
164321 /* 300 */ 1277, 1373, 1373, 1373, 1363, 1363, 1363, 1363, 1367, 1367,
164322 /* 310 */ 1462, 1340, 1333, 1232, 1629, 1629, 1349, 1349, 1628, 1628,
164323 /* 320 */ 1349, 1483, 1613, 1408, 1310, 1316, 1316, 1316, 1316, 1349,
164324 /* 330 */ 1250, 1386, 1613, 1613, 1386, 1408, 1310, 1386, 1310, 1386,
164325 /* 340 */ 1349, 1250, 1499, 1623, 1349, 1250, 1473, 1349, 1250, 1349,
164326 /* 350 */ 1250, 1473, 1308, 1308, 1308, 1297, 1232, 1232, 1473, 1308,
164327 /* 360 */ 1282, 1308, 1297, 1308, 1308, 1571, 1232, 1477, 1477, 1473,
164328 /* 370 */ 1349, 1563, 1563, 1376, 1376, 1381, 1367, 1468, 1349, 1232,
164329 /* 380 */ 1381, 1379, 1377, 1386, 1300, 1585, 1585, 1581, 1581, 1581,
164330 /* 390 */ 1634, 1634, 1532, 1598, 1265, 1265, 1265, 1265, 1598, 1284,
164331 /* 400 */ 1284, 1266, 1266, 1265, 1598, 1232, 1232, 1232, 1232, 1232,
164332 /* 410 */ 1232, 1593, 1232, 1527, 1484, 1353, 1232, 1232, 1232, 1232,
164333 /* 420 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164334 /* 430 */ 1538, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164335 /* 440 */ 1232, 1413, 1232, 1235, 1529, 1232, 1232, 1232, 1232, 1232,
164336 /* 450 */ 1232, 1232, 1232, 1390, 1391, 1354, 1232, 1232, 1232, 1232,
164337 /* 460 */ 1232, 1232, 1232, 1405, 1232, 1232, 1232, 1400, 1232, 1232,
164338 /* 470 */ 1232, 1232, 1232, 1232, 1232, 1232, 1625, 1232, 1232, 1232,
164339 /* 480 */ 1232, 1232, 1232, 1498, 1497, 1232, 1232, 1351, 1232, 1232,
164340 /* 490 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164341 /* 500 */ 1232, 1280, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164342 /* 510 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164343 /* 520 */ 1232, 1232, 1232, 1232, 1232, 1378, 1232, 1232, 1232, 1232,
164344 /* 530 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
164345 /* 540 */ 1568, 1368, 1232, 1232, 1616, 1232, 1232, 1232, 1232, 1232,
164346 /* 550 */ 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1609,
164347 /* 560 */ 1324, 1415, 1232, 1414, 1418, 1254, 1232, 1244, 1232, 1232,
 
164348 };
164349 /********** End of lemon-generated parsing tables *****************************/
164350
164351 /* The next table maps tokens (terminal symbols) into fallback tokens.
164352 ** If a construct like the following:
@@ -165170,204 +165399,206 @@
165170 /* 204 */ "expr ::= expr likeop expr ESCAPE expr",
165171 /* 205 */ "expr ::= expr ISNULL|NOTNULL",
165172 /* 206 */ "expr ::= expr NOT NULL",
165173 /* 207 */ "expr ::= expr IS expr",
165174 /* 208 */ "expr ::= expr IS NOT expr",
165175 /* 209 */ "expr ::= NOT expr",
165176 /* 210 */ "expr ::= BITNOT expr",
165177 /* 211 */ "expr ::= PLUS|MINUS expr",
165178 /* 212 */ "expr ::= expr PTR expr",
165179 /* 213 */ "between_op ::= BETWEEN",
165180 /* 214 */ "between_op ::= NOT BETWEEN",
165181 /* 215 */ "expr ::= expr between_op expr AND expr",
165182 /* 216 */ "in_op ::= IN",
165183 /* 217 */ "in_op ::= NOT IN",
165184 /* 218 */ "expr ::= expr in_op LP exprlist RP",
165185 /* 219 */ "expr ::= LP select RP",
165186 /* 220 */ "expr ::= expr in_op LP select RP",
165187 /* 221 */ "expr ::= expr in_op nm dbnm paren_exprlist",
165188 /* 222 */ "expr ::= EXISTS LP select RP",
165189 /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END",
165190 /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
165191 /* 225 */ "case_exprlist ::= WHEN expr THEN expr",
165192 /* 226 */ "case_else ::= ELSE expr",
165193 /* 227 */ "case_else ::=",
165194 /* 228 */ "case_operand ::= expr",
165195 /* 229 */ "case_operand ::=",
165196 /* 230 */ "exprlist ::=",
165197 /* 231 */ "nexprlist ::= nexprlist COMMA expr",
165198 /* 232 */ "nexprlist ::= expr",
165199 /* 233 */ "paren_exprlist ::=",
165200 /* 234 */ "paren_exprlist ::= LP exprlist RP",
165201 /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
165202 /* 236 */ "uniqueflag ::= UNIQUE",
165203 /* 237 */ "uniqueflag ::=",
165204 /* 238 */ "eidlist_opt ::=",
165205 /* 239 */ "eidlist_opt ::= LP eidlist RP",
165206 /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder",
165207 /* 241 */ "eidlist ::= nm collate sortorder",
165208 /* 242 */ "collate ::=",
165209 /* 243 */ "collate ::= COLLATE ID|STRING",
165210 /* 244 */ "cmd ::= DROP INDEX ifexists fullname",
165211 /* 245 */ "cmd ::= VACUUM vinto",
165212 /* 246 */ "cmd ::= VACUUM nm vinto",
165213 /* 247 */ "vinto ::= INTO expr",
165214 /* 248 */ "vinto ::=",
165215 /* 249 */ "cmd ::= PRAGMA nm dbnm",
165216 /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
165217 /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
165218 /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
165219 /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
165220 /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT",
165221 /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT",
165222 /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
165223 /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
165224 /* 258 */ "trigger_time ::= BEFORE|AFTER",
165225 /* 259 */ "trigger_time ::= INSTEAD OF",
165226 /* 260 */ "trigger_time ::=",
165227 /* 261 */ "trigger_event ::= DELETE|INSERT",
165228 /* 262 */ "trigger_event ::= UPDATE",
165229 /* 263 */ "trigger_event ::= UPDATE OF idlist",
165230 /* 264 */ "when_clause ::=",
165231 /* 265 */ "when_clause ::= WHEN expr",
165232 /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
165233 /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI",
165234 /* 268 */ "trnm ::= nm DOT nm",
165235 /* 269 */ "tridxby ::= INDEXED BY nm",
165236 /* 270 */ "tridxby ::= NOT INDEXED",
165237 /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
165238 /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
165239 /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
165240 /* 274 */ "trigger_cmd ::= scanpt select scanpt",
165241 /* 275 */ "expr ::= RAISE LP IGNORE RP",
165242 /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP",
165243 /* 277 */ "raisetype ::= ROLLBACK",
165244 /* 278 */ "raisetype ::= ABORT",
165245 /* 279 */ "raisetype ::= FAIL",
165246 /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname",
165247 /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
165248 /* 282 */ "cmd ::= DETACH database_kw_opt expr",
165249 /* 283 */ "key_opt ::=",
165250 /* 284 */ "key_opt ::= KEY expr",
165251 /* 285 */ "cmd ::= REINDEX",
165252 /* 286 */ "cmd ::= REINDEX nm dbnm",
165253 /* 287 */ "cmd ::= ANALYZE",
165254 /* 288 */ "cmd ::= ANALYZE nm dbnm",
165255 /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
165256 /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
165257 /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
165258 /* 292 */ "add_column_fullname ::= fullname",
165259 /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
165260 /* 294 */ "cmd ::= create_vtab",
165261 /* 295 */ "cmd ::= create_vtab LP vtabarglist RP",
165262 /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
165263 /* 297 */ "vtabarg ::=",
165264 /* 298 */ "vtabargtoken ::= ANY",
165265 /* 299 */ "vtabargtoken ::= lp anylist RP",
165266 /* 300 */ "lp ::= LP",
165267 /* 301 */ "with ::= WITH wqlist",
165268 /* 302 */ "with ::= WITH RECURSIVE wqlist",
165269 /* 303 */ "wqas ::= AS",
165270 /* 304 */ "wqas ::= AS MATERIALIZED",
165271 /* 305 */ "wqas ::= AS NOT MATERIALIZED",
165272 /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
165273 /* 307 */ "wqlist ::= wqitem",
165274 /* 308 */ "wqlist ::= wqlist COMMA wqitem",
165275 /* 309 */ "windowdefn_list ::= windowdefn",
165276 /* 310 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
165277 /* 311 */ "windowdefn ::= nm AS LP window RP",
165278 /* 312 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
165279 /* 313 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
165280 /* 314 */ "window ::= ORDER BY sortlist frame_opt",
165281 /* 315 */ "window ::= nm ORDER BY sortlist frame_opt",
165282 /* 316 */ "window ::= frame_opt",
165283 /* 317 */ "window ::= nm frame_opt",
165284 /* 318 */ "frame_opt ::=",
165285 /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
165286 /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
165287 /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
165288 /* 322 */ "frame_bound_s ::= frame_bound",
165289 /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
165290 /* 324 */ "frame_bound_e ::= frame_bound",
165291 /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
165292 /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
165293 /* 327 */ "frame_bound ::= CURRENT ROW",
165294 /* 328 */ "frame_exclude_opt ::=",
165295 /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
165296 /* 330 */ "frame_exclude ::= NO OTHERS",
165297 /* 331 */ "frame_exclude ::= CURRENT ROW",
165298 /* 332 */ "frame_exclude ::= GROUP|TIES",
165299 /* 333 */ "window_clause ::= WINDOW windowdefn_list",
165300 /* 334 */ "filter_over ::= filter_clause over_clause",
165301 /* 335 */ "filter_over ::= over_clause",
165302 /* 336 */ "filter_over ::= filter_clause",
165303 /* 337 */ "over_clause ::= OVER LP window RP",
165304 /* 338 */ "over_clause ::= OVER nm",
165305 /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP",
165306 /* 340 */ "input ::= cmdlist",
165307 /* 341 */ "cmdlist ::= cmdlist ecmd",
165308 /* 342 */ "cmdlist ::= ecmd",
165309 /* 343 */ "ecmd ::= SEMI",
165310 /* 344 */ "ecmd ::= cmdx SEMI",
165311 /* 345 */ "ecmd ::= explain cmdx SEMI",
165312 /* 346 */ "trans_opt ::=",
165313 /* 347 */ "trans_opt ::= TRANSACTION",
165314 /* 348 */ "trans_opt ::= TRANSACTION nm",
165315 /* 349 */ "savepoint_opt ::= SAVEPOINT",
165316 /* 350 */ "savepoint_opt ::=",
165317 /* 351 */ "cmd ::= create_table create_table_args",
165318 /* 352 */ "table_option_set ::= table_option",
165319 /* 353 */ "columnlist ::= columnlist COMMA columnname carglist",
165320 /* 354 */ "columnlist ::= columnname carglist",
165321 /* 355 */ "nm ::= ID|INDEXED",
165322 /* 356 */ "nm ::= STRING",
165323 /* 357 */ "nm ::= JOIN_KW",
165324 /* 358 */ "typetoken ::= typename",
165325 /* 359 */ "typename ::= ID|STRING",
165326 /* 360 */ "signed ::= plus_num",
165327 /* 361 */ "signed ::= minus_num",
165328 /* 362 */ "carglist ::= carglist ccons",
165329 /* 363 */ "carglist ::=",
165330 /* 364 */ "ccons ::= NULL onconf",
165331 /* 365 */ "ccons ::= GENERATED ALWAYS AS generated",
165332 /* 366 */ "ccons ::= AS generated",
165333 /* 367 */ "conslist_opt ::= COMMA conslist",
165334 /* 368 */ "conslist ::= conslist tconscomma tcons",
165335 /* 369 */ "conslist ::= tcons",
165336 /* 370 */ "tconscomma ::=",
165337 /* 371 */ "defer_subclause_opt ::= defer_subclause",
165338 /* 372 */ "resolvetype ::= raisetype",
165339 /* 373 */ "selectnowith ::= oneselect",
165340 /* 374 */ "oneselect ::= values",
165341 /* 375 */ "sclp ::= selcollist COMMA",
165342 /* 376 */ "as ::= ID|STRING",
165343 /* 377 */ "indexed_opt ::= indexed_by",
165344 /* 378 */ "returning ::=",
165345 /* 379 */ "expr ::= term",
165346 /* 380 */ "likeop ::= LIKE_KW|MATCH",
165347 /* 381 */ "exprlist ::= nexprlist",
165348 /* 382 */ "nmnum ::= plus_num",
165349 /* 383 */ "nmnum ::= nm",
165350 /* 384 */ "nmnum ::= ON",
165351 /* 385 */ "nmnum ::= DELETE",
165352 /* 386 */ "nmnum ::= DEFAULT",
165353 /* 387 */ "plus_num ::= INTEGER|FLOAT",
165354 /* 388 */ "foreach_clause ::=",
165355 /* 389 */ "foreach_clause ::= FOR EACH ROW",
165356 /* 390 */ "trnm ::= nm",
165357 /* 391 */ "tridxby ::=",
165358 /* 392 */ "database_kw_opt ::= DATABASE",
165359 /* 393 */ "database_kw_opt ::=",
165360 /* 394 */ "kwcolumn_opt ::=",
165361 /* 395 */ "kwcolumn_opt ::= COLUMNKW",
165362 /* 396 */ "vtabarglist ::= vtabarg",
165363 /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
165364 /* 398 */ "vtabarg ::= vtabarg vtabargtoken",
165365 /* 399 */ "anylist ::=",
165366 /* 400 */ "anylist ::= anylist LP anylist RP",
165367 /* 401 */ "anylist ::= anylist ANY",
165368 /* 402 */ "with ::=",
 
 
165369 };
165370 #endif /* NDEBUG */
165371
165372
165373 #if YYSTACKDEPTH<=0
@@ -166079,204 +166310,206 @@
166079 217, /* (204) expr ::= expr likeop expr ESCAPE expr */
166080 217, /* (205) expr ::= expr ISNULL|NOTNULL */
166081 217, /* (206) expr ::= expr NOT NULL */
166082 217, /* (207) expr ::= expr IS expr */
166083 217, /* (208) expr ::= expr IS NOT expr */
166084 217, /* (209) expr ::= NOT expr */
166085 217, /* (210) expr ::= BITNOT expr */
166086 217, /* (211) expr ::= PLUS|MINUS expr */
166087 217, /* (212) expr ::= expr PTR expr */
166088 275, /* (213) between_op ::= BETWEEN */
166089 275, /* (214) between_op ::= NOT BETWEEN */
166090 217, /* (215) expr ::= expr between_op expr AND expr */
166091 276, /* (216) in_op ::= IN */
166092 276, /* (217) in_op ::= NOT IN */
166093 217, /* (218) expr ::= expr in_op LP exprlist RP */
166094 217, /* (219) expr ::= LP select RP */
166095 217, /* (220) expr ::= expr in_op LP select RP */
166096 217, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */
166097 217, /* (222) expr ::= EXISTS LP select RP */
166098 217, /* (223) expr ::= CASE case_operand case_exprlist case_else END */
166099 279, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166100 279, /* (225) case_exprlist ::= WHEN expr THEN expr */
166101 280, /* (226) case_else ::= ELSE expr */
166102 280, /* (227) case_else ::= */
166103 278, /* (228) case_operand ::= expr */
166104 278, /* (229) case_operand ::= */
166105 261, /* (230) exprlist ::= */
166106 253, /* (231) nexprlist ::= nexprlist COMMA expr */
166107 253, /* (232) nexprlist ::= expr */
166108 277, /* (233) paren_exprlist ::= */
166109 277, /* (234) paren_exprlist ::= LP exprlist RP */
166110 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166111 281, /* (236) uniqueflag ::= UNIQUE */
166112 281, /* (237) uniqueflag ::= */
166113 221, /* (238) eidlist_opt ::= */
166114 221, /* (239) eidlist_opt ::= LP eidlist RP */
166115 232, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */
166116 232, /* (241) eidlist ::= nm collate sortorder */
166117 282, /* (242) collate ::= */
166118 282, /* (243) collate ::= COLLATE ID|STRING */
166119 190, /* (244) cmd ::= DROP INDEX ifexists fullname */
166120 190, /* (245) cmd ::= VACUUM vinto */
166121 190, /* (246) cmd ::= VACUUM nm vinto */
166122 283, /* (247) vinto ::= INTO expr */
166123 283, /* (248) vinto ::= */
166124 190, /* (249) cmd ::= PRAGMA nm dbnm */
166125 190, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */
166126 190, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166127 190, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */
166128 190, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166129 211, /* (254) plus_num ::= PLUS INTEGER|FLOAT */
166130 212, /* (255) minus_num ::= MINUS INTEGER|FLOAT */
166131 190, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166132 285, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166133 287, /* (258) trigger_time ::= BEFORE|AFTER */
166134 287, /* (259) trigger_time ::= INSTEAD OF */
166135 287, /* (260) trigger_time ::= */
166136 288, /* (261) trigger_event ::= DELETE|INSERT */
166137 288, /* (262) trigger_event ::= UPDATE */
166138 288, /* (263) trigger_event ::= UPDATE OF idlist */
166139 290, /* (264) when_clause ::= */
166140 290, /* (265) when_clause ::= WHEN expr */
166141 286, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166142 286, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */
166143 292, /* (268) trnm ::= nm DOT nm */
166144 293, /* (269) tridxby ::= INDEXED BY nm */
166145 293, /* (270) tridxby ::= NOT INDEXED */
166146 291, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166147 291, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166148 291, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166149 291, /* (274) trigger_cmd ::= scanpt select scanpt */
166150 217, /* (275) expr ::= RAISE LP IGNORE RP */
166151 217, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */
166152 236, /* (277) raisetype ::= ROLLBACK */
166153 236, /* (278) raisetype ::= ABORT */
166154 236, /* (279) raisetype ::= FAIL */
166155 190, /* (280) cmd ::= DROP TRIGGER ifexists fullname */
166156 190, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166157 190, /* (282) cmd ::= DETACH database_kw_opt expr */
166158 295, /* (283) key_opt ::= */
166159 295, /* (284) key_opt ::= KEY expr */
166160 190, /* (285) cmd ::= REINDEX */
166161 190, /* (286) cmd ::= REINDEX nm dbnm */
166162 190, /* (287) cmd ::= ANALYZE */
166163 190, /* (288) cmd ::= ANALYZE nm dbnm */
166164 190, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */
166165 190, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166166 190, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166167 296, /* (292) add_column_fullname ::= fullname */
166168 190, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166169 190, /* (294) cmd ::= create_vtab */
166170 190, /* (295) cmd ::= create_vtab LP vtabarglist RP */
166171 298, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166172 300, /* (297) vtabarg ::= */
166173 301, /* (298) vtabargtoken ::= ANY */
166174 301, /* (299) vtabargtoken ::= lp anylist RP */
166175 302, /* (300) lp ::= LP */
166176 266, /* (301) with ::= WITH wqlist */
166177 266, /* (302) with ::= WITH RECURSIVE wqlist */
166178 305, /* (303) wqas ::= AS */
166179 305, /* (304) wqas ::= AS MATERIALIZED */
166180 305, /* (305) wqas ::= AS NOT MATERIALIZED */
166181 304, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */
166182 241, /* (307) wqlist ::= wqitem */
166183 241, /* (308) wqlist ::= wqlist COMMA wqitem */
166184 306, /* (309) windowdefn_list ::= windowdefn */
166185 306, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166186 307, /* (311) windowdefn ::= nm AS LP window RP */
166187 308, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166188 308, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166189 308, /* (314) window ::= ORDER BY sortlist frame_opt */
166190 308, /* (315) window ::= nm ORDER BY sortlist frame_opt */
166191 308, /* (316) window ::= frame_opt */
166192 308, /* (317) window ::= nm frame_opt */
166193 309, /* (318) frame_opt ::= */
166194 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166195 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166196 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
166197 315, /* (322) frame_bound_s ::= frame_bound */
166198 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
166199 316, /* (324) frame_bound_e ::= frame_bound */
166200 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
166201 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
166202 314, /* (327) frame_bound ::= CURRENT ROW */
166203 317, /* (328) frame_exclude_opt ::= */
166204 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
166205 318, /* (330) frame_exclude ::= NO OTHERS */
166206 318, /* (331) frame_exclude ::= CURRENT ROW */
166207 318, /* (332) frame_exclude ::= GROUP|TIES */
166208 251, /* (333) window_clause ::= WINDOW windowdefn_list */
166209 273, /* (334) filter_over ::= filter_clause over_clause */
166210 273, /* (335) filter_over ::= over_clause */
166211 273, /* (336) filter_over ::= filter_clause */
166212 312, /* (337) over_clause ::= OVER LP window RP */
166213 312, /* (338) over_clause ::= OVER nm */
166214 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */
166215 185, /* (340) input ::= cmdlist */
166216 186, /* (341) cmdlist ::= cmdlist ecmd */
166217 186, /* (342) cmdlist ::= ecmd */
166218 187, /* (343) ecmd ::= SEMI */
166219 187, /* (344) ecmd ::= cmdx SEMI */
166220 187, /* (345) ecmd ::= explain cmdx SEMI */
166221 192, /* (346) trans_opt ::= */
166222 192, /* (347) trans_opt ::= TRANSACTION */
166223 192, /* (348) trans_opt ::= TRANSACTION nm */
166224 194, /* (349) savepoint_opt ::= SAVEPOINT */
166225 194, /* (350) savepoint_opt ::= */
166226 190, /* (351) cmd ::= create_table create_table_args */
166227 203, /* (352) table_option_set ::= table_option */
166228 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */
166229 201, /* (354) columnlist ::= columnname carglist */
166230 193, /* (355) nm ::= ID|INDEXED */
166231 193, /* (356) nm ::= STRING */
166232 193, /* (357) nm ::= JOIN_KW */
166233 208, /* (358) typetoken ::= typename */
166234 209, /* (359) typename ::= ID|STRING */
166235 210, /* (360) signed ::= plus_num */
166236 210, /* (361) signed ::= minus_num */
166237 207, /* (362) carglist ::= carglist ccons */
166238 207, /* (363) carglist ::= */
166239 215, /* (364) ccons ::= NULL onconf */
166240 215, /* (365) ccons ::= GENERATED ALWAYS AS generated */
166241 215, /* (366) ccons ::= AS generated */
166242 202, /* (367) conslist_opt ::= COMMA conslist */
166243 228, /* (368) conslist ::= conslist tconscomma tcons */
166244 228, /* (369) conslist ::= tcons */
166245 229, /* (370) tconscomma ::= */
166246 233, /* (371) defer_subclause_opt ::= defer_subclause */
166247 235, /* (372) resolvetype ::= raisetype */
166248 239, /* (373) selectnowith ::= oneselect */
166249 240, /* (374) oneselect ::= values */
166250 254, /* (375) sclp ::= selcollist COMMA */
166251 255, /* (376) as ::= ID|STRING */
166252 264, /* (377) indexed_opt ::= indexed_by */
166253 272, /* (378) returning ::= */
166254 217, /* (379) expr ::= term */
166255 274, /* (380) likeop ::= LIKE_KW|MATCH */
166256 261, /* (381) exprlist ::= nexprlist */
166257 284, /* (382) nmnum ::= plus_num */
166258 284, /* (383) nmnum ::= nm */
166259 284, /* (384) nmnum ::= ON */
166260 284, /* (385) nmnum ::= DELETE */
166261 284, /* (386) nmnum ::= DEFAULT */
166262 211, /* (387) plus_num ::= INTEGER|FLOAT */
166263 289, /* (388) foreach_clause ::= */
166264 289, /* (389) foreach_clause ::= FOR EACH ROW */
166265 292, /* (390) trnm ::= nm */
166266 293, /* (391) tridxby ::= */
166267 294, /* (392) database_kw_opt ::= DATABASE */
166268 294, /* (393) database_kw_opt ::= */
166269 297, /* (394) kwcolumn_opt ::= */
166270 297, /* (395) kwcolumn_opt ::= COLUMNKW */
166271 299, /* (396) vtabarglist ::= vtabarg */
166272 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
166273 300, /* (398) vtabarg ::= vtabarg vtabargtoken */
166274 303, /* (399) anylist ::= */
166275 303, /* (400) anylist ::= anylist LP anylist RP */
166276 303, /* (401) anylist ::= anylist ANY */
166277 266, /* (402) with ::= */
 
 
166278 };
166279
166280 /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
166281 ** of symbols on the right-hand side of that rule. */
166282 static const signed char yyRuleInfoNRhs[] = {
@@ -166487,204 +166720,206 @@
166487 -5, /* (204) expr ::= expr likeop expr ESCAPE expr */
166488 -2, /* (205) expr ::= expr ISNULL|NOTNULL */
166489 -3, /* (206) expr ::= expr NOT NULL */
166490 -3, /* (207) expr ::= expr IS expr */
166491 -4, /* (208) expr ::= expr IS NOT expr */
166492 -2, /* (209) expr ::= NOT expr */
166493 -2, /* (210) expr ::= BITNOT expr */
166494 -2, /* (211) expr ::= PLUS|MINUS expr */
166495 -3, /* (212) expr ::= expr PTR expr */
166496 -1, /* (213) between_op ::= BETWEEN */
166497 -2, /* (214) between_op ::= NOT BETWEEN */
166498 -5, /* (215) expr ::= expr between_op expr AND expr */
166499 -1, /* (216) in_op ::= IN */
166500 -2, /* (217) in_op ::= NOT IN */
166501 -5, /* (218) expr ::= expr in_op LP exprlist RP */
166502 -3, /* (219) expr ::= LP select RP */
166503 -5, /* (220) expr ::= expr in_op LP select RP */
166504 -5, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */
166505 -4, /* (222) expr ::= EXISTS LP select RP */
166506 -5, /* (223) expr ::= CASE case_operand case_exprlist case_else END */
166507 -5, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166508 -4, /* (225) case_exprlist ::= WHEN expr THEN expr */
166509 -2, /* (226) case_else ::= ELSE expr */
166510 0, /* (227) case_else ::= */
166511 -1, /* (228) case_operand ::= expr */
166512 0, /* (229) case_operand ::= */
166513 0, /* (230) exprlist ::= */
166514 -3, /* (231) nexprlist ::= nexprlist COMMA expr */
166515 -1, /* (232) nexprlist ::= expr */
166516 0, /* (233) paren_exprlist ::= */
166517 -3, /* (234) paren_exprlist ::= LP exprlist RP */
166518 -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166519 -1, /* (236) uniqueflag ::= UNIQUE */
166520 0, /* (237) uniqueflag ::= */
166521 0, /* (238) eidlist_opt ::= */
166522 -3, /* (239) eidlist_opt ::= LP eidlist RP */
166523 -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */
166524 -3, /* (241) eidlist ::= nm collate sortorder */
166525 0, /* (242) collate ::= */
166526 -2, /* (243) collate ::= COLLATE ID|STRING */
166527 -4, /* (244) cmd ::= DROP INDEX ifexists fullname */
166528 -2, /* (245) cmd ::= VACUUM vinto */
166529 -3, /* (246) cmd ::= VACUUM nm vinto */
166530 -2, /* (247) vinto ::= INTO expr */
166531 0, /* (248) vinto ::= */
166532 -3, /* (249) cmd ::= PRAGMA nm dbnm */
166533 -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */
166534 -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166535 -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */
166536 -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166537 -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */
166538 -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */
166539 -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166540 -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166541 -1, /* (258) trigger_time ::= BEFORE|AFTER */
166542 -2, /* (259) trigger_time ::= INSTEAD OF */
166543 0, /* (260) trigger_time ::= */
166544 -1, /* (261) trigger_event ::= DELETE|INSERT */
166545 -1, /* (262) trigger_event ::= UPDATE */
166546 -3, /* (263) trigger_event ::= UPDATE OF idlist */
166547 0, /* (264) when_clause ::= */
166548 -2, /* (265) when_clause ::= WHEN expr */
166549 -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166550 -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */
166551 -3, /* (268) trnm ::= nm DOT nm */
166552 -3, /* (269) tridxby ::= INDEXED BY nm */
166553 -2, /* (270) tridxby ::= NOT INDEXED */
166554 -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166555 -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166556 -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166557 -3, /* (274) trigger_cmd ::= scanpt select scanpt */
166558 -4, /* (275) expr ::= RAISE LP IGNORE RP */
166559 -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */
166560 -1, /* (277) raisetype ::= ROLLBACK */
166561 -1, /* (278) raisetype ::= ABORT */
166562 -1, /* (279) raisetype ::= FAIL */
166563 -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */
166564 -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166565 -3, /* (282) cmd ::= DETACH database_kw_opt expr */
166566 0, /* (283) key_opt ::= */
166567 -2, /* (284) key_opt ::= KEY expr */
166568 -1, /* (285) cmd ::= REINDEX */
166569 -3, /* (286) cmd ::= REINDEX nm dbnm */
166570 -1, /* (287) cmd ::= ANALYZE */
166571 -3, /* (288) cmd ::= ANALYZE nm dbnm */
166572 -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */
166573 -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166574 -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166575 -1, /* (292) add_column_fullname ::= fullname */
166576 -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166577 -1, /* (294) cmd ::= create_vtab */
166578 -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */
166579 -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166580 0, /* (297) vtabarg ::= */
166581 -1, /* (298) vtabargtoken ::= ANY */
166582 -3, /* (299) vtabargtoken ::= lp anylist RP */
166583 -1, /* (300) lp ::= LP */
166584 -2, /* (301) with ::= WITH wqlist */
166585 -3, /* (302) with ::= WITH RECURSIVE wqlist */
166586 -1, /* (303) wqas ::= AS */
166587 -2, /* (304) wqas ::= AS MATERIALIZED */
166588 -3, /* (305) wqas ::= AS NOT MATERIALIZED */
166589 -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */
166590 -1, /* (307) wqlist ::= wqitem */
166591 -3, /* (308) wqlist ::= wqlist COMMA wqitem */
166592 -1, /* (309) windowdefn_list ::= windowdefn */
166593 -3, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166594 -5, /* (311) windowdefn ::= nm AS LP window RP */
166595 -5, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166596 -6, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166597 -4, /* (314) window ::= ORDER BY sortlist frame_opt */
166598 -5, /* (315) window ::= nm ORDER BY sortlist frame_opt */
166599 -1, /* (316) window ::= frame_opt */
166600 -2, /* (317) window ::= nm frame_opt */
166601 0, /* (318) frame_opt ::= */
166602 -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166603 -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166604 -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
166605 -1, /* (322) frame_bound_s ::= frame_bound */
166606 -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
166607 -1, /* (324) frame_bound_e ::= frame_bound */
166608 -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
166609 -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
166610 -2, /* (327) frame_bound ::= CURRENT ROW */
166611 0, /* (328) frame_exclude_opt ::= */
166612 -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
166613 -2, /* (330) frame_exclude ::= NO OTHERS */
166614 -2, /* (331) frame_exclude ::= CURRENT ROW */
166615 -1, /* (332) frame_exclude ::= GROUP|TIES */
166616 -2, /* (333) window_clause ::= WINDOW windowdefn_list */
166617 -2, /* (334) filter_over ::= filter_clause over_clause */
166618 -1, /* (335) filter_over ::= over_clause */
166619 -1, /* (336) filter_over ::= filter_clause */
166620 -4, /* (337) over_clause ::= OVER LP window RP */
166621 -2, /* (338) over_clause ::= OVER nm */
166622 -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */
166623 -1, /* (340) input ::= cmdlist */
166624 -2, /* (341) cmdlist ::= cmdlist ecmd */
166625 -1, /* (342) cmdlist ::= ecmd */
166626 -1, /* (343) ecmd ::= SEMI */
166627 -2, /* (344) ecmd ::= cmdx SEMI */
166628 -3, /* (345) ecmd ::= explain cmdx SEMI */
166629 0, /* (346) trans_opt ::= */
166630 -1, /* (347) trans_opt ::= TRANSACTION */
166631 -2, /* (348) trans_opt ::= TRANSACTION nm */
166632 -1, /* (349) savepoint_opt ::= SAVEPOINT */
166633 0, /* (350) savepoint_opt ::= */
166634 -2, /* (351) cmd ::= create_table create_table_args */
166635 -1, /* (352) table_option_set ::= table_option */
166636 -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */
166637 -2, /* (354) columnlist ::= columnname carglist */
166638 -1, /* (355) nm ::= ID|INDEXED */
166639 -1, /* (356) nm ::= STRING */
166640 -1, /* (357) nm ::= JOIN_KW */
166641 -1, /* (358) typetoken ::= typename */
166642 -1, /* (359) typename ::= ID|STRING */
166643 -1, /* (360) signed ::= plus_num */
166644 -1, /* (361) signed ::= minus_num */
166645 -2, /* (362) carglist ::= carglist ccons */
166646 0, /* (363) carglist ::= */
166647 -2, /* (364) ccons ::= NULL onconf */
166648 -4, /* (365) ccons ::= GENERATED ALWAYS AS generated */
166649 -2, /* (366) ccons ::= AS generated */
166650 -2, /* (367) conslist_opt ::= COMMA conslist */
166651 -3, /* (368) conslist ::= conslist tconscomma tcons */
166652 -1, /* (369) conslist ::= tcons */
166653 0, /* (370) tconscomma ::= */
166654 -1, /* (371) defer_subclause_opt ::= defer_subclause */
166655 -1, /* (372) resolvetype ::= raisetype */
166656 -1, /* (373) selectnowith ::= oneselect */
166657 -1, /* (374) oneselect ::= values */
166658 -2, /* (375) sclp ::= selcollist COMMA */
166659 -1, /* (376) as ::= ID|STRING */
166660 -1, /* (377) indexed_opt ::= indexed_by */
166661 0, /* (378) returning ::= */
166662 -1, /* (379) expr ::= term */
166663 -1, /* (380) likeop ::= LIKE_KW|MATCH */
166664 -1, /* (381) exprlist ::= nexprlist */
166665 -1, /* (382) nmnum ::= plus_num */
166666 -1, /* (383) nmnum ::= nm */
166667 -1, /* (384) nmnum ::= ON */
166668 -1, /* (385) nmnum ::= DELETE */
166669 -1, /* (386) nmnum ::= DEFAULT */
166670 -1, /* (387) plus_num ::= INTEGER|FLOAT */
166671 0, /* (388) foreach_clause ::= */
166672 -3, /* (389) foreach_clause ::= FOR EACH ROW */
166673 -1, /* (390) trnm ::= nm */
166674 0, /* (391) tridxby ::= */
166675 -1, /* (392) database_kw_opt ::= DATABASE */
166676 0, /* (393) database_kw_opt ::= */
166677 0, /* (394) kwcolumn_opt ::= */
166678 -1, /* (395) kwcolumn_opt ::= COLUMNKW */
166679 -1, /* (396) vtabarglist ::= vtabarg */
166680 -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
166681 -2, /* (398) vtabarg ::= vtabarg vtabargtoken */
166682 0, /* (399) anylist ::= */
166683 -4, /* (400) anylist ::= anylist LP anylist RP */
166684 -2, /* (401) anylist ::= anylist ANY */
166685 0, /* (402) with ::= */
 
 
166686 };
166687
166688 static void yy_accept(yyParser*); /* Forward Declaration */
166689
166690 /*
@@ -166740,11 +166975,11 @@
166740 {yymsp[1].minor.yy394 = TK_DEFERRED;}
166741 break;
166742 case 5: /* transtype ::= DEFERRED */
166743 case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
166744 case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
166745 case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321);
166746 {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/}
166747 break;
166748 case 8: /* cmd ::= COMMIT|END trans_opt */
166749 case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
166750 {sqlite3EndTransaction(pParse,yymsp[-1].major);}
@@ -166777,11 +167012,11 @@
166777 case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
166778 case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
166779 case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
166780 case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
166781 case 98: /* distinct ::= */ yytestcase(yyruleno==98);
166782 case 242: /* collate ::= */ yytestcase(yyruleno==242);
166783 {yymsp[1].minor.yy394 = 0;}
166784 break;
166785 case 16: /* ifnotexists ::= IF NOT EXISTS */
166786 {yymsp[-2].minor.yy394 = 1;}
166787 break;
@@ -166961,13 +167196,13 @@
166961 case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171);
166962 {yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;}
166963 break;
166964 case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
166965 case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
166966 case 214: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==214);
166967 case 217: /* in_op ::= NOT IN */ yytestcase(yyruleno==217);
166968 case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243);
166969 {yymsp[-1].minor.yy394 = 1;}
166970 break;
166971 case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
166972 {yymsp[-1].minor.yy394 = 0;}
166973 break;
@@ -167113,13 +167348,13 @@
167113 {yymsp[0].minor.yy394 = SF_All;}
167114 break;
167115 case 99: /* sclp ::= */
167116 case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132);
167117 case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142);
167118 case 230: /* exprlist ::= */ yytestcase(yyruleno==230);
167119 case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233);
167120 case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238);
167121 {yymsp[1].minor.yy322 = 0;}
167122 break;
167123 case 100: /* selcollist ::= sclp scanpt expr scanpt as */
167124 {
167125 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
@@ -167141,12 +167376,12 @@
167141 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
167142 }
167143 break;
167144 case 103: /* as ::= AS nm */
167145 case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115);
167146 case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
167147 case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255);
167148 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
167149 break;
167150 case 105: /* from ::= */
167151 case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108);
167152 {yymsp[1].minor.yy131 = 0;}
@@ -167314,20 +167549,20 @@
167314 break;
167315 case 144: /* having_opt ::= */
167316 case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
167317 case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
167318 case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
167319 case 227: /* case_else ::= */ yytestcase(yyruleno==227);
167320 case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
167321 case 248: /* vinto ::= */ yytestcase(yyruleno==248);
167322 {yymsp[1].minor.yy528 = 0;}
167323 break;
167324 case 145: /* having_opt ::= HAVING expr */
167325 case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
167326 case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
167327 case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226);
167328 case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
167329 {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
167330 break;
167331 case 147: /* limit_opt ::= LIMIT expr */
167332 {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
167333 break;
@@ -167351,11 +167586,22 @@
167351 break;
167352 case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
167353 {
167354 sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0);
167355 sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list");
167356 yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, yymsp[-1].minor.yy131);
 
 
 
 
 
 
 
 
 
 
 
167357 sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0);
167358 }
167359 break;
167360 case 158: /* setlist ::= setlist COMMA nm EQ expr */
167361 {
@@ -167597,33 +167843,45 @@
167597 {
167598 yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528);
167599 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL);
167600 }
167601 break;
167602 case 209: /* expr ::= NOT expr */
167603 case 210: /* expr ::= BITNOT expr */ yytestcase(yyruleno==210);
 
 
 
 
 
 
 
 
 
 
 
 
167604 {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/}
167605 break;
167606 case 211: /* expr ::= PLUS|MINUS expr */
167607 {
167608 yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0);
167609 /*A-overwrites-B*/
167610 }
167611 break;
167612 case 212: /* expr ::= expr PTR expr */
167613 {
167614 ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528);
167615 pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528);
167616 yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
167617 }
167618 yymsp[-2].minor.yy528 = yylhsminor.yy528;
167619 break;
167620 case 213: /* between_op ::= BETWEEN */
167621 case 216: /* in_op ::= IN */ yytestcase(yyruleno==216);
167622 {yymsp[0].minor.yy394 = 0;}
167623 break;
167624 case 215: /* expr ::= expr between_op expr AND expr */
167625 {
167626 ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
167627 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528);
167628 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0);
167629 if( yymsp[-4].minor.yy528 ){
@@ -167632,11 +167890,11 @@
167632 sqlite3ExprListDelete(pParse->db, pList);
167633 }
167634 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167635 }
167636 break;
167637 case 218: /* expr ::= expr in_op LP exprlist RP */
167638 {
167639 if( yymsp[-1].minor.yy322==0 ){
167640 /* Expressions of the form
167641 **
167642 ** expr1 IN ()
@@ -167644,11 +167902,12 @@
167644 **
167645 ** simplify to constants 0 (false) and 1 (true), respectively,
167646 ** regardless of the value of expr1.
167647 */
167648 sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528);
167649 yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy394 ? "1" : "0");
 
167650 }else{
167651 Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
167652 if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){
167653 yymsp[-1].minor.yy322->a[0].pExpr = 0;
167654 sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
@@ -167672,41 +167931,41 @@
167672 }
167673 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167674 }
167675 }
167676 break;
167677 case 219: /* expr ::= LP select RP */
167678 {
167679 yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
167680 sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47);
167681 }
167682 break;
167683 case 220: /* expr ::= expr in_op LP select RP */
167684 {
167685 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
167686 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47);
167687 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167688 }
167689 break;
167690 case 221: /* expr ::= expr in_op nm dbnm paren_exprlist */
167691 {
167692 SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
167693 Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
167694 if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322);
167695 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
167696 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect);
167697 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167698 }
167699 break;
167700 case 222: /* expr ::= EXISTS LP select RP */
167701 {
167702 Expr *p;
167703 p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
167704 sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47);
167705 }
167706 break;
167707 case 223: /* expr ::= CASE case_operand case_exprlist case_else END */
167708 {
167709 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0);
167710 if( yymsp[-4].minor.yy528 ){
167711 yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322;
167712 sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528);
@@ -167714,406 +167973,406 @@
167714 sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
167715 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
167716 }
167717 }
167718 break;
167719 case 224: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
167720 {
167721 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
167722 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528);
167723 }
167724 break;
167725 case 225: /* case_exprlist ::= WHEN expr THEN expr */
167726 {
167727 yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
167728 yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528);
167729 }
167730 break;
167731 case 228: /* case_operand ::= expr */
167732 {yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/}
167733 break;
167734 case 231: /* nexprlist ::= nexprlist COMMA expr */
167735 {yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);}
167736 break;
167737 case 232: /* nexprlist ::= expr */
167738 {yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/}
167739 break;
167740 case 234: /* paren_exprlist ::= LP exprlist RP */
167741 case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239);
167742 {yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
167743 break;
167744 case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
167745 {
167746 sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
167747 sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394,
167748 &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF);
167749 if( IN_RENAME_OBJECT && pParse->pNewIndex ){
167750 sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
167751 }
167752 }
167753 break;
167754 case 236: /* uniqueflag ::= UNIQUE */
167755 case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278);
167756 {yymsp[0].minor.yy394 = OE_Abort;}
167757 break;
167758 case 237: /* uniqueflag ::= */
167759 {yymsp[1].minor.yy394 = OE_None;}
167760 break;
167761 case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */
167762 {
167763 yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394);
167764 }
167765 break;
167766 case 241: /* eidlist ::= nm collate sortorder */
167767 {
167768 yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/
167769 }
167770 break;
167771 case 244: /* cmd ::= DROP INDEX ifexists fullname */
167772 {sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);}
167773 break;
167774 case 245: /* cmd ::= VACUUM vinto */
167775 {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);}
167776 break;
167777 case 246: /* cmd ::= VACUUM nm vinto */
167778 {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);}
167779 break;
167780 case 249: /* cmd ::= PRAGMA nm dbnm */
167781 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
167782 break;
167783 case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
167784 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
167785 break;
167786 case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
167787 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
167788 break;
167789 case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
167790 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
167791 break;
167792 case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
167793 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
167794 break;
167795 case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
167796 {
167797 Token all;
167798 all.z = yymsp[-3].minor.yy0.z;
167799 all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
167800 sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all);
167801 }
167802 break;
167803 case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
167804 {
167805 sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394);
167806 yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
167807 }
167808 break;
167809 case 258: /* trigger_time ::= BEFORE|AFTER */
167810 { yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ }
167811 break;
167812 case 259: /* trigger_time ::= INSTEAD OF */
167813 { yymsp[-1].minor.yy394 = TK_INSTEAD;}
167814 break;
167815 case 260: /* trigger_time ::= */
167816 { yymsp[1].minor.yy394 = TK_BEFORE; }
167817 break;
167818 case 261: /* trigger_event ::= DELETE|INSERT */
167819 case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262);
167820 {yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;}
167821 break;
167822 case 263: /* trigger_event ::= UPDATE OF idlist */
167823 {yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;}
167824 break;
167825 case 264: /* when_clause ::= */
167826 case 283: /* key_opt ::= */ yytestcase(yyruleno==283);
167827 { yymsp[1].minor.yy528 = 0; }
167828 break;
167829 case 265: /* when_clause ::= WHEN expr */
167830 case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284);
167831 { yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; }
167832 break;
167833 case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
167834 {
167835 assert( yymsp[-2].minor.yy33!=0 );
167836 yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33;
167837 yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33;
167838 }
167839 break;
167840 case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */
167841 {
167842 assert( yymsp[-1].minor.yy33!=0 );
167843 yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33;
167844 }
167845 break;
167846 case 268: /* trnm ::= nm DOT nm */
167847 {
167848 yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
167849 sqlite3ErrorMsg(pParse,
167850 "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
167851 "statements within triggers");
167852 }
167853 break;
167854 case 269: /* tridxby ::= INDEXED BY nm */
167855 {
167856 sqlite3ErrorMsg(pParse,
167857 "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
167858 "within triggers");
167859 }
167860 break;
167861 case 270: /* tridxby ::= NOT INDEXED */
167862 {
167863 sqlite3ErrorMsg(pParse,
167864 "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
167865 "within triggers");
167866 }
167867 break;
167868 case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
167869 {yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);}
167870 yymsp[-8].minor.yy33 = yylhsminor.yy33;
167871 break;
167872 case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
167873 {
167874 yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/
167875 }
167876 yymsp[-7].minor.yy33 = yylhsminor.yy33;
167877 break;
167878 case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
167879 {yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);}
167880 yymsp[-5].minor.yy33 = yylhsminor.yy33;
167881 break;
167882 case 274: /* trigger_cmd ::= scanpt select scanpt */
167883 {yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/}
167884 yymsp[-2].minor.yy33 = yylhsminor.yy33;
167885 break;
167886 case 275: /* expr ::= RAISE LP IGNORE RP */
167887 {
167888 yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
167889 if( yymsp[-3].minor.yy528 ){
167890 yymsp[-3].minor.yy528->affExpr = OE_Ignore;
167891 }
167892 }
167893 break;
167894 case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */
167895 {
167896 yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
167897 if( yymsp[-5].minor.yy528 ) {
167898 yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394;
167899 }
167900 }
167901 break;
167902 case 277: /* raisetype ::= ROLLBACK */
167903 {yymsp[0].minor.yy394 = OE_Rollback;}
167904 break;
167905 case 279: /* raisetype ::= FAIL */
167906 {yymsp[0].minor.yy394 = OE_Fail;}
167907 break;
167908 case 280: /* cmd ::= DROP TRIGGER ifexists fullname */
167909 {
167910 sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394);
167911 }
167912 break;
167913 case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
167914 {
167915 sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528);
167916 }
167917 break;
167918 case 282: /* cmd ::= DETACH database_kw_opt expr */
167919 {
167920 sqlite3Detach(pParse, yymsp[0].minor.yy528);
167921 }
167922 break;
167923 case 285: /* cmd ::= REINDEX */
167924 {sqlite3Reindex(pParse, 0, 0);}
167925 break;
167926 case 286: /* cmd ::= REINDEX nm dbnm */
167927 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
167928 break;
167929 case 287: /* cmd ::= ANALYZE */
167930 {sqlite3Analyze(pParse, 0, 0);}
167931 break;
167932 case 288: /* cmd ::= ANALYZE nm dbnm */
167933 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
167934 break;
167935 case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
167936 {
167937 sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0);
167938 }
167939 break;
167940 case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
167941 {
167942 yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
167943 sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
167944 }
167945 break;
167946 case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
167947 {
167948 sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0);
167949 }
167950 break;
167951 case 292: /* add_column_fullname ::= fullname */
167952 {
167953 disableLookaside(pParse);
167954 sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131);
167955 }
167956 break;
167957 case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
167958 {
167959 sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
167960 }
167961 break;
167962 case 294: /* cmd ::= create_vtab */
167963 {sqlite3VtabFinishParse(pParse,0);}
167964 break;
167965 case 295: /* cmd ::= create_vtab LP vtabarglist RP */
167966 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
167967 break;
167968 case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
167969 {
167970 sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394);
167971 }
167972 break;
167973 case 297: /* vtabarg ::= */
167974 {sqlite3VtabArgInit(pParse);}
167975 break;
167976 case 298: /* vtabargtoken ::= ANY */
167977 case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299);
167978 case 300: /* lp ::= LP */ yytestcase(yyruleno==300);
167979 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
167980 break;
167981 case 301: /* with ::= WITH wqlist */
167982 case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302);
167983 { sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); }
167984 break;
167985 case 303: /* wqas ::= AS */
167986 {yymsp[0].minor.yy516 = M10d_Any;}
167987 break;
167988 case 304: /* wqas ::= AS MATERIALIZED */
167989 {yymsp[-1].minor.yy516 = M10d_Yes;}
167990 break;
167991 case 305: /* wqas ::= AS NOT MATERIALIZED */
167992 {yymsp[-2].minor.yy516 = M10d_No;}
167993 break;
167994 case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */
167995 {
167996 yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/
167997 }
167998 break;
167999 case 307: /* wqlist ::= wqitem */
168000 {
168001 yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/
168002 }
168003 break;
168004 case 308: /* wqlist ::= wqlist COMMA wqitem */
168005 {
168006 yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385);
168007 }
168008 break;
168009 case 309: /* windowdefn_list ::= windowdefn */
168010 { yylhsminor.yy41 = yymsp[0].minor.yy41; }
168011 yymsp[0].minor.yy41 = yylhsminor.yy41;
168012 break;
168013 case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
168014 {
168015 assert( yymsp[0].minor.yy41!=0 );
168016 sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41);
168017 yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41;
168018 yylhsminor.yy41 = yymsp[0].minor.yy41;
168019 }
168020 yymsp[-2].minor.yy41 = yylhsminor.yy41;
168021 break;
168022 case 311: /* windowdefn ::= nm AS LP window RP */
168023 {
168024 if( ALWAYS(yymsp[-1].minor.yy41) ){
168025 yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
168026 }
168027 yylhsminor.yy41 = yymsp[-1].minor.yy41;
168028 }
168029 yymsp[-4].minor.yy41 = yylhsminor.yy41;
168030 break;
168031 case 312: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
168032 {
168033 yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0);
168034 }
168035 break;
168036 case 313: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
168037 {
168038 yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0);
168039 }
168040 yymsp[-5].minor.yy41 = yylhsminor.yy41;
168041 break;
168042 case 314: /* window ::= ORDER BY sortlist frame_opt */
168043 {
168044 yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0);
168045 }
168046 break;
168047 case 315: /* window ::= nm ORDER BY sortlist frame_opt */
168048 {
168049 yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
168050 }
168051 yymsp[-4].minor.yy41 = yylhsminor.yy41;
168052 break;
168053 case 316: /* window ::= frame_opt */
168054 case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335);
168055 {
168056 yylhsminor.yy41 = yymsp[0].minor.yy41;
168057 }
168058 yymsp[0].minor.yy41 = yylhsminor.yy41;
168059 break;
168060 case 317: /* window ::= nm frame_opt */
168061 {
168062 yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0);
168063 }
168064 yymsp[-1].minor.yy41 = yylhsminor.yy41;
168065 break;
168066 case 318: /* frame_opt ::= */
168067 {
168068 yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
168069 }
168070 break;
168071 case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
168072 {
168073 yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516);
168074 }
168075 yymsp[-2].minor.yy41 = yylhsminor.yy41;
168076 break;
168077 case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
168078 {
168079 yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516);
168080 }
168081 yymsp[-5].minor.yy41 = yylhsminor.yy41;
168082 break;
168083 case 322: /* frame_bound_s ::= frame_bound */
168084 case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324);
168085 {yylhsminor.yy595 = yymsp[0].minor.yy595;}
168086 yymsp[0].minor.yy595 = yylhsminor.yy595;
168087 break;
168088 case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */
168089 case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325);
168090 case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327);
168091 {yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;}
168092 yymsp[-1].minor.yy595 = yylhsminor.yy595;
168093 break;
168094 case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */
168095 {yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;}
168096 yymsp[-1].minor.yy595 = yylhsminor.yy595;
168097 break;
168098 case 328: /* frame_exclude_opt ::= */
168099 {yymsp[1].minor.yy516 = 0;}
168100 break;
168101 case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
168102 {yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;}
168103 break;
168104 case 330: /* frame_exclude ::= NO OTHERS */
168105 case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331);
168106 {yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/}
168107 break;
168108 case 332: /* frame_exclude ::= GROUP|TIES */
168109 {yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/}
168110 break;
168111 case 333: /* window_clause ::= WINDOW windowdefn_list */
168112 { yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; }
168113 break;
168114 case 334: /* filter_over ::= filter_clause over_clause */
168115 {
168116 if( yymsp[0].minor.yy41 ){
168117 yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528;
168118 }else{
168119 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
@@ -168120,11 +168379,11 @@
168120 }
168121 yylhsminor.yy41 = yymsp[0].minor.yy41;
168122 }
168123 yymsp[-1].minor.yy41 = yylhsminor.yy41;
168124 break;
168125 case 336: /* filter_over ::= filter_clause */
168126 {
168127 yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
168128 if( yylhsminor.yy41 ){
168129 yylhsminor.yy41->eFrmType = TK_FILTER;
168130 yylhsminor.yy41->pFilter = yymsp[0].minor.yy528;
@@ -168132,91 +168391,91 @@
168132 sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528);
168133 }
168134 }
168135 yymsp[0].minor.yy41 = yylhsminor.yy41;
168136 break;
168137 case 337: /* over_clause ::= OVER LP window RP */
168138 {
168139 yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41;
168140 assert( yymsp[-3].minor.yy41!=0 );
168141 }
168142 break;
168143 case 338: /* over_clause ::= OVER nm */
168144 {
168145 yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
168146 if( yymsp[-1].minor.yy41 ){
168147 yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
168148 }
168149 }
168150 break;
168151 case 339: /* filter_clause ::= FILTER LP WHERE expr RP */
168152 { yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; }
168153 break;
168154 default:
168155 /* (340) input ::= cmdlist */ yytestcase(yyruleno==340);
168156 /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341);
168157 /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342);
168158 /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343);
168159 /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344);
168160 /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345);
168161 /* (346) trans_opt ::= */ yytestcase(yyruleno==346);
168162 /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347);
168163 /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348);
168164 /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349);
168165 /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350);
168166 /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351);
168167 /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352);
168168 /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353);
168169 /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354);
168170 /* (355) nm ::= ID|INDEXED */ yytestcase(yyruleno==355);
168171 /* (356) nm ::= STRING */ yytestcase(yyruleno==356);
168172 /* (357) nm ::= JOIN_KW */ yytestcase(yyruleno==357);
168173 /* (358) typetoken ::= typename */ yytestcase(yyruleno==358);
168174 /* (359) typename ::= ID|STRING */ yytestcase(yyruleno==359);
168175 /* (360) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=360);
168176 /* (361) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=361);
168177 /* (362) carglist ::= carglist ccons */ yytestcase(yyruleno==362);
168178 /* (363) carglist ::= */ yytestcase(yyruleno==363);
168179 /* (364) ccons ::= NULL onconf */ yytestcase(yyruleno==364);
168180 /* (365) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==365);
168181 /* (366) ccons ::= AS generated */ yytestcase(yyruleno==366);
168182 /* (367) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==367);
168183 /* (368) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==368);
168184 /* (369) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=369);
168185 /* (370) tconscomma ::= */ yytestcase(yyruleno==370);
168186 /* (371) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=371);
168187 /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372);
168188 /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373);
168189 /* (374) oneselect ::= values */ yytestcase(yyruleno==374);
168190 /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375);
168191 /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376);
168192 /* (377) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=377);
168193 /* (378) returning ::= */ yytestcase(yyruleno==378);
168194 /* (379) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=379);
168195 /* (380) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==380);
168196 /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381);
168197 /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382);
168198 /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383);
168199 /* (384) nmnum ::= ON */ yytestcase(yyruleno==384);
168200 /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385);
168201 /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386);
168202 /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387);
168203 /* (388) foreach_clause ::= */ yytestcase(yyruleno==388);
168204 /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389);
168205 /* (390) trnm ::= nm */ yytestcase(yyruleno==390);
168206 /* (391) tridxby ::= */ yytestcase(yyruleno==391);
168207 /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392);
168208 /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393);
168209 /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394);
168210 /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395);
168211 /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396);
168212 /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397);
168213 /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398);
168214 /* (399) anylist ::= */ yytestcase(yyruleno==399);
168215 /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400);
168216 /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401);
168217 /* (402) with ::= */ yytestcase(yyruleno==402);
168218 break;
168219 /********** End reduce actions ************************************************/
168220 };
168221 assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
168222 yygoto = yyRuleInfoLhs[yyruleno];
@@ -174912,10 +175171,28 @@
174912 */
174913 SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
174914 int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
174915 return iDb<0 ? 0 : db->aDb[iDb].pBt;
174916 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174917
174918 /*
174919 ** Return the filename of the database associated with a database
174920 ** connection.
174921 */
@@ -190551,10 +190828,12 @@
190551 if( rc==SQLITE_OK ){
190552 if( pNode->key.n ){
190553 pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix);
190554 }
190555 pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix);
 
 
190556 memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix);
190557 pBlk->n += nSuffix;
190558
190559 memcpy(pNode->key.a, zTerm, nTerm);
190560 pNode->key.n = nTerm;
@@ -190673,10 +190952,11 @@
190673 NodeWriter *pLeaf; /* Object used to write leaf nodes */
190674
190675 pLeaf = &pWriter->aNodeWriter[0];
190676 nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm);
190677 nSuffix = nTerm - nPrefix;
 
190678
190679 nSpace = sqlite3Fts3VarintLen(nPrefix);
190680 nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
190681 nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
190682
@@ -236295,11 +236575,11 @@
236295 int nArg, /* Number of args */
236296 sqlite3_value **apUnused /* Function arguments */
236297 ){
236298 assert( nArg==0 );
236299 UNUSED_PARAM2(nArg, apUnused);
236300 sqlite3_result_text(pCtx, "fts5: 2022-05-10 00:24:01 c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527", -1, SQLITE_TRANSIENT);
236301 }
236302
236303 /*
236304 ** Return true if zName is the extension on one of the shadow tables used
236305 ** by this module.
236306
--- 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-06-15 16:26:37 56c60a35ea457f06db58ec3f694a1ae16fd03e6625da1d7879d63d72bbcb1c62"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -6580,10 +6580,32 @@
6580 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
6581 ** create the statement in the first place.
6582 */
6583 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
6584
6585 /*
6586 ** CAPI3REF: Return The Schema Name For A Database Connection
6587 ** METHOD: sqlite3
6588 **
6589 ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
6590 ** for the N-th database on database connection D, or a NULL pointer of N is
6591 ** out of range. An N alue of 0 means the main database file. An N of 1 is
6592 ** the "temp" schema. Larger values of N correspond to various ATTACH-ed
6593 ** databases.
6594 **
6595 ** Space to hold the string that is returned by sqlite3_db_name() is managed
6596 ** by SQLite itself. The string might be deallocated by any operation that
6597 ** changes the schema, including [ATTACH] or [DETACH] or calls to
6598 ** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that
6599 ** occur on a different thread. Applications that need to
6600 ** remember the string long-term should make their own copy. Applications that
6601 ** are accessing the same database connection simultaneously on multiple
6602 ** threads should mutex-protect calls to this API and should make their own
6603 ** private copy of the result prior to releasing the mutex.
6604 */
6605 SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N);
6606
6607 /*
6608 ** CAPI3REF: Return The Filename For A Database Connection
6609 ** METHOD: sqlite3
6610 **
6611 ** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
@@ -15702,17 +15724,18 @@
15724 #define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */
15725 #define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */
15726 #define OP_VRename 176
15727 #define OP_Pagecount 177
15728 #define OP_MaxPgcnt 178
15729 #define OP_ClrSubtype 179 /* synopsis: r[P1].subtype = 0 */
15730 #define OP_FilterAdd 180 /* synopsis: filter(P1) += key(P3@P4) */
15731 #define OP_Trace 181
15732 #define OP_CursorHint 182
15733 #define OP_ReleaseReg 183 /* synopsis: release r[P1@P2] mask P3 */
15734 #define OP_Noop 184
15735 #define OP_Explain 185
15736 #define OP_Abortable 186
15737
15738 /* Properties such as "out2" or "jump" that are specified in
15739 ** comments following the "case" for each opcode in the vdbe.c
15740 ** are encoded into bitvectors as follows:
15741 */
@@ -15743,12 +15766,12 @@
15766 /* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
15767 /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
15768 /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
15769 /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15770 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15771 /* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\
15772 /* 184 */ 0x00, 0x00, 0x00,}
15773
15774 /* The resolve3P2Values() routine is able to run faster if it knows
15775 ** the value of the largest JUMP opcode. The smaller the maximum
15776 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15777 ** generated this include file strives to group all JUMP opcodes
@@ -16285,10 +16308,17 @@
16308 /* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h
16309 */
16310 #ifndef SQLITE_MAX_PATHLEN
16311 # define SQLITE_MAX_PATHLEN FILENAME_MAX
16312 #endif
16313
16314 /* Maximum number of symlinks that will be resolved while trying to
16315 ** expand a filename in xFullPathname() in the VFS.
16316 */
16317 #ifndef SQLITE_MAX_SYMLINK
16318 # define SQLITE_MAX_SYMLINK 200
16319 #endif
16320
16321 /*
16322 ** The default size of a disk sector
16323 */
16324 #ifndef SQLITE_DEFAULT_SECTOR_SIZE
@@ -17157,11 +17187,11 @@
17187 #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
17188 #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
17189 #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
17190 ** single query - might change over time */
17191 #define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
17192 /* 0x8000 -- available for reuse */
17193 #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
17194 #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
17195 #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
17196 #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
17197 #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
@@ -17174,10 +17204,11 @@
17204 #define INLINEFUNC_implies_nonnull_row 1
17205 #define INLINEFUNC_expr_implies_expr 2
17206 #define INLINEFUNC_expr_compare 3
17207 #define INLINEFUNC_affinity 4
17208 #define INLINEFUNC_iif 5
17209 #define INLINEFUNC_sqlite_offset 6
17210 #define INLINEFUNC_unlikely 99 /* Default case */
17211
17212 /*
17213 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
17214 ** used to create the initializers for the FuncDef structures.
@@ -18120,11 +18151,11 @@
18151 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
18152 ** TK_VARIABLE: variable number (always >= 1).
18153 ** TK_SELECT_COLUMN: column of the result vector */
18154 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
18155 union {
18156 int iJoin; /* If EP_OuterON or EP_InnerON, the right table */
18157 int iOfst; /* else: start of token from start of statement */
18158 } w;
18159 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
18160 union {
18161 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@@ -18141,33 +18172,33 @@
18172 ** Value restrictions:
18173 **
18174 ** EP_Agg == NC_HasAgg == SF_HasAgg
18175 ** EP_Win == NC_HasWin
18176 */
18177 #define EP_OuterON 0x000001 /* Originates in ON/USING clause of outer join */
18178 #define EP_InnerON 0x000002 /* Originates in ON/USING of an inner join */
18179 #define EP_Distinct 0x000004 /* Aggregate function with DISTINCT keyword */
18180 #define EP_HasFunc 0x000008 /* Contains one or more functions of any kind */
18181 #define EP_Agg 0x000010 /* Contains one or more aggregate functions */
18182 #define EP_FixedCol 0x000020 /* TK_Column with a known fixed value */
18183 #define EP_VarSelect 0x000040 /* pSelect is correlated, not constant */
18184 #define EP_DblQuoted 0x000080 /* token.z was originally in "..." */
18185 #define EP_InfixFunc 0x000100 /* True for an infix function: LIKE, GLOB, etc */
18186 #define EP_Collate 0x000200 /* Tree contains a TK_COLLATE operator */
18187 #define EP_Commuted 0x000400 /* Comparison operator has been commuted */
18188 #define EP_IntValue 0x000800 /* Integer value contained in u.iValue */
18189 #define EP_xIsSelect 0x001000 /* x.pSelect is valid (otherwise x.pList is) */
18190 #define EP_Skip 0x002000 /* Operator does not contribute to affinity */
18191 #define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
18192 #define EP_Win 0x008000 /* Contains window functions */
18193 #define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
18194 #define EP_MemToken 0x020000 /* Need to sqlite3DbFree() Expr.zToken */
18195 #define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */
18196 #define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */
18197 #define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
18198 #define EP_CanBeNull 0x200000 /* Can be null despite NOT NULL constraint */
18199 #define EP_Subquery 0x400000 /* Tree contains a TK_SELECT operator */
18200 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
18201 #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
18202 #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
18203 #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
18204 #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
@@ -18186,12 +18217,12 @@
18217 */
18218 #define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
18219 #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
18220 #define ExprSetProperty(E,P) (E)->flags|=(P)
18221 #define ExprClearProperty(E,P) (E)->flags&=~(P)
18222 #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue)
18223 #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse)
18224
18225 /* Macros used to ensure that the correct members of unions are accessed
18226 ** in Expr.
18227 */
18228 #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
@@ -18366,16 +18397,18 @@
18397 u8 jointype; /* Type of join between this table and the previous */
18398 unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
18399 unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
18400 unsigned isTabFunc :1; /* True if table-valued-function syntax */
18401 unsigned isCorrelated :1; /* True if sub-query is correlated */
18402 unsigned isMaterialized:1; /* This is a materialized view */
18403 unsigned viaCoroutine :1; /* Implemented as a co-routine */
18404 unsigned isRecursive :1; /* True for recursive reference in WITH */
18405 unsigned fromDDL :1; /* Comes from sqlite_schema */
18406 unsigned isCte :1; /* This is a CTE */
18407 unsigned notCte :1; /* This item may not match a CTE */
18408 unsigned isUsing :1; /* u3.pUsing is valid */
18409 unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
18410 unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */
18411 unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
18412 } fg;
18413 int iCursor; /* The VDBE cursor number used to access this table */
18414 union {
@@ -20595,11 +20628,10 @@
20628 ** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
20629 */
20630 #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */
20631 #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */
20632 #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
 
20633 SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);
20634
20635 SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
20636 SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
20637 #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
@@ -22224,11 +22256,11 @@
22256 u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
22257 #endif
22258 Bool isEphemeral:1; /* True for an ephemeral table */
22259 Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
22260 Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
22261 Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */
22262 u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
22263 union { /* pBtx for isEphermeral. pAltMap otherwise */
22264 Btree *pBtx; /* Separate file holding temporary table */
22265 u32 *aAltMap; /* Mapping from table to index column numbers */
22266 } ub;
@@ -30545,11 +30577,13 @@
30577 /*
30578 ** If pExpr has a byte offset for the start of a token, record that as
30579 ** as the error offset.
30580 */
30581 SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
30582 while( pExpr
30583 && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0)
30584 ){
30585 pExpr = pExpr->pLeft;
30586 }
30587 if( pExpr==0 ) return;
30588 db->errByteOffset = pExpr->w.iOfst;
30589 }
@@ -31196,10 +31230,13 @@
31230 sqlite3_str_appendf(&x, " DDL");
31231 }
31232 if( pItem->fg.isCte ){
31233 sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
31234 }
31235 if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
31236 sqlite3_str_appendf(&x, " ON");
31237 }
31238 sqlite3StrAccumFinish(&x);
31239 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
31240 n = 0;
31241 if( pItem->pSelect ) n++;
31242 if( pItem->fg.isTabFunc ) n++;
@@ -31470,12 +31507,15 @@
31507 if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
31508 StrAccum x;
31509 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
31510 sqlite3_str_appendf(&x, " fg.af=%x.%c",
31511 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
31512 if( ExprHasProperty(pExpr, EP_OuterON) ){
31513 sqlite3_str_appendf(&x, " outer.iJoin=%d", pExpr->w.iJoin);
31514 }
31515 if( ExprHasProperty(pExpr, EP_InnerON) ){
31516 sqlite3_str_appendf(&x, " inner.iJoin=%d", pExpr->w.iJoin);
31517 }
31518 if( ExprHasProperty(pExpr, EP_FromDDL) ){
31519 sqlite3_str_appendf(&x, " DDL");
31520 }
31521 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -35398,17 +35438,18 @@
35438 /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
35439 /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
35440 /* 176 */ "VRename" OpHelp(""),
35441 /* 177 */ "Pagecount" OpHelp(""),
35442 /* 178 */ "MaxPgcnt" OpHelp(""),
35443 /* 179 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"),
35444 /* 180 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
35445 /* 181 */ "Trace" OpHelp(""),
35446 /* 182 */ "CursorHint" OpHelp(""),
35447 /* 183 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
35448 /* 184 */ "Noop" OpHelp(""),
35449 /* 185 */ "Explain" OpHelp(""),
35450 /* 186 */ "Abortable" OpHelp(""),
35451 };
35452 return azName[i];
35453 }
35454 #endif
35455
@@ -41837,90 +41878,103 @@
41878 }
41879 return SQLITE_OK;
41880 }
41881
41882 /*
41883 ** A pathname under construction
41884 */
41885 typedef struct DbPath DbPath;
41886 struct DbPath {
41887 int rc; /* Non-zero following any error */
41888 int nSymlink; /* Number of symlinks resolved */
41889 char *zOut; /* Write the pathname here */
41890 int nOut; /* Bytes of space available to zOut[] */
41891 int nUsed; /* Bytes of zOut[] currently being used */
41892 };
41893
41894 /* Forward reference */
41895 static void appendAllPathElements(DbPath*,const char*);
41896
41897 /*
41898 ** Append a single path element to the DbPath under construction
41899 */
41900 static void appendOnePathElement(
41901 DbPath *pPath, /* Path under construction, to which to append zName */
41902 const char *zName, /* Name to append to pPath. Not zero-terminated */
41903 int nName /* Number of significant bytes in zName */
41904 ){
41905 assert( nName>0 );
41906 assert( zName!=0 );
41907 if( zName[0]=='.' ){
41908 if( nName==1 ) return;
41909 if( zName[1]=='.' && nName==2 ){
41910 if( pPath->nUsed<=1 ){
41911 pPath->rc = SQLITE_ERROR;
41912 return;
41913 }
41914 assert( pPath->zOut[0]=='/' );
41915 while( pPath->zOut[--pPath->nUsed]!='/' ){}
41916 return;
41917 }
41918 }
41919 if( pPath->nUsed + nName + 2 >= pPath->nOut ){
41920 pPath->rc = SQLITE_ERROR;
41921 return;
41922 }
41923 pPath->zOut[pPath->nUsed++] = '/';
41924 memcpy(&pPath->zOut[pPath->nUsed], zName, nName);
41925 pPath->nUsed += nName;
41926 #if defined(HAVE_READLINK) && defined(HAVE_LSTAT)
41927 if( pPath->rc==SQLITE_OK ){
41928 const char *zIn;
41929 struct stat buf;
41930 pPath->zOut[pPath->nUsed] = 0;
41931 zIn = pPath->zOut;
41932 if( osLstat(zIn, &buf)!=0 ){
41933 if( errno!=ENOENT ){
41934 pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
41935 }
41936 }else if( S_ISLNK(buf.st_mode) ){
41937 ssize_t got;
41938 char zLnk[SQLITE_MAX_PATHLEN+2];
41939 if( pPath->nSymlink++ > SQLITE_MAX_SYMLINK ){
41940 pPath->rc = SQLITE_CANTOPEN_BKPT;
41941 return;
41942 }
41943 got = osReadlink(zIn, zLnk, sizeof(zLnk)-2);
41944 if( got<=0 || got>=(ssize_t)sizeof(zLnk)-2 ){
41945 pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
41946 return;
41947 }
41948 zLnk[got] = 0;
41949 if( zLnk[0]=='/' ){
41950 pPath->nUsed = 0;
41951 }else{
41952 pPath->nUsed -= nName + 1;
41953 }
41954 appendAllPathElements(pPath, zLnk);
41955 }
41956 }
41957 #endif
41958 }
41959
41960 /*
41961 ** Append all path elements in zPath to the DbPath under construction.
41962 */
41963 static void appendAllPathElements(
41964 DbPath *pPath, /* Path under construction, to which to append zName */
41965 const char *zPath /* Path to append to pPath. Is zero-terminated */
41966 ){
41967 int i = 0;
41968 int j = 0;
41969 do{
41970 while( zPath[i] && zPath[i]!='/' ){ i++; }
41971 if( i>j ){
41972 appendOnePathElement(pPath, &zPath[j], i-j);
41973 }
41974 j = i+1;
41975 }while( zPath[i++] );
41976 }
41977
41978 /*
41979 ** Turn a relative pathname into a full pathname. The relative path
41980 ** is stored as a nul-terminated string in the buffer pointed to by
@@ -41934,89 +41988,30 @@
41988 sqlite3_vfs *pVfs, /* Pointer to vfs object */
41989 const char *zPath, /* Possibly relative input path */
41990 int nOut, /* Size of output buffer in bytes */
41991 char *zOut /* Output buffer */
41992 ){
41993 DbPath path;
 
 
 
 
 
 
 
 
 
41994 UNUSED_PARAMETER(pVfs);
41995 path.rc = 0;
41996 path.nUsed = 0;
41997 path.nSymlink = 0;
41998 path.nOut = nOut;
41999 path.zOut = zOut;
42000 if( zPath[0]!='/' ){
42001 char zPwd[SQLITE_MAX_PATHLEN+2];
42002 if( osGetcwd(zPwd, sizeof(zPwd)-2)==0 ){
42003 return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
42004 }
42005 appendAllPathElements(&path, zPwd);
42006 }
42007 appendAllPathElements(&path, zPath);
42008 zOut[path.nUsed] = 0;
42009 if( path.rc || path.nUsed<2 ) return SQLITE_CANTOPEN_BKPT;
42010 if( path.nSymlink ) return SQLITE_OK_SYMLINK;
42011 return SQLITE_OK;
42012 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42013
42014 #ifndef SQLITE_OMIT_LOAD_EXTENSION
42015 /*
42016 ** Interfaces for opening a shared library, finding entry points
42017 ** within the shared library, and closing the shared library.
@@ -56473,10 +56468,11 @@
56468 }else if( (currentSize+szPage)<=newSize ){
56469 char *pTmp = pPager->pTmpSpace;
56470 memset(pTmp, 0, szPage);
56471 testcase( (newSize-szPage) == currentSize );
56472 testcase( (newSize-szPage) > currentSize );
56473 sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &newSize);
56474 rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
56475 }
56476 if( rc==SQLITE_OK ){
56477 pPager->dbFileSize = nPage;
56478 }
@@ -70725,16 +70721,21 @@
70721 eMode = BTALLOC_LE;
70722 iNear = nFin;
70723 }
70724 do {
70725 MemPage *pFreePg;
70726 Pgno dbSize = btreePagecount(pBt);
70727 rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
70728 if( rc!=SQLITE_OK ){
70729 releasePage(pLastPg);
70730 return rc;
70731 }
70732 releasePage(pFreePg);
70733 if( iFreePg>dbSize ){
70734 releasePage(pLastPg);
70735 return SQLITE_CORRUPT_BKPT;
70736 }
70737 }while( bCommit && iFreePg>nFin );
70738 assert( iFreePg<iLastPg );
70739
70740 rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, bCommit);
70741 releasePage(pLastPg);
@@ -75957,11 +75958,11 @@
75958 }
75959
75960 TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
75961 pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
75962 loc==0 ? "overwrite" : "new entry"));
75963 assert( pPage->isInit || CORRUPT_DB );
75964 newCell = pBt->pTmpSpace;
75965 assert( newCell!=0 );
75966 if( flags & BTREE_PREFORMAT ){
75967 rc = SQLITE_OK;
75968 szNew = pBt->nPreformatSize;
@@ -80239,12 +80240,12 @@
80240 assert( !ExprHasProperty(pExpr, EP_IntValue) );
80241 aff = sqlite3AffinityType(pExpr->u.zToken,0);
80242 rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
80243 testcase( rc!=SQLITE_OK );
80244 if( *ppVal ){
80245 sqlite3VdbeMemCast(*ppVal, aff, enc);
80246 sqlite3ValueApplyAffinity(*ppVal, affinity, enc);
80247 }
80248 return rc;
80249 }
80250
80251 /* Handle negative integers in a single step. This is needed in the
@@ -82215,15 +82216,13 @@
82216 if( c=='4' ){
82217 sqlite3_str_appendall(&x, zP4);
82218 }else if( c=='X' ){
82219 if( pOp->zComment && pOp->zComment[0] ){
82220 sqlite3_str_appendall(&x, pOp->zComment);
82221 seenCom = 1;
82222 break;
82223 }
 
 
82224 }else{
82225 int v1 = translateP(c, pOp);
82226 int v2;
82227 if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
82228 ii += 3;
@@ -89770,14 +89769,19 @@
89769 pOut++;
89770 }while( --n );
89771 break;
89772 }
89773
89774 /* Opcode: Copy P1 P2 P3 * P5
89775 ** Synopsis: r[P2@P3+1]=r[P1@P3+1]
89776 **
89777 ** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
89778 **
89779 ** If the 0x0002 bit of P5 is set then also clear the MEM_Subtype flag in the
89780 ** destination. The 0x0001 bit of P5 indicates that this Copy opcode cannot
89781 ** be merged. The 0x0001 bit is used by the query planner and does not
89782 ** come into play during query execution.
89783 **
89784 ** This instruction makes a deep copy of the value. A duplicate
89785 ** is made of any string or blob constant. See also OP_SCopy.
89786 */
89787 case OP_Copy: {
@@ -89789,10 +89793,13 @@
89793 assert( pOut!=pIn1 );
89794 while( 1 ){
89795 memAboutToChange(p, pOut);
89796 sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
89797 Deephemeralize(pOut);
89798 if( (pOut->flags & MEM_Subtype)!=0 && (pOp->p5 & 0x0002)!=0 ){
89799 pOut->flags &= ~MEM_Subtype;
89800 }
89801 #ifdef SQLITE_DEBUG
89802 pOut->pScopyFrom = 0;
89803 #endif
89804 REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
89805 if( (n--)==0 ) break;
@@ -92171,10 +92178,15 @@
92178 if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
92179 sqlite3ResetOneSchema(db, pOp->p1);
92180 }
92181 p->expired = 1;
92182 rc = SQLITE_SCHEMA;
92183
92184 /* Set changeCntOn to 0 to prevent the value returned by sqlite3_changes()
92185 ** from being modified in sqlite3VdbeHalt(). If this statement is
92186 ** reprepared, changeCntOn will be set again. */
92187 p->changeCntOn = 0;
92188 }
92189 if( rc ) goto abort_due_to_error;
92190 break;
92191 }
92192
@@ -92470,12 +92482,12 @@
92482 pCx->pKeyInfo = pOrig->pKeyInfo;
92483 pCx->isTable = pOrig->isTable;
92484 pCx->pgnoRoot = pOrig->pgnoRoot;
92485 pCx->isOrdered = pOrig->isOrdered;
92486 pCx->ub.pBtx = pOrig->ub.pBtx;
92487 pCx->noReuse = 1;
92488 pOrig->noReuse = 1;
92489 rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR,
92490 pCx->pKeyInfo, pCx->uc.pCursor);
92491 /* The sqlite3BtreeCursor() routine can only fail for the first cursor
92492 ** opened for a database. Since there is already an open cursor when this
92493 ** opcode is run, the sqlite3BtreeCursor() cannot fail */
@@ -92538,11 +92550,11 @@
92550 assert( aMem[pOp->p3].flags & MEM_Null );
92551 aMem[pOp->p3].n = 0;
92552 aMem[pOp->p3].z = "";
92553 }
92554 pCx = p->apCsr[pOp->p1];
92555 if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){
92556 /* If the ephermeral table is already open and has no duplicates from
92557 ** OP_OpenDup, then erase all existing content so that the table is
92558 ** empty again, rather than creating a new table. */
92559 assert( pCx->isEphemeral );
92560 pCx->seqCount = 0;
@@ -94125,10 +94137,11 @@
94137 ** pseudo-cursor that always gives null rows. */
94138 pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO);
94139 if( pC==0 ) goto no_mem;
94140 pC->seekResult = 0;
94141 pC->isTable = 1;
94142 pC->noReuse = 1;
94143 pC->uc.pCursor = sqlite3BtreeFakeValidCursor();
94144 }
94145 pC->nullRow = 1;
94146 pC->cacheStatus = CACHE_STALE;
94147 if( pC->eCurType==CURTYPE_BTREE ){
@@ -96257,18 +96270,18 @@
96270 Mem *pDest;
96271 sqlite3_context sContext;
96272
96273 VdbeCursor *pCur = p->apCsr[pOp->p1];
96274 assert( pCur!=0 );
 
96275 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
96276 pDest = &aMem[pOp->p3];
96277 memAboutToChange(p, pDest);
96278 if( pCur->nullRow ){
96279 sqlite3VdbeMemSetNull(pDest);
96280 break;
96281 }
96282 assert( pCur->eCurType==CURTYPE_VTAB );
96283 pVtab = pCur->uc.pVCur->pVtab;
96284 pModule = pVtab->pModule;
96285 assert( pModule->xColumn );
96286 memset(&sContext, 0, sizeof(sContext));
96287 sContext.pOut = pDest;
@@ -96591,10 +96604,21 @@
96604
96605 REGISTER_TRACE(pOp->p3, pOut);
96606 UPDATE_MAX_BLOBSIZE(pOut);
96607 break;
96608 }
96609
96610 /* Opcode: ClrSubtype P1 * * * *
96611 ** Synopsis: r[P1].subtype = 0
96612 **
96613 ** Clear the subtype from register P1.
96614 */
96615 case OP_ClrSubtype: { /* in1 */
96616 pIn1 = &aMem[pOp->p1];
96617 pIn1->flags &= ~MEM_Subtype;
96618 break;
96619 }
96620
96621 /* Opcode: FilterAdd P1 * P3 P4 *
96622 ** Synopsis: filter(P1) += key(P3@P4)
96623 **
96624 ** Compute a hash on the P4 registers starting with r[P3] and
@@ -102345,11 +102369,11 @@
102369 for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
102370 anRef[i] = p->nRef;
102371 }
102372 sqlite3WalkExpr(pWalker, pExpr->pLeft);
102373 if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
102374 testcase( ExprHasProperty(pExpr, EP_OuterON) );
102375 assert( !ExprHasProperty(pExpr, EP_IntValue) );
102376 if( pExpr->op==TK_NOTNULL ){
102377 pExpr->u.zToken = "true";
102378 ExprSetProperty(pExpr, EP_IsTrue);
102379 }else{
@@ -104636,10 +104660,11 @@
104660 pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
104661 if( pNew==0 ){
104662 sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
104663 return 0;
104664 }
104665 assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) );
104666 pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
104667 if( pList
104668 && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
104669 && !pParse->nested
104670 ){
@@ -104914,11 +104939,11 @@
104939 #endif
104940 ){
104941 nSize = EXPR_FULLSIZE;
104942 }else{
104943 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
104944 assert( !ExprHasProperty(p, EP_OuterON) );
104945 assert( !ExprHasProperty(p, EP_MemToken) );
104946 assert( !ExprHasVVAProperty(p, EP_NoReduce) );
104947 if( p->pLeft || p->x.pList ){
104948 nSize = EXPR_REDUCEDSIZE | EP_Reduced;
104949 }else{
@@ -105740,11 +105765,11 @@
105765 static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
105766
105767 /* If pWalker->eCode is 2 then any term of the expression that comes from
105768 ** the ON or USING clauses of an outer join disqualifies the expression
105769 ** from being considered constant. */
105770 if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){
105771 pWalker->eCode = 0;
105772 return WRC_Abort;
105773 }
105774
105775 switch( pExpr->op ){
@@ -105887,14 +105912,14 @@
105912 SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){
105913 if( pSrc->fg.jointype & JT_LTORJ ){
105914 return 0; /* rule (3) */
105915 }
105916 if( pSrc->fg.jointype & JT_LEFT ){
105917 if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */
105918 if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */
105919 }else{
105920 if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */
105921 }
105922 return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
105923 }
105924
105925
@@ -106312,15 +106337,11 @@
106337 int mustBeUnique; /* True if RHS must be unique */
106338 Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
106339
106340 assert( pX->op==TK_IN );
106341 mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
106342 iTab = pParse->nTab++;
 
 
 
 
106343
106344 /* If the RHS of this IN(...) operator is a SELECT, and if it matters
106345 ** whether or not the SELECT result contains NULL values, check whether
106346 ** or not NULL is actually possible (it may not be, for example, due
106347 ** to NOT NULL constraints in the schema). If no NULL values are possible,
@@ -106650,13 +106671,12 @@
106671 pExpr->x.pSelect->selId));
106672 }
106673 assert( ExprUseYSub(pExpr) );
106674 sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
106675 pExpr->y.sub.iAddr);
106676 assert( iTab!=pExpr->iTable );
106677 sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
 
106678 sqlite3VdbeJumpHere(v, addrOnce);
106679 return;
106680 }
106681
106682 /* Begin coding the subroutine */
@@ -107526,11 +107546,21 @@
107546 memset(&caseExpr, 0, sizeof(caseExpr));
107547 caseExpr.op = TK_CASE;
107548 caseExpr.x.pList = pFarg;
107549 return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
107550 }
107551 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
107552 case INLINEFUNC_sqlite_offset: {
107553 Expr *pArg = pFarg->a[0].pExpr;
107554 if( pArg->op==TK_COLUMN && pArg->iTable>=0 ){
107555 sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
107556 }else{
107557 sqlite3VdbeAddOp2(v, OP_Null, 0, target);
107558 }
107559 break;
107560 }
107561 #endif
107562 default: {
107563 /* The UNLIKELY() function is a no-op. The result is the value
107564 ** of the first argument.
107565 */
107566 assert( nFarg==1 || nFarg==2 );
@@ -108065,24 +108095,12 @@
108095 #endif
108096 if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
108097 if( !pColl ) pColl = db->pDfltColl;
108098 sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
108099 }
108100 sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
108101 pDef, pExpr->op2);
 
 
 
 
 
 
 
 
 
 
 
 
108102 if( nFarg ){
108103 if( constMask==0 ){
108104 sqlite3ReleaseTempRange(pParse, r1, nFarg);
108105 }else{
108106 sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
@@ -108149,13 +108167,29 @@
108167 ** Z is stored in pExpr->pList->a[1].pExpr.
108168 */
108169 case TK_BETWEEN: {
108170 exprCodeBetween(pParse, pExpr, target, 0, 0);
108171 return target;
108172 }
108173 case TK_COLLATE: {
108174 if( !ExprHasProperty(pExpr, EP_Collate)
108175 && ALWAYS(pExpr->pLeft)
108176 && pExpr->pLeft->op==TK_FUNCTION
108177 ){
108178 inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
108179 if( inReg!=target ){
108180 sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
108181 inReg = target;
108182 }
108183 sqlite3VdbeAddOp1(v, OP_ClrSubtype, inReg);
108184 return inReg;
108185 }else{
108186 pExpr = pExpr->pLeft;
108187 goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */
108188 }
108189 }
108190 case TK_SPAN:
 
108191 case TK_UPLUS: {
108192 pExpr = pExpr->pLeft;
108193 goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */
108194 }
108195
@@ -108645,12 +108679,12 @@
108679 }else{
108680 /* Mark the expression is being from the ON or USING clause of a join
108681 ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
108682 ** it into the Parse.pConstExpr list. We should use a new bit for this,
108683 ** for clarity, but we are out of bits in the Expr.flags field so we
108684 ** have to reuse the EP_OuterON bit. Bummer. */
108685 pDel->flags |= EP_OuterON;
108686 sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
108687 }
108688 sqlite3ReleaseTempReg(pParse, regFree1);
108689 }
108690 sqlite3ExprDelete(db, pDel);
@@ -109331,11 +109365,11 @@
109365 ** (never setting pWalker->eCode) is a harmless missed optimization.
109366 */
109367 static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
109368 testcase( pExpr->op==TK_AGG_COLUMN );
109369 testcase( pExpr->op==TK_AGG_FUNCTION );
109370 if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune;
109371 switch( pExpr->op ){
109372 case TK_ISNOT:
109373 case TK_ISNULL:
109374 case TK_NOTNULL:
109375 case TK_IS:
@@ -109428,11 +109462,11 @@
109462 ** is NULL. A false negative is merely a missed optimization opportunity.
109463 **
109464 ** False positives are not allowed, however. A false positive may result
109465 ** in an incorrect answer.
109466 **
109467 ** Terms of p that are marked with EP_OuterON (and hence that come from
109468 ** the ON or USING clauses of OUTER JOINS) are excluded from the analysis.
109469 **
109470 ** This routine is used to check if a LEFT JOIN can be converted into
109471 ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
109472 ** clause requires that some column of the right table of the LEFT JOIN
@@ -111302,31 +111336,37 @@
111336 if( pParse->nErr ) rc = pParse->rc;
111337 }
111338 if( rc==SQLITE_OK && pStep->zTarget ){
111339 SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep);
111340 if( pSrc ){
111341 Select *pSel = sqlite3SelectNew(
111342 pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0
111343 );
111344 if( pSel==0 ){
111345 pStep->pExprList = 0;
111346 pSrc = 0;
111347 rc = SQLITE_NOMEM;
111348 }else{
111349 sqlite3SelectPrep(pParse, pSel, 0);
111350 rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
111351 assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList );
111352 assert( pSrc==pSel->pSrc );
111353 if( pStep->pExprList ) pSel->pEList = 0;
111354 pSel->pSrc = 0;
111355 sqlite3SelectDelete(db, pSel);
111356 }
111357 if( pStep->pFrom ){
111358 int i;
111359 for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){
111360 SrcItem *p = &pStep->pFrom->a[i];
111361 if( p->pSelect ){
111362 sqlite3SelectPrep(pParse, p->pSelect, 0);
111363 }
111364 }
111365 }
111366
111367 if( db->mallocFailed ){
111368 rc = SQLITE_NOMEM;
111369 }
111370 sNC.pSrcList = pSrc;
111371 if( rc==SQLITE_OK && pStep->pWhere ){
111372 rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
@@ -111773,10 +111813,19 @@
111813 if( rc==SQLITE_OK ){
111814 renameWalkTrigger(&sWalker, pTrigger);
111815 for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
111816 if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
111817 renameTokenFind(&sParse, &sCtx, pStep->zTarget);
111818 }
111819 if( pStep->pFrom ){
111820 int i;
111821 for(i=0; i<pStep->pFrom->nSrc; i++){
111822 SrcItem *pItem = &pStep->pFrom->a[i];
111823 if( 0==sqlite3_stricmp(pItem->zName, zOld) ){
111824 renameTokenFind(&sParse, &sCtx, pItem->zName);
111825 }
111826 }
111827 }
111828 }
111829 }
111830 }
111831 }
@@ -124372,15 +124421,15 @@
124421 }else{
124422 ans = log(x);
124423 switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){
124424 case 1:
124425 /* Convert from natural logarithm to log base 10 */
124426 ans /= M_LN10;
124427 break;
124428 case 2:
124429 /* Convert from natural logarithm to log base 2 */
124430 ans /= M_LN2;
124431 break;
124432 default:
124433 break;
124434 }
124435 }
@@ -124515,12 +124564,11 @@
124564 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
124565 INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124566 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124567 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
124568 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
124569 INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
 
124570 #endif
124571 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
124572 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
124573 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
124574 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -129800,10 +129848,11 @@
129848 /* Version 3.39.0 and later */
129849 int (*deserialize)(sqlite3*,const char*,unsigned char*,
129850 sqlite3_int64,sqlite3_int64,unsigned);
129851 unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
129852 unsigned int);
129853 const char *(*db_name)(sqlite3*,int);
129854 };
129855
129856 /*
129857 ** This is the function signature used for all extension entry points. It
129858 ** is also defined in the file "loadext.c".
@@ -130118,14 +130167,16 @@
130167 #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
130168 #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
130169 #define sqlite3_vtab_in sqlite3_api->vtab_in
130170 #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
130171 #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
130172 /* Version 3.39.0 and later */
130173 #ifndef SQLITE_OMIT_DESERIALIZE
130174 #define sqlite3_deserialize sqlite3_api->deserialize
130175 #define sqlite3_serialize sqlite3_api->serialize
130176 #endif
130177 #define sqlite3_db_name sqlite3_api->db_name
130178 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
130179
130180 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
130181 /* This case when the file really is being compiled as a loadable
130182 ** extension */
@@ -130629,15 +130680,16 @@
130680 0,
130681 #endif
130682 /* Version 3.39.0 and later */
130683 #ifndef SQLITE_OMIT_DESERIALIZE
130684 sqlite3_deserialize,
130685 sqlite3_serialize,
130686 #else
130687 0,
130688 0,
 
130689 #endif
130690 sqlite3_db_name
130691 };
130692
130693 /* True if x is the directory separator character
130694 */
130695 #if SQLITE_OS_WIN
@@ -135849,15 +135901,15 @@
135901 }
135902 return 0;
135903 }
135904
135905 /*
135906 ** Set the EP_OuterON property on all terms of the given expression.
135907 ** And set the Expr.w.iJoin to iTable for every term in the
135908 ** expression.
135909 **
135910 ** The EP_OuterON property is used on terms of an expression to tell
135911 ** the OUTER JOIN processing logic that this term is part of the
135912 ** join restriction specified in the ON or USING clause and not a part
135913 ** of the more general WHERE clause. These terms are moved over to the
135914 ** WHERE clause during join processing but we need to remember that they
135915 ** originated in the ON or USING clause.
@@ -135875,11 +135927,11 @@
135927 ** defer the handling of t1.x=5, it will be processed immediately
135928 ** after the t1 loop and rows with t1.x!=5 will never appear in
135929 ** the output, which is incorrect.
135930 */
135931 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){
135932 assert( joinFlag==EP_OuterON || joinFlag==EP_InnerON );
135933 while( p ){
135934 ExprSetProperty(p, joinFlag);
135935 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
135936 ExprSetVVAProperty(p, EP_NoReduce);
135937 p->w.iJoin = iTable;
@@ -135896,35 +135948,41 @@
135948 p = p->pRight;
135949 }
135950 }
135951
135952 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
135953 ** term that is marked with EP_OuterON and w.iJoin==iTable into
135954 ** an ordinary term that omits the EP_OuterON mark.
135955 **
135956 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
135957 **
135958 ** If nullable is true, that means that Expr p might evaluate to NULL even
135959 ** if it is a reference to a NOT NULL column. This can happen, for example,
135960 ** if the table that p references is on the left side of a RIGHT JOIN.
135961 ** If nullable is true, then take care to not remove the EP_CanBeNull bit.
135962 ** See forum thread https://sqlite.org/forum/forumpost/b40696f50145d21c
135963 */
135964 static void unsetJoinExpr(Expr *p, int iTable, int nullable){
135965 while( p ){
135966 if( ExprHasProperty(p, EP_OuterON)
135967 && (iTable<0 || p->w.iJoin==iTable) ){
135968 ExprClearProperty(p, EP_OuterON);
135969 ExprSetProperty(p, EP_InnerON);
135970 }
135971 if( p->op==TK_COLUMN && p->iTable==iTable && !nullable ){
135972 ExprClearProperty(p, EP_CanBeNull);
135973 }
135974 if( p->op==TK_FUNCTION ){
135975 assert( ExprUseXList(p) );
135976 if( p->x.pList ){
135977 int i;
135978 for(i=0; i<p->x.pList->nExpr; i++){
135979 unsetJoinExpr(p->x.pList->a[i].pExpr, iTable, nullable);
135980 }
135981 }
135982 }
135983 unsetJoinExpr(p->pLeft, iTable, nullable);
135984 p = p->pRight;
135985 }
135986 }
135987
135988 /*
@@ -135934,12 +135992,12 @@
135992 ** do not need to be concerned with NATURAL joins and we only have
135993 ** think about USING joins.
135994 **
135995 ** * ON and USING clauses result in extra terms being added to the
135996 ** WHERE clause to enforce the specified constraints. The extra
135997 ** WHERE clause terms will be tagged with EP_OuterON or
135998 ** EP_InnerON so that we know that they originated in ON/USING.
135999 **
136000 ** The terms of a FROM clause are contained in the Select.pSrc structure.
136001 ** The left most table is the first entry in Select.pSrc. The right-most
136002 ** table is the last entry. The join operator is held in the entry to
136003 ** the right. Thus entry 1 contains the join operator for the join between
@@ -135960,11 +136018,11 @@
136018 for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
136019 Table *pRightTab = pRight->pTab;
136020 u32 joinType;
136021
136022 if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
136023 joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON;
136024
136025 /* If this is a NATURAL join, synthesize an approprate USING clause
136026 ** to specify which columns should be joined.
136027 */
136028 if( pRight->fg.jointype & JT_NATURAL ){
@@ -136081,10 +136139,11 @@
136139 */
136140 else if( pRight->u3.pOn ){
136141 sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
136142 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
136143 pRight->u3.pOn = 0;
136144 pRight->fg.isOn = 1;
136145 }
136146 }
136147 return 0;
136148 }
136149
@@ -137664,14 +137723,15 @@
137723 pColExpr = pColExpr->pRight;
137724 assert( pColExpr!=0 );
137725 }
137726 if( pColExpr->op==TK_COLUMN
137727 && ALWAYS( ExprUseYTab(pColExpr) )
137728 && ALWAYS( pColExpr->y.pTab!=0 )
137729 ){
137730 /* For columns use the column name name */
137731 int iCol = pColExpr->iColumn;
137732 pTab = pColExpr->y.pTab;
137733 if( iCol<0 ) iCol = pTab->iPKey;
137734 zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
137735 }else if( pColExpr->op==TK_ID ){
137736 assert( !ExprHasProperty(pColExpr, EP_IntValue) );
137737 zName = pColExpr->u.zToken;
@@ -139233,13 +139293,14 @@
139293 static Expr *substExpr(
139294 SubstContext *pSubst, /* Description of the substitution */
139295 Expr *pExpr /* Expr in which substitution occurs */
139296 ){
139297 if( pExpr==0 ) return 0;
139298 if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON)
139299 && pExpr->w.iJoin==pSubst->iTable
139300 ){
139301 testcase( ExprHasProperty(pExpr, EP_InnerON) );
139302 pExpr->w.iJoin = pSubst->iNewTable;
139303 }
139304 if( pExpr->op==TK_COLUMN
139305 && pExpr->iTable==pSubst->iTable
139306 && !ExprHasProperty(pExpr, EP_FixedCol)
@@ -139274,16 +139335,21 @@
139335 return pExpr;
139336 }
139337 if( pSubst->isOuterJoin ){
139338 ExprSetProperty(pNew, EP_CanBeNull);
139339 }
139340 if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
139341 sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
139342 pExpr->flags & (EP_OuterON|EP_InnerON));
139343 }
139344 sqlite3ExprDelete(db, pExpr);
139345 pExpr = pNew;
139346 if( pExpr->op==TK_TRUEFALSE ){
139347 pExpr->u.iValue = sqlite3ExprTruthValue(pExpr);
139348 pExpr->op = TK_INTEGER;
139349 ExprSetProperty(pExpr, EP_IntValue);
139350 }
139351
139352 /* Ensure that the expression now has an implicit collation sequence,
139353 ** just as it did when it was a column of a view or sub-query. */
139354 if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){
139355 CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
@@ -139440,11 +139506,11 @@
139506 static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){
139507 int op = pExpr->op;
139508 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
139509 renumberCursorDoMapping(pWalker, &pExpr->iTable);
139510 }
139511 if( ExprHasProperty(pExpr, EP_OuterON) ){
139512 renumberCursorDoMapping(pWalker, &pExpr->w.iJoin);
139513 }
139514 return WRC_Continue;
139515 }
139516
@@ -139633,10 +139699,15 @@
139699 ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
139700 ** is the first element of the parent query.
139701 **
139702 ** (28) The subquery is not a MATERIALIZED CTE.
139703 **
139704 ** (29) Either the subquery is not the right-hand operand of a join with an
139705 ** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or
139706 ** the right-most table within the FROM clause of the subquery
139707 ** is not part of an outer join.
139708 **
139709 **
139710 ** In this routine, the "p" parameter is a pointer to the outer query.
139711 ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
139712 ** uses aggregates.
139713 **
@@ -139759,10 +139830,39 @@
139830 return 0; /* Restriction (27) */
139831 }
139832 if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
139833 return 0; /* (28) */
139834 }
139835
139836 /* Restriction (29):
139837 **
139838 ** We do not want two constraints on the same term of the flattened
139839 ** query where one constraint has EP_InnerON and the other is EP_OuterON.
139840 ** To prevent this, one or the other of the following conditions must be
139841 ** false:
139842 **
139843 ** (29a) The right-most entry in the FROM clause of the subquery
139844 ** must not be part of an outer join.
139845 **
139846 ** (29b) The subquery itself must not be the right operand of a
139847 ** NATURAL join or a join that as an ON or USING clause.
139848 **
139849 ** These conditions are sufficient to keep an EP_OuterON from being
139850 ** flattened into an EP_InnerON. Restrictions (3a) and (27) prevent
139851 ** an EP_InnerON from being flattened into an EP_OuterON.
139852 */
139853 if( pSubSrc->nSrc>=2
139854 && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0
139855 ){
139856 if( (pSubitem->fg.jointype & JT_NATURAL)!=0
139857 || pSubitem->fg.isUsing
139858 || NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */
139859 || pSubitem->fg.isOn
139860 ){
139861 return 0;
139862 }
139863 }
139864
139865 /* Restriction (17): If the sub-query is a compound SELECT, then it must
139866 ** use only the UNION ALL operator. And none of the simple select queries
139867 ** that make up the compound SELECT are allowed to be aggregate or distinct
139868 ** queries.
@@ -140018,11 +140118,11 @@
140118 pSub->pOrderBy = 0;
140119 }
140120 pWhere = pSub->pWhere;
140121 pSub->pWhere = 0;
140122 if( isOuterJoin>0 ){
140123 sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON);
140124 }
140125 if( pWhere ){
140126 if( pParent->pWhere ){
140127 pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
140128 }else{
@@ -140151,11 +140251,15 @@
140251 ** found, add it to the pConst structure.
140252 */
140253 static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
140254 Expr *pRight, *pLeft;
140255 if( NEVER(pExpr==0) ) return;
140256 if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){
140257 testcase( ExprHasProperty(pExpr, EP_OuterON) );
140258 testcase( ExprHasProperty(pExpr, EP_InnerON) );
140259 return;
140260 }
140261 if( pExpr->op==TK_AND ){
140262 findConstInWhere(pConst, pExpr->pRight);
140263 findConstInWhere(pConst, pExpr->pLeft);
140264 return;
140265 }
@@ -140187,13 +140291,13 @@
140291 int bIgnoreAffBlob
140292 ){
140293 int i;
140294 if( pConst->pOomFault[0] ) return WRC_Prune;
140295 if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
140296 if( ExprHasProperty(pExpr, EP_FixedCol|EP_OuterON) ){
140297 testcase( ExprHasProperty(pExpr, EP_FixedCol) );
140298 testcase( ExprHasProperty(pExpr, EP_OuterON) );
140299 return WRC_Continue;
140300 }
140301 for(i=0; i<pConst->nConst; i++){
140302 Expr *pColumn = pConst->apExpr[i*2];
140303 if( pColumn==pExpr ) continue;
@@ -140474,16 +140578,16 @@
140578 pWhere = pWhere->pLeft;
140579 }
140580
140581 #if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */
140582 if( isLeftJoin
140583 && (ExprHasProperty(pWhere,EP_OuterON)==0
140584 || pWhere->w.iJoin!=iCursor)
140585 ){
140586 return 0; /* restriction (4) */
140587 }
140588 if( ExprHasProperty(pWhere,EP_OuterON)
140589 && pWhere->w.iJoin!=iCursor
140590 ){
140591 return 0; /* restriction (5) */
140592 }
140593 #endif
@@ -140492,11 +140596,11 @@
140596 nChng++;
140597 pSubq->selFlags |= SF_PushDown;
140598 while( pSubq ){
140599 SubstContext x;
140600 pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
140601 unsetJoinExpr(pNew, -1, 1);
140602 x.pParse = pParse;
140603 x.iTable = pSrc->iCursor;
140604 x.iNewTable = pSrc->iCursor;
140605 x.isOuterJoin = 0;
140606 x.pEList = pSubq->pEList;
@@ -141988,10 +142092,33 @@
142092 }
142093 #endif
142094 return 1;
142095 }
142096 #endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
142097
142098 /*
142099 ** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same
142100 ** as pSrcItem but has the same alias as p0, then return true.
142101 ** Otherwise return false.
142102 */
142103 static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
142104 int i;
142105 for(i=0; i<pSrc->nSrc; i++){
142106 SrcItem *p1 = &pSrc->a[i];
142107 if( p1==p0 ) continue;
142108 if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
142109 return 1;
142110 }
142111 if( p1->pSelect
142112 && (p1->pSelect->selFlags & SF_NestedFrom)!=0
142113 && sameSrcAlias(p0, p1->pSelect->pSrc)
142114 ){
142115 return 1;
142116 }
142117 }
142118 return 0;
142119 }
142120
142121 /*
142122 ** Generate code for the SELECT statement given in the p argument.
142123 **
142124 ** The results are returned according to the SelectDest structure.
@@ -142093,19 +142220,16 @@
142220 ** systems handle this case differently, and not all the same way,
142221 ** which is just confusing. To avoid this, we follow PG's lead and
142222 ** disallow it altogether. */
142223 if( p->selFlags & SF_UFSrcCheck ){
142224 SrcItem *p0 = &p->pSrc->a[0];
142225 if( sameSrcAlias(p0, p->pSrc) ){
142226 sqlite3ErrorMsg(pParse,
142227 "target object/alias may not appear in FROM clause: %s",
142228 p0->zAlias ? p0->zAlias : p0->pTab->zName
142229 );
142230 goto select_end;
 
 
 
142231 }
142232
142233 /* Clear the SF_UFSrcCheck flag. The check has already been performed,
142234 ** and leaving this flag set can cause errors if a compound sub-query
142235 ** in p->pSrc is flattened into this query and this function called
@@ -142156,11 +142280,12 @@
142280 && OptimizationEnabled(db, SQLITE_SimplifyJoin)
142281 ){
142282 SELECTTRACE(0x100,pParse,p,
142283 ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
142284 pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
142285 unsetJoinExpr(p->pWhere, pItem->iCursor,
142286 pTabList->a[0].fg.jointype & JT_LTORJ);
142287 }
142288
142289 /* No futher action if this term of the FROM clause is no a subquery */
142290 if( pSub==0 ) continue;
142291
@@ -142376,11 +142501,11 @@
142501 zSavedAuthContext = pParse->zAuthContext;
142502 pParse->zAuthContext = pItem->zName;
142503
142504 /* Generate code to implement the subquery
142505 **
142506 ** The subquery is implemented as a co-routine all if the following are
142507 ** true:
142508 **
142509 ** (1) the subquery is guaranteed to be the outer loop (so that
142510 ** it does not need to be computed more than once), and
142511 ** (2) the subquery is not a CTE that should be materialized
@@ -142434,15 +142559,15 @@
142559 /* Materialize the view. If the view is not correlated, generate a
142560 ** subroutine to do the materialization so that subsequent uses of
142561 ** the same view can reuse the materialization. */
142562 int topAddr;
142563 int onceAddr = 0;
 
142564
142565 pItem->regReturn = ++pParse->nMem;
142566 topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
142567 pItem->addrFillSub = topAddr+1;
142568 pItem->fg.isMaterialized = 1;
142569 if( pItem->fg.isCorrelated==0 ){
142570 /* If the subquery is not correlated and if we are not inside of
142571 ** a trigger, then we only need to compute the value of the subquery
142572 ** once. */
142573 onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
@@ -142453,13 +142578,13 @@
142578 sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
142579 ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem));
142580 sqlite3Select(pParse, pSub, &dest);
142581 pItem->pTab->nRowLogEst = pSub->nSelectRow;
142582 if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
142583 sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
142584 VdbeComment((v, "end %!S", pItem));
142585 sqlite3VdbeJumpHere(v, topAddr);
142586 sqlite3ClearTempRegCache(pParse);
142587 if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
142588 CteUse *pCteUse = pItem->u2.pCteUse;
142589 pCteUse->addrM9e = pItem->addrFillSub;
142590 pCteUse->regRtn = pItem->regReturn;
@@ -143178,11 +143303,11 @@
143303 }
143304 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
143305 eDist = sqlite3WhereIsDistinct(pWInfo);
143306 updateAccumulator(pParse, regAcc, pAggInfo, eDist);
143307 if( eDist!=WHERE_DISTINCT_NOOP ){
143308 struct AggInfo_func *pF = pAggInfo->aFunc;
143309 if( pF ){
143310 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
143311 }
143312 }
143313
@@ -143977,11 +144102,11 @@
144102 ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
144103 */
144104 SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
144105 Parse *pParse, /* Parser */
144106 Token *pTableName, /* Name of the table to be updated */
144107 SrcList *pFrom, /* FROM clause for an UPDATE-FROM, or NULL */
144108 ExprList *pEList, /* The SET clause: list of column and new values */
144109 Expr *pWhere, /* The WHERE clause */
144110 u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
144111 const char *zStart, /* Start of SQL text */
144112 const char *zEnd /* End of SQL text */
@@ -144313,10 +144438,18 @@
144438 if( pSchema!=db->aDb[1].pSchema ){
144439 pSrc->a[0].pSchema = pSchema;
144440 }
144441 if( pStep->pFrom ){
144442 SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
144443 if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){
144444 Select *pSubquery;
144445 Token as;
144446 pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0);
144447 as.n = 0;
144448 as.z = 0;
144449 pDup = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
144450 }
144451 pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup);
144452 }
144453 }else{
144454 sqlite3DbFree(db, zName);
144455 }
@@ -145944,11 +146077,11 @@
146077 if( pPk ){
146078 sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
146079 }else{
146080 sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
146081 }
146082 VdbeCoverage(v);
146083 }
146084
146085 /* Do FK constraint checks. */
146086 if( hasFK ){
146087 sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
@@ -148402,11 +148535,11 @@
148535 ** This object is a header on a block of allocated memory that will be
148536 ** automatically freed when its WInfo oject is destructed.
148537 */
148538 struct WhereMemBlock {
148539 WhereMemBlock *pNext; /* Next block in the chain */
148540 u64 sz; /* Bytes of space */
148541 };
148542
148543 /*
148544 ** Extra information attached to a WhereLevel that is a RIGHT JOIN.
148545 */
@@ -148973,12 +149106,13 @@
149106 #define WO_ISNULL 0x0100
149107 #define WO_OR 0x0200 /* Two or more OR-connected terms */
149108 #define WO_AND 0x0400 /* Two or more AND-connected terms */
149109 #define WO_EQUIV 0x0800 /* Of the form A==B, both columns */
149110 #define WO_NOOP 0x1000 /* This term does not restrict search space */
149111 #define WO_ROWVAL 0x2000 /* A row-value term */
149112
149113 #define WO_ALL 0x3fff /* Mask of all possible WO_* values */
149114 #define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */
149115
149116 /*
149117 ** These are definitions of bits in the WhereLoop.wsFlags field.
149118 ** The particular combination of bits in each WhereLoop help to
@@ -149344,11 +149478,11 @@
149478 */
149479 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
149480 int nLoop = 0;
149481 assert( pTerm!=0 );
149482 while( (pTerm->wtFlags & TERM_CODED)==0
149483 && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_OuterON))
149484 && (pLevel->notReady & pTerm->prereqAll)==0
149485 ){
149486 if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
149487 pTerm->wtFlags |= TERM_LIKECOND;
149488 }else{
@@ -149617,12 +149751,11 @@
149751 pExpr->iTable = iTab;
149752 }
149753 sqlite3ExprDelete(db, pX);
149754 }else{
149755 aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
149756 eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
 
149757 }
149758 pX = pExpr;
149759 }
149760
149761 if( eType==IN_INDEX_INDEX_DESC ){
@@ -150066,20 +150199,20 @@
150199 **
150200 ** are also excluded. See codeCursorHintIsOrFunction() for details.
150201 */
150202 if( pTabItem->fg.jointype & JT_LEFT ){
150203 Expr *pExpr = pTerm->pExpr;
150204 if( !ExprHasProperty(pExpr, EP_OuterON)
150205 || pExpr->w.iJoin!=pTabItem->iCursor
150206 ){
150207 sWalker.eCode = 0;
150208 sWalker.xExprCallback = codeCursorHintIsOrFunction;
150209 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
150210 if( sWalker.eCode ) continue;
150211 }
150212 }else{
150213 if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) continue;
150214 }
150215
150216 /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
150217 ** the cursor. These terms are not needed as hints for a pure range
150218 ** scan (that has no == terms) so omit them. */
@@ -151406,11 +151539,11 @@
151539 WhereInfo *pSubWInfo; /* Info for single OR-term scan */
151540 Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
151541 Expr *pDelete; /* Local copy of OR clause term */
151542 int jmp1 = 0; /* Address of jump operation */
151543 testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
151544 && !ExprHasProperty(pOrExpr, EP_OuterON)
151545 ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
151546 pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0);
151547 if( db->mallocFailed ){
151548 sqlite3ExprDelete(db, pDelete);
151549 continue;
@@ -151614,16 +151747,26 @@
151747 pWInfo->untestedTerms = 1;
151748 continue;
151749 }
151750 pE = pTerm->pExpr;
151751 assert( pE!=0 );
151752 if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){
151753 if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){
151754 /* Defer processing WHERE clause constraints until after outer
151755 ** join processing. tag-20220513a */
151756 continue;
151757 }else if( (pTabItem->fg.jointype & JT_LEFT)==JT_LEFT
151758 && !ExprHasProperty(pE,EP_OuterON) ){
151759 continue;
151760 }else{
151761 Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin);
151762 if( m & pLevel->notReady ){
151763 /* An ON clause that is not ripe */
151764 continue;
151765 }
151766 }
151767 }
 
151768 if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
151769 iNext = 2;
151770 continue;
151771 }
151772 if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){
@@ -151678,19 +151821,19 @@
151821 WhereTerm *pAlt;
151822 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151823 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
151824 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
151825 if( pTerm->leftCursor!=iCur ) continue;
151826 if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue;
151827 pE = pTerm->pExpr;
151828 #ifdef WHERETRACE_ENABLED /* 0x800 */
151829 if( sqlite3WhereTrace & 0x800 ){
151830 sqlite3DebugPrintf("Coding transitive constraint:\n");
151831 sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
151832 }
151833 #endif
151834 assert( !ExprHasProperty(pE, EP_OuterON) );
151835 assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
151836 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151837 pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
151838 WO_EQ|WO_IN|WO_IS, 0);
151839 if( pAlt==0 ) continue;
@@ -151757,22 +151900,12 @@
151900 */
151901 if( pLevel->iLeftJoin ){
151902 pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
151903 sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
151904 VdbeComment((v, "record LEFT JOIN hit"));
151905 if( pLevel->pRJ==0 ){
151906 goto code_outer_join_constraints; /* WHERE clause constraints */
 
 
 
 
 
 
 
 
 
 
151907 }
151908 }
151909
151910 if( pLevel->pRJ ){
151911 /* Create a subroutine used to process all interior loops and code
@@ -151784,10 +151917,30 @@
151917 WhereRightJoin *pRJ = pLevel->pRJ;
151918 sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn);
151919 pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v);
151920 assert( pParse->withinRJSubrtn < 255 );
151921 pParse->withinRJSubrtn++;
151922
151923 /* WHERE clause constraints must be deferred until after outer join
151924 ** row elimination has completed, since WHERE clause constraints apply
151925 ** to the results of the OUTER JOIN. The following loop generates the
151926 ** appropriate WHERE clause constraint checks. tag-20220513a.
151927 */
151928 code_outer_join_constraints:
151929 for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
151930 testcase( pTerm->wtFlags & TERM_VIRTUAL );
151931 testcase( pTerm->wtFlags & TERM_CODED );
151932 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
151933 if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
151934 assert( pWInfo->untestedTerms );
151935 continue;
151936 }
151937 if( pTabItem->fg.jointype & JT_LTORJ ) continue;
151938 assert( pTerm->pExpr );
151939 sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
151940 pTerm->wtFlags |= TERM_CODED;
151941 }
151942 }
151943
151944 #if WHERETRACE_ENABLED /* 0x20800 */
151945 if( sqlite3WhereTrace & 0x20000 ){
151946 sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
@@ -151837,13 +151990,17 @@
151990 }
151991 if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){
151992 mAll |= pLoop->maskSelf;
151993 for(k=0; k<pWC->nTerm; k++){
151994 WhereTerm *pTerm = &pWC->a[k];
151995 if( (pTerm->wtFlags & (TERM_VIRTUAL|TERM_SLICE))!=0
151996 && pTerm->eOperator!=WO_ROWVAL
151997 ){
151998 break;
151999 }
152000 if( pTerm->prereqAll & ~mAll ) continue;
152001 if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue;
152002 pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
152003 sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
152004 }
152005 }
152006 sFrom.nSrc = 1;
@@ -152351,12 +152508,12 @@
152508 /*
152509 ** If the pBase expression originated in the ON or USING clause of
152510 ** a join, then transfer the appropriate markings over to derived.
152511 */
152512 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
152513 if( pDerived && ExprHasProperty(pBase, EP_OuterON|EP_InnerON) ){
152514 pDerived->flags |= pBase->flags & (EP_OuterON|EP_InnerON);
152515 pDerived->w.iJoin = pBase->w.iJoin;
152516 }
152517 }
152518
152519 /*
@@ -152807,11 +152964,11 @@
152964 static int termIsEquivalence(Parse *pParse, Expr *pExpr){
152965 char aff1, aff2;
152966 CollSeq *pColl;
152967 if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
152968 if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
152969 if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;
152970 aff1 = sqlite3ExprAffinity(pExpr->pLeft);
152971 aff2 = sqlite3ExprAffinity(pExpr->pRight);
152972 if( aff1!=aff2
152973 && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
152974 ){
@@ -152995,22 +153152,30 @@
153152
153153 #ifdef SQLITE_DEBUG
153154 if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){
153155 printf("\n*** Incorrect prereqAll computed for:\n");
153156 sqlite3TreeViewExpr(0,pExpr,0);
153157 assert( 0 );
153158 }
153159 #endif
153160
153161 if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){
153162 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
153163 if( ExprHasProperty(pExpr, EP_OuterON) ){
153164 prereqAll |= x;
153165 extraRight = x-1; /* ON clause terms may not be used with an index
153166 ** on left table of a LEFT JOIN. Ticket #3015 */
153167 if( (prereqAll>>1)>=x ){
153168 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
153169 return;
153170 }
153171 }else if( (prereqAll>>1)>=x ){
153172 /* The ON clause of an INNER JOIN references a table to its right.
153173 ** Most other SQL database engines raise an error. But all versions
153174 ** of SQLite going back to 3.0.0 have just put the ON clause constraint
153175 ** into the WHERE clause and carried on. */
153176 ExprClearProperty(pExpr, EP_InnerON);
153177 }
153178 }
153179 pTerm->prereqAll = prereqAll;
153180 pTerm->leftCursor = -1;
153181 pTerm->iParent = -1;
@@ -153074,11 +153239,11 @@
153239 pNew->prereqRight = prereqLeft | extraRight;
153240 pNew->prereqAll = prereqAll;
153241 pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
153242 }else
153243 if( op==TK_ISNULL
153244 && !ExprHasProperty(pExpr,EP_OuterON)
153245 && 0==sqlite3ExprCanBeNull(pLeft)
153246 ){
153247 assert( !ExprHasProperty(pExpr, EP_IntValue) );
153248 pExpr->op = TK_TRUEFALSE;
153249 pExpr->u.zToken = "false";
@@ -153145,11 +153310,11 @@
153310 ** The virtual term must be tagged with TERM_VNULL.
153311 */
153312 else if( pExpr->op==TK_NOTNULL ){
153313 if( pExpr->pLeft->op==TK_COLUMN
153314 && pExpr->pLeft->iColumn>=0
153315 && !ExprHasProperty(pExpr, EP_OuterON)
153316 ){
153317 Expr *pNewExpr;
153318 Expr *pLeft = pExpr->pLeft;
153319 int idxNew;
153320 WhereTerm *pNewTerm;
@@ -153293,11 +153458,11 @@
153458 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
153459 exprAnalyze(pSrc, pWC, idxNew);
153460 }
153461 pTerm = &pWC->a[idxTerm];
153462 pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
153463 pTerm->eOperator = WO_ROWVAL;
153464 }
153465
153466 /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
153467 ** a virtual term for each vector component. The expression object
153468 ** used by each such virtual term is pExpr (the full vector IN(...)
@@ -153349,12 +153514,12 @@
153514 prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
153515 if( (prereqExpr & prereqColumn)==0 ){
153516 Expr *pNewExpr;
153517 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
153518 0, sqlite3ExprDup(db, pRight, 0));
153519 if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){
153520 ExprSetProperty(pNewExpr, EP_OuterON);
153521 pNewExpr->w.iJoin = pExpr->w.iJoin;
153522 }
153523 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
153524 testcase( idxNew==0 );
153525 pNewTerm = &pWC->a[idxNew];
@@ -153494,11 +153659,11 @@
153659 for(ii=0; ii<pWC->nTerm; ii++){
153660 if( pWC->a[ii].wtFlags & TERM_CODED ){
153661 /* This term is a vector operation that has been decomposed into
153662 ** other, subsequent terms. It can be ignored. See tag-20220128a */
153663 assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
153664 assert( pWC->a[ii].eOperator==WO_ROWVAL );
153665 continue;
153666 }
153667 if( pWC->a[ii].leftCursor!=iCsr ) return;
153668 }
153669
@@ -153717,13 +153882,13 @@
153882 pItem->colUsed |= sqlite3ExprColUsed(pColRef);
153883 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
153884 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
153885 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
153886 if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){
153887 joinType = EP_OuterON;
153888 }else{
153889 joinType = EP_InnerON;
153890 }
153891 sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType);
153892 whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
153893 }
153894 }
@@ -154060,11 +154225,11 @@
154225 if( pTerm->leftCursor==iCur
154226 && pTerm->u.x.leftColumn==iColumn
154227 && (iColumn!=XN_EXPR
154228 || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
154229 pScan->pIdxExpr,iCur)==0)
154230 && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_OuterON))
154231 ){
154232 if( (pTerm->eOperator & WO_EQUIV)!=0
154233 && pScan->nEquiv<ArraySize(pScan->aiCur)
154234 && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0
154235 ){
@@ -154412,10 +154577,11 @@
154577 if( pOp->opcode==OP_Column ){
154578 pOp->opcode = OP_Copy;
154579 pOp->p1 = pOp->p2 + iRegister;
154580 pOp->p2 = pOp->p3;
154581 pOp->p3 = 0;
154582 pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */
154583 }else if( pOp->opcode==OP_Rowid ){
154584 pOp->opcode = OP_Sequence;
154585 pOp->p1 = iAutoidxCur;
154586 #ifdef SQLITE_ALLOW_ROWID_IN_VIEW
154587 if( iAutoidxCur==0 ){
@@ -154486,18 +154652,21 @@
154652 const Bitmask notReady /* Tables in outer loops of the join */
154653 ){
154654 char aff;
154655 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
154656 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
154657 assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
154658 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
154659 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
154660 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
154661 testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
154662 testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
154663 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
154664 || pTerm->pExpr->w.iJoin != pSrc->iCursor
154665 ){
154666 return 0; /* See tag-20191211-001 */
154667 }
154668 }
154669 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
154670 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
154671 if( pTerm->u.x.leftColumn<0 ) return 0;
154672 aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
@@ -154907,17 +155076,24 @@
155076 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155077 assert( pTerm->u.x.leftColumn>=XN_ROWID );
155078 assert( pTerm->u.x.leftColumn<pTab->nCol );
155079
155080 /* tag-20191211-002: WHERE-clause constraints are not useful to the
155081 ** right-hand table of a LEFT JOIN nor to the either table of a
155082 ** RIGHT JOIN. See tag-20191211-001 for the
155083 ** equivalent restriction for ordinary tables. */
155084 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
155085 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
155086 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
155087 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
155088 testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) );
155089 testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
155090 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
155091 || pTerm->pExpr->w.iJoin != pSrc->iCursor
155092 ){
155093 continue;
155094 }
155095 }
155096 nTerm++;
155097 pTerm->wtFlags |= TERM_OK;
155098 }
155099
@@ -155789,11 +155965,11 @@
155965 char zType[8];
155966 char zLeft[50];
155967 memcpy(zType, "....", 5);
155968 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
155969 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
155970 if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) zType[2] = 'L';
155971 if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
155972 if( pTerm->eOperator & WO_SINGLE ){
155973 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
155974 sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
155975 pTerm->leftCursor, pTerm->u.x.leftColumn);
@@ -156563,16 +156739,32 @@
156739 ** to mix with a lower range bound from some other source */
156740 if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
156741
156742 /* tag-20191211-001: Do not allow constraints from the WHERE clause to
156743 ** be used by the right table of a LEFT JOIN nor by the left table of a
156744 ** RIGHT JOIN. Only constraints in the ON clause are allowed.
156745 ** See tag-20191211-002 for the vtab equivalent.
156746 **
156747 ** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f
156748 ** for an example of a WHERE clause constraints that may not be used on
156749 ** the right table of a RIGHT JOIN because the constraint implies a
156750 ** not-NULL condition on the left table of the RIGHT JOIN.
156751 **
156752 ** 2022-06-10: The same condition applies to termCanDriveIndex() above.
156753 ** https://sqlite.org/forum/forumpost/51e6959f61
156754 */
156755 if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
156756 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
156757 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
156758 testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
156759 testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
156760 testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
156761 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
156762 || pTerm->pExpr->w.iJoin != pSrc->iCursor
156763 ){
156764 continue;
156765 }
156766 }
156767
156768 if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
156769 pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
156770 }else{
@@ -156920,27 +157112,30 @@
157112 /* Check to see if a partial index with pPartIndexWhere can be used
157113 ** in the current query. Return true if it can be and false if not.
157114 */
157115 static int whereUsablePartialIndex(
157116 int iTab, /* The table for which we want an index */
157117 u8 jointype, /* The JT_* flags on the join */
157118 WhereClause *pWC, /* The WHERE clause of the query */
157119 Expr *pWhere /* The WHERE clause from the partial index */
157120 ){
157121 int i;
157122 WhereTerm *pTerm;
157123 Parse *pParse;
157124
157125 if( jointype & JT_LTORJ ) return 0;
157126 pParse = pWC->pWInfo->pParse;
157127 while( pWhere->op==TK_AND ){
157128 if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0;
157129 pWhere = pWhere->pRight;
157130 }
157131 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
157132 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
157133 Expr *pExpr;
157134 pExpr = pTerm->pExpr;
157135 if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
157136 && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
157137 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
157138 && (pTerm->wtFlags & TERM_VNULL)==0
157139 ){
157140 return 1;
157141 }
@@ -157102,13 +157297,12 @@
157297 /* Loop over all indices. If there was an INDEXED BY clause, then only
157298 ** consider index pProbe. */
157299 for(; rc==SQLITE_OK && pProbe;
157300 pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++
157301 ){
 
157302 if( pProbe->pPartIdxWhere!=0
157303 && !whereUsablePartialIndex(pSrc->iCursor, pSrc->fg.jointype, pWC,
157304 pProbe->pPartIdxWhere)
157305 ){
157306 testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
157307 continue; /* Partial index inappropriate for this query */
157308 }
@@ -157212,11 +157406,18 @@
157406
157407 pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup);
157408 }
157409 ApplyCostMultiplier(pNew->rRun, pTab->costMult);
157410 whereLoopOutputAdjust(pWC, pNew, rSize);
157411 if( (pSrc->fg.jointype & JT_RIGHT)!=0 && pProbe->aColExpr ){
157412 /* Do not do an SCAN of a index-on-expression in a RIGHT JOIN
157413 ** because the cursor used to access the index might not be
157414 ** positioned to the correct row during the right-join no-match
157415 ** loop. */
157416 }else{
157417 rc = whereLoopInsert(pBuilder, pNew);
157418 }
157419 pNew->nOut = rSize;
157420 if( rc ) break;
157421 }
157422 }
157423
@@ -157387,10 +157588,11 @@
157588 pIdxInfo->orderByConsumed = 0;
157589 pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
157590 *pbIn = 1; assert( (mExclude & WO_IN)==0 );
157591 }
157592
157593 assert( pbRetryLimit || !isLimitTerm(pTerm) );
157594 if( isLimitTerm(pTerm) && *pbIn ){
157595 /* If there is an IN(...) term handled as an == (separate call to
157596 ** xFilter for each value on the RHS of the IN) and a LIMIT or
157597 ** OFFSET term handled as well, the plan is unusable. Set output
157598 ** variable *pbRetryLimit to true to tell the caller to retry with
@@ -157860,11 +158062,13 @@
158062 SrcList *pTabList = pWInfo->pTabList;
158063 SrcItem *pItem;
158064 SrcItem *pEnd = &pTabList->a[pWInfo->nLevel];
158065 sqlite3 *db = pWInfo->pParse->db;
158066 int rc = SQLITE_OK;
158067 int bFirstPastRJ = 0;
158068 WhereLoop *pNew;
158069
158070
158071 /* Loop over the tables in the join, from left to right */
158072 pNew = pBuilder->pNew;
158073 whereLoopInit(pNew);
158074 pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
@@ -157871,14 +158075,17 @@
158075 for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
158076 Bitmask mUnusable = 0;
158077 pNew->iTab = iTab;
158078 pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
158079 pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
158080 if( bFirstPastRJ || (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
158081 /* Add prerequisites to prevent reordering of FROM clause terms
158082 ** across CROSS joins and outer joins. The bFirstPastRJ boolean
158083 ** prevents the right operand of a RIGHT JOIN from being swapped with
158084 ** other elements even further to the right. */
158085 mPrereq |= mPrior;
158086 bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
158087 }
158088 #ifndef SQLITE_OMIT_VIRTUALTABLE
158089 if( IsVirtual(pItem->pTab) ){
158090 SrcItem *p;
158091 for(p=&pItem[1]; p<pEnd; p++){
@@ -158944,11 +159151,11 @@
159151 }
159152 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
159153 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
159154 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
159155 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
159156 if( !ExprHasProperty(pTerm->pExpr, EP_OuterON)
159157 || pTerm->pExpr->w.iJoin!=pItem->iCursor
159158 ){
159159 break;
159160 }
159161 }
@@ -159570,10 +159777,11 @@
159777 op = OP_ReopenIdx;
159778 }else{
159779 iIndexCur = pParse->nTab++;
159780 }
159781 pLevel->iIdxCur = iIndexCur;
159782 assert( pIx!=0 );
159783 assert( pIx->pSchema==pTab->pSchema );
159784 assert( iIndexCur>=0 );
159785 if( op ){
159786 sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
159787 sqlite3VdbeSetP4KeyInfo(pParse, pIx);
@@ -159645,13 +159853,24 @@
159853 ** program.
159854 */
159855 for(ii=0; ii<nTabList; ii++){
159856 int addrExplain;
159857 int wsFlags;
159858 SrcItem *pSrc;
159859 if( pParse->nErr ) goto whereBeginError;
159860 pLevel = &pWInfo->a[ii];
159861 wsFlags = pLevel->pWLoop->wsFlags;
159862 pSrc = &pTabList->a[pLevel->iFrom];
159863 if( pSrc->fg.isMaterialized ){
159864 if( pSrc->fg.isCorrelated ){
159865 sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
159866 }else{
159867 int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
159868 sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
159869 sqlite3VdbeJumpHere(v, iOnce);
159870 }
159871 }
159872 if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
159873 if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
159874 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
159875 constructAutomaticIndex(pParse, &pWInfo->sWC,
159876 &pTabList->a[pLevel->iFrom], notReady, pLevel);
@@ -159739,10 +159958,11 @@
159958 WhereLevel *pLevel;
159959 WhereLoop *pLoop;
159960 SrcList *pTabList = pWInfo->pTabList;
159961 sqlite3 *db = pParse->db;
159962 int iEnd = sqlite3VdbeCurrentAddr(v);
159963 int nRJ = 0;
159964
159965 /* Generate loop termination code.
159966 */
159967 VdbeModuleComment((v, "End WHERE-core"));
159968 for(i=pWInfo->nLevel-1; i>=0; i--){
@@ -159755,12 +159975,11 @@
159975 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
159976 pLevel->addrCont = 0;
159977 pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v);
159978 sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
159979 VdbeCoverage(v);
159980 nRJ++;
 
159981 }
159982 pLoop = pLevel->pWLoop;
159983 if( pLevel->op!=OP_Noop ){
159984 #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
159985 int addrSeek = 0;
@@ -159898,10 +160117,11 @@
160117 VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
160118 pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
160119 }
160120
160121 assert( pWInfo->nLevel<=pTabList->nSrc );
160122 if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
160123 for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
160124 int k, last;
160125 VdbeOp *pOp, *pLastOp;
160126 Index *pIdx = 0;
160127 SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
@@ -160034,13 +160254,13 @@
160254 */
160255 sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
160256
160257 /* Final cleanup
160258 */
 
160259 pParse->nQueryLoop = pWInfo->savedNQueryLoop;
160260 whereInfoFree(db, pWInfo);
160261 pParse->withinRJSubrtn -= nRJ;
160262 return;
160263 }
160264
160265 /************** End of where.c ***********************************************/
160266 /************** Begin file window.c ******************************************/
@@ -163662,22 +163882,22 @@
163882 #define sqlite3ParserCTX_PDECL ,Parse *pParse
163883 #define sqlite3ParserCTX_PARAM ,pParse
163884 #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
163885 #define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
163886 #define YYFALLBACK 1
163887 #define YYNSTATE 576
163888 #define YYNRULE 405
163889 #define YYNRULE_WITH_ACTION 342
163890 #define YYNTOKEN 185
163891 #define YY_MAX_SHIFT 575
163892 #define YY_MIN_SHIFTREDUCE 835
163893 #define YY_MAX_SHIFTREDUCE 1239
163894 #define YY_ERROR_ACTION 1240
163895 #define YY_ACCEPT_ACTION 1241
163896 #define YY_NO_ACTION 1242
163897 #define YY_MIN_REDUCE 1243
163898 #define YY_MAX_REDUCE 1647
163899 /************* End control #defines *******************************************/
163900 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
163901
163902 /* Define the yytestcase() macro to be a no-op if is not already defined
163903 ** otherwise.
@@ -163740,219 +163960,222 @@
163960 ** yy_reduce_ofst[] For each state, the offset into yy_action for
163961 ** shifting non-terminals after a reduce.
163962 ** yy_default[] Default action for each state.
163963 **
163964 *********** Begin parsing tables **********************************************/
163965 #define YY_ACTTAB_COUNT (2098)
163966 static const YYACTIONTYPE yy_action[] = {
163967 /* 0 */ 568, 208, 568, 118, 115, 229, 568, 118, 115, 229,
163968 /* 10 */ 568, 1314, 377, 1293, 408, 562, 562, 562, 568, 409,
163969 /* 20 */ 378, 1314, 1276, 41, 41, 41, 41, 208, 1526, 71,
163970 /* 30 */ 71, 971, 419, 41, 41, 491, 303, 279, 303, 972,
163971 /* 40 */ 397, 71, 71, 125, 126, 80, 1217, 1217, 1050, 1053,
163972 /* 50 */ 1040, 1040, 123, 123, 124, 124, 124, 124, 476, 409,
163973 /* 60 */ 1241, 1, 1, 575, 2, 1245, 550, 118, 115, 229,
163974 /* 70 */ 317, 480, 146, 480, 524, 118, 115, 229, 529, 1327,
163975 /* 80 */ 417, 523, 142, 125, 126, 80, 1217, 1217, 1050, 1053,
163976 /* 90 */ 1040, 1040, 123, 123, 124, 124, 124, 124, 118, 115,
163977 /* 100 */ 229, 327, 122, 122, 122, 122, 121, 121, 120, 120,
163978 /* 110 */ 120, 119, 116, 444, 284, 284, 284, 284, 442, 442,
163979 /* 120 */ 442, 1567, 376, 1569, 1192, 375, 1163, 565, 1163, 565,
163980 /* 130 */ 409, 1567, 537, 259, 226, 444, 101, 145, 449, 316,
163981 /* 140 */ 559, 240, 122, 122, 122, 122, 121, 121, 120, 120,
163982 /* 150 */ 120, 119, 116, 444, 125, 126, 80, 1217, 1217, 1050,
163983 /* 160 */ 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, 142,
163984 /* 170 */ 294, 1192, 339, 448, 120, 120, 120, 119, 116, 444,
163985 /* 180 */ 127, 1192, 1193, 1194, 148, 441, 440, 568, 119, 116,
163986 /* 190 */ 444, 124, 124, 124, 124, 117, 122, 122, 122, 122,
163987 /* 200 */ 121, 121, 120, 120, 120, 119, 116, 444, 454, 113,
163988 /* 210 */ 13, 13, 546, 122, 122, 122, 122, 121, 121, 120,
163989 /* 220 */ 120, 120, 119, 116, 444, 422, 316, 559, 1192, 1193,
163990 /* 230 */ 1194, 149, 1224, 409, 1224, 124, 124, 124, 124, 122,
163991 /* 240 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116,
163992 /* 250 */ 444, 465, 342, 1037, 1037, 1051, 1054, 125, 126, 80,
163993 /* 260 */ 1217, 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124,
163994 /* 270 */ 124, 124, 1279, 522, 222, 1192, 568, 409, 224, 514,
163995 /* 280 */ 175, 82, 83, 122, 122, 122, 122, 121, 121, 120,
163996 /* 290 */ 120, 120, 119, 116, 444, 1007, 16, 16, 1192, 133,
163997 /* 300 */ 133, 125, 126, 80, 1217, 1217, 1050, 1053, 1040, 1040,
163998 /* 310 */ 123, 123, 124, 124, 124, 124, 122, 122, 122, 122,
163999 /* 320 */ 121, 121, 120, 120, 120, 119, 116, 444, 1041, 546,
164000 /* 330 */ 1192, 373, 1192, 1193, 1194, 252, 1434, 399, 504, 501,
164001 /* 340 */ 500, 111, 560, 566, 4, 926, 926, 433, 499, 340,
164002 /* 350 */ 460, 328, 360, 394, 1237, 1192, 1193, 1194, 563, 568,
164003 /* 360 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119,
164004 /* 370 */ 116, 444, 284, 284, 369, 1580, 1607, 441, 440, 154,
164005 /* 380 */ 409, 445, 71, 71, 1286, 565, 1221, 1192, 1193, 1194,
164006 /* 390 */ 85, 1223, 271, 557, 543, 515, 1561, 568, 98, 1222,
164007 /* 400 */ 6, 1278, 472, 142, 125, 126, 80, 1217, 1217, 1050,
164008 /* 410 */ 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, 550,
164009 /* 420 */ 13, 13, 1027, 507, 1224, 1192, 1224, 549, 109, 109,
164010 /* 430 */ 222, 568, 1238, 175, 568, 427, 110, 197, 445, 570,
164011 /* 440 */ 569, 430, 1552, 1017, 325, 551, 1192, 270, 287, 368,
164012 /* 450 */ 510, 363, 509, 257, 71, 71, 543, 71, 71, 359,
164013 /* 460 */ 316, 559, 1613, 122, 122, 122, 122, 121, 121, 120,
164014 /* 470 */ 120, 120, 119, 116, 444, 1017, 1017, 1019, 1020, 27,
164015 /* 480 */ 284, 284, 1192, 1193, 1194, 1158, 568, 1612, 409, 901,
164016 /* 490 */ 190, 550, 356, 565, 550, 937, 533, 517, 1158, 516,
164017 /* 500 */ 413, 1158, 552, 1192, 1193, 1194, 568, 544, 1554, 51,
164018 /* 510 */ 51, 214, 125, 126, 80, 1217, 1217, 1050, 1053, 1040,
164019 /* 520 */ 1040, 123, 123, 124, 124, 124, 124, 1192, 474, 135,
164020 /* 530 */ 135, 409, 284, 284, 1490, 505, 121, 121, 120, 120,
164021 /* 540 */ 120, 119, 116, 444, 1007, 565, 518, 217, 541, 1561,
164022 /* 550 */ 316, 559, 142, 6, 532, 125, 126, 80, 1217, 1217,
164023 /* 560 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164024 /* 570 */ 1555, 122, 122, 122, 122, 121, 121, 120, 120, 120,
164025 /* 580 */ 119, 116, 444, 485, 1192, 1193, 1194, 482, 281, 1267,
164026 /* 590 */ 957, 252, 1192, 373, 504, 501, 500, 1192, 340, 571,
164027 /* 600 */ 1192, 571, 409, 292, 499, 957, 876, 191, 480, 316,
164028 /* 610 */ 559, 384, 290, 380, 122, 122, 122, 122, 121, 121,
164029 /* 620 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164030 /* 630 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164031 /* 640 */ 124, 409, 394, 1136, 1192, 869, 100, 284, 284, 1192,
164032 /* 650 */ 1193, 1194, 373, 1093, 1192, 1193, 1194, 1192, 1193, 1194,
164033 /* 660 */ 565, 455, 32, 373, 233, 125, 126, 80, 1217, 1217,
164034 /* 670 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164035 /* 680 */ 1433, 959, 568, 228, 958, 122, 122, 122, 122, 121,
164036 /* 690 */ 121, 120, 120, 120, 119, 116, 444, 1158, 228, 1192,
164037 /* 700 */ 157, 1192, 1193, 1194, 1553, 13, 13, 301, 957, 1232,
164038 /* 710 */ 1158, 153, 409, 1158, 373, 1583, 1176, 5, 369, 1580,
164039 /* 720 */ 429, 1238, 3, 957, 122, 122, 122, 122, 121, 121,
164040 /* 730 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164041 /* 740 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164042 /* 750 */ 124, 409, 208, 567, 1192, 1028, 1192, 1193, 1194, 1192,
164043 /* 760 */ 388, 852, 155, 1552, 286, 402, 1098, 1098, 488, 568,
164044 /* 770 */ 465, 342, 1319, 1319, 1552, 125, 126, 80, 1217, 1217,
164045 /* 780 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164046 /* 790 */ 129, 568, 13, 13, 374, 122, 122, 122, 122, 121,
164047 /* 800 */ 121, 120, 120, 120, 119, 116, 444, 302, 568, 453,
164048 /* 810 */ 528, 1192, 1193, 1194, 13, 13, 1192, 1193, 1194, 1297,
164049 /* 820 */ 463, 1267, 409, 1317, 1317, 1552, 1012, 453, 452, 200,
164050 /* 830 */ 299, 71, 71, 1265, 122, 122, 122, 122, 121, 121,
164051 /* 840 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164052 /* 850 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164053 /* 860 */ 124, 409, 227, 1073, 1158, 284, 284, 419, 312, 278,
164054 /* 870 */ 278, 285, 285, 1419, 406, 405, 382, 1158, 565, 568,
164055 /* 880 */ 1158, 1196, 565, 1600, 565, 125, 126, 80, 1217, 1217,
164056 /* 890 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124,
164057 /* 900 */ 453, 1482, 13, 13, 1536, 122, 122, 122, 122, 121,
164058 /* 910 */ 121, 120, 120, 120, 119, 116, 444, 201, 568, 354,
164059 /* 920 */ 1586, 575, 2, 1245, 840, 841, 842, 1562, 317, 1212,
164060 /* 930 */ 146, 6, 409, 255, 254, 253, 206, 1327, 9, 1196,
164061 /* 940 */ 262, 71, 71, 424, 122, 122, 122, 122, 121, 121,
164062 /* 950 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217,
164063 /* 960 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164064 /* 970 */ 124, 568, 284, 284, 568, 1213, 409, 574, 313, 1245,
164065 /* 980 */ 349, 1296, 352, 419, 317, 565, 146, 491, 525, 1643,
164066 /* 990 */ 395, 371, 491, 1327, 70, 70, 1295, 71, 71, 240,
164067 /* 1000 */ 1325, 104, 80, 1217, 1217, 1050, 1053, 1040, 1040, 123,
164068 /* 1010 */ 123, 124, 124, 124, 124, 122, 122, 122, 122, 121,
164069 /* 1020 */ 121, 120, 120, 120, 119, 116, 444, 1114, 284, 284,
164070 /* 1030 */ 428, 448, 1525, 1213, 439, 284, 284, 1489, 1352, 311,
164071 /* 1040 */ 474, 565, 1115, 971, 491, 491, 217, 1263, 565, 1538,
164072 /* 1050 */ 568, 972, 207, 568, 1027, 240, 383, 1116, 519, 122,
164073 /* 1060 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116,
164074 /* 1070 */ 444, 1018, 107, 71, 71, 1017, 13, 13, 912, 568,
164075 /* 1080 */ 1495, 568, 284, 284, 97, 526, 491, 448, 913, 1326,
164076 /* 1090 */ 1322, 545, 409, 284, 284, 565, 151, 209, 1495, 1497,
164077 /* 1100 */ 262, 450, 55, 55, 56, 56, 565, 1017, 1017, 1019,
164078 /* 1110 */ 443, 332, 409, 527, 12, 295, 125, 126, 80, 1217,
164079 /* 1120 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164080 /* 1130 */ 124, 347, 409, 864, 1534, 1213, 125, 126, 80, 1217,
164081 /* 1140 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164082 /* 1150 */ 124, 1137, 1641, 474, 1641, 371, 125, 114, 80, 1217,
164083 /* 1160 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124,
164084 /* 1170 */ 124, 1495, 329, 474, 331, 122, 122, 122, 122, 121,
164085 /* 1180 */ 121, 120, 120, 120, 119, 116, 444, 203, 1419, 568,
164086 /* 1190 */ 1294, 864, 464, 1213, 436, 122, 122, 122, 122, 121,
164087 /* 1200 */ 121, 120, 120, 120, 119, 116, 444, 553, 1137, 1642,
164088 /* 1210 */ 539, 1642, 15, 15, 892, 122, 122, 122, 122, 121,
164089 /* 1220 */ 121, 120, 120, 120, 119, 116, 444, 568, 298, 538,
164090 /* 1230 */ 1135, 1419, 1559, 1560, 1331, 409, 6, 6, 1169, 1268,
164091 /* 1240 */ 415, 320, 284, 284, 1419, 508, 565, 525, 300, 457,
164092 /* 1250 */ 43, 43, 568, 893, 12, 565, 330, 478, 425, 407,
164093 /* 1260 */ 126, 80, 1217, 1217, 1050, 1053, 1040, 1040, 123, 123,
164094 /* 1270 */ 124, 124, 124, 124, 568, 57, 57, 288, 1192, 1419,
164095 /* 1280 */ 496, 458, 392, 392, 391, 273, 389, 1135, 1558, 849,
164096 /* 1290 */ 1169, 407, 6, 568, 321, 1158, 470, 44, 44, 1557,
164097 /* 1300 */ 1114, 426, 234, 6, 323, 256, 540, 256, 1158, 431,
164098 /* 1310 */ 568, 1158, 322, 17, 487, 1115, 58, 58, 122, 122,
164099 /* 1320 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 444,
164100 /* 1330 */ 1116, 216, 481, 59, 59, 1192, 1193, 1194, 111, 560,
164101 /* 1340 */ 324, 4, 236, 456, 526, 568, 237, 456, 568, 437,
164102 /* 1350 */ 168, 556, 420, 141, 479, 563, 568, 293, 568, 1095,
164103 /* 1360 */ 568, 293, 568, 1095, 531, 568, 872, 8, 60, 60,
164104 /* 1370 */ 235, 61, 61, 568, 414, 568, 414, 568, 445, 62,
164105 /* 1380 */ 62, 45, 45, 46, 46, 47, 47, 199, 49, 49,
164106 /* 1390 */ 557, 568, 359, 568, 100, 486, 50, 50, 63, 63,
164107 /* 1400 */ 64, 64, 561, 415, 535, 410, 568, 1027, 568, 534,
164108 /* 1410 */ 316, 559, 316, 559, 65, 65, 14, 14, 568, 1027,
164109 /* 1420 */ 568, 512, 932, 872, 1018, 109, 109, 931, 1017, 66,
164110 /* 1430 */ 66, 131, 131, 110, 451, 445, 570, 569, 416, 177,
164111 /* 1440 */ 1017, 132, 132, 67, 67, 568, 467, 568, 932, 471,
164112 /* 1450 */ 1364, 283, 226, 931, 315, 1363, 407, 568, 459, 407,
164113 /* 1460 */ 1017, 1017, 1019, 239, 407, 86, 213, 1350, 52, 52,
164114 /* 1470 */ 68, 68, 1017, 1017, 1019, 1020, 27, 1585, 1180, 447,
164115 /* 1480 */ 69, 69, 288, 97, 108, 1541, 106, 392, 392, 391,
164116 /* 1490 */ 273, 389, 568, 879, 849, 883, 568, 111, 560, 466,
164117 /* 1500 */ 4, 568, 152, 30, 38, 568, 1132, 234, 396, 323,
164118 /* 1510 */ 111, 560, 527, 4, 563, 53, 53, 322, 568, 163,
164119 /* 1520 */ 163, 568, 337, 468, 164, 164, 333, 563, 76, 76,
164120 /* 1530 */ 568, 289, 1514, 568, 31, 1513, 568, 445, 338, 483,
164121 /* 1540 */ 100, 54, 54, 344, 72, 72, 296, 236, 1080, 557,
164122 /* 1550 */ 445, 879, 1360, 134, 134, 168, 73, 73, 141, 161,
164123 /* 1560 */ 161, 1574, 557, 535, 568, 319, 568, 348, 536, 1009,
164124 /* 1570 */ 473, 261, 261, 891, 890, 235, 535, 568, 1027, 568,
164125 /* 1580 */ 475, 534, 261, 367, 109, 109, 521, 136, 136, 130,
164126 /* 1590 */ 130, 1027, 110, 366, 445, 570, 569, 109, 109, 1017,
164127 /* 1600 */ 162, 162, 156, 156, 568, 110, 1080, 445, 570, 569,
164128 /* 1610 */ 410, 351, 1017, 568, 353, 316, 559, 568, 343, 568,
164129 /* 1620 */ 100, 497, 357, 258, 100, 898, 899, 140, 140, 355,
164130 /* 1630 */ 1310, 1017, 1017, 1019, 1020, 27, 139, 139, 362, 451,
164131 /* 1640 */ 137, 137, 138, 138, 1017, 1017, 1019, 1020, 27, 1180,
164132 /* 1650 */ 447, 568, 372, 288, 111, 560, 1021, 4, 392, 392,
164133 /* 1660 */ 391, 273, 389, 568, 1141, 849, 568, 1076, 568, 258,
164134 /* 1670 */ 492, 563, 568, 211, 75, 75, 555, 962, 234, 261,
164135 /* 1680 */ 323, 111, 560, 929, 4, 113, 77, 77, 322, 74,
164136 /* 1690 */ 74, 42, 42, 1373, 445, 48, 48, 1418, 563, 974,
164137 /* 1700 */ 975, 1092, 1091, 1092, 1091, 862, 557, 150, 930, 1346,
164138 /* 1710 */ 113, 1358, 554, 1424, 1021, 1275, 1266, 1254, 236, 1253,
164139 /* 1720 */ 1255, 445, 1593, 1343, 308, 276, 168, 309, 11, 141,
164140 /* 1730 */ 393, 310, 232, 557, 1405, 1027, 335, 291, 1400, 219,
164141 /* 1740 */ 336, 109, 109, 936, 297, 1410, 235, 341, 477, 110,
164142 /* 1750 */ 502, 445, 570, 569, 1393, 1409, 1017, 400, 1293, 365,
164143 /* 1760 */ 223, 1486, 1027, 1485, 1355, 1356, 1354, 1353, 109, 109,
164144 /* 1770 */ 204, 1596, 1232, 558, 265, 218, 110, 205, 445, 570,
164145 /* 1780 */ 569, 410, 387, 1017, 1533, 179, 316, 559, 1017, 1017,
164146 /* 1790 */ 1019, 1020, 27, 230, 1531, 1229, 79, 560, 85, 4,
164147 /* 1800 */ 418, 215, 548, 81, 84, 188, 1406, 173, 181, 461,
164148 /* 1810 */ 451, 35, 462, 563, 183, 1017, 1017, 1019, 1020, 27,
164149 /* 1820 */ 184, 1491, 185, 186, 495, 242, 98, 398, 1412, 36,
164150 /* 1830 */ 1411, 484, 91, 469, 401, 1414, 445, 192, 1480, 246,
164151 /* 1840 */ 1502, 490, 346, 277, 248, 196, 493, 511, 557, 350,
164152 /* 1850 */ 1256, 249, 250, 403, 1313, 1312, 111, 560, 432, 4,
164153 /* 1860 */ 1311, 1304, 93, 1611, 883, 1610, 224, 404, 434, 520,
164154 /* 1870 */ 263, 435, 1579, 563, 1283, 1282, 364, 1027, 306, 1281,
164155 /* 1880 */ 264, 1609, 1565, 109, 109, 370, 1303, 307, 1564, 438,
164156 /* 1890 */ 128, 110, 1378, 445, 570, 569, 445, 546, 1017, 10,
164157 /* 1900 */ 1466, 105, 381, 1377, 34, 572, 99, 1336, 557, 314,
164158 /* 1910 */ 1186, 530, 272, 274, 379, 210, 1335, 547, 385, 386,
164159 /* 1920 */ 275, 573, 1251, 1246, 411, 412, 1518, 165, 178, 1519,
164160 /* 1930 */ 1017, 1017, 1019, 1020, 27, 1517, 1516, 1027, 78, 147,
164161 /* 1940 */ 166, 220, 221, 109, 109, 836, 304, 167, 446, 212,
164162 /* 1950 */ 318, 110, 231, 445, 570, 569, 144, 1090, 1017, 1088,
164163 /* 1960 */ 326, 180, 169, 1212, 182, 334, 238, 915, 241, 1104,
164164 /* 1970 */ 187, 170, 171, 421, 87, 88, 423, 189, 89, 90,
164165 /* 1980 */ 172, 1107, 243, 1103, 244, 158, 18, 245, 345, 247,
164166 /* 1990 */ 1017, 1017, 1019, 1020, 27, 261, 1096, 193, 1226, 489,
164167 /* 2000 */ 194, 37, 366, 851, 494, 251, 195, 506, 92, 19,
164168 /* 2010 */ 498, 358, 20, 503, 881, 361, 94, 894, 305, 159,
164169 /* 2020 */ 513, 39, 95, 1174, 160, 1056, 966, 1143, 96, 174,
164170 /* 2030 */ 1142, 225, 280, 282, 198, 960, 113, 1164, 1160, 260,
164171 /* 2040 */ 21, 22, 23, 1162, 1168, 1167, 1148, 24, 33, 25,
164172 /* 2050 */ 202, 542, 26, 100, 1071, 102, 1057, 103, 7, 1055,
164173 /* 2060 */ 1059, 1113, 1060, 1112, 266, 267, 28, 40, 390, 1022,
164174 /* 2070 */ 863, 112, 29, 564, 1182, 1181, 268, 176, 143, 925,
164175 /* 2080 */ 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
164176 /* 2090 */ 1242, 1242, 1242, 1242, 269, 1602, 1242, 1601,
164177 };
164178 static const YYCODETYPE yy_lookahead[] = {
164179 /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276,
164180 /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19,
164181 /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216,
@@ -164114,57 +164337,57 @@
164337 /* 1580 */ 23, 90, 25, 121, 106, 107, 19, 216, 217, 216,
164338 /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121,
164339 /* 1600 */ 216, 217, 216, 217, 193, 114, 117, 116, 117, 118,
164340 /* 1610 */ 133, 193, 121, 193, 193, 138, 139, 193, 23, 193,
164341 /* 1620 */ 25, 23, 23, 25, 25, 7, 8, 216, 217, 193,
164342 /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 193, 162,
164343 /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1,
164344 /* 1650 */ 2, 193, 193, 5, 19, 20, 59, 22, 10, 11,
164345 /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 193, 25,
164346 /* 1670 */ 288, 36, 193, 242, 216, 217, 236, 23, 30, 25,
164347 /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216,
164348 /* 1690 */ 217, 216, 217, 193, 59, 216, 217, 193, 36, 83,
164349 /* 1700 */ 84, 153, 153, 155, 155, 23, 71, 25, 23, 193,
164350 /* 1710 */ 25, 193, 193, 193, 117, 193, 193, 193, 70, 193,
164351 /* 1720 */ 193, 59, 193, 255, 255, 287, 78, 255, 243, 81,
164352 /* 1730 */ 191, 255, 297, 71, 271, 100, 293, 245, 267, 214,
164353 /* 1740 */ 246, 106, 107, 108, 246, 271, 98, 245, 293, 114,
164354 /* 1750 */ 220, 116, 117, 118, 267, 271, 121, 271, 225, 219,
164355 /* 1760 */ 229, 219, 100, 219, 259, 259, 259, 259, 106, 107,
164356 /* 1770 */ 249, 196, 60, 280, 141, 243, 114, 249, 116, 117,
164357 /* 1780 */ 118, 133, 245, 121, 200, 297, 138, 139, 153, 154,
164358 /* 1790 */ 155, 156, 157, 297, 200, 38, 19, 20, 151, 22,
164359 /* 1800 */ 200, 150, 140, 294, 294, 22, 272, 43, 234, 18,
164360 /* 1810 */ 162, 270, 200, 36, 237, 153, 154, 155, 156, 157,
164361 /* 1820 */ 237, 283, 237, 237, 18, 199, 149, 246, 272, 270,
164362 /* 1830 */ 272, 200, 158, 246, 246, 234, 59, 234, 246, 199,
164363 /* 1840 */ 290, 62, 289, 200, 199, 22, 221, 115, 71, 200,
164364 /* 1850 */ 200, 199, 199, 221, 218, 218, 19, 20, 64, 22,
164365 /* 1860 */ 218, 227, 22, 224, 126, 224, 165, 221, 24, 305,
164366 /* 1870 */ 200, 113, 312, 36, 218, 220, 218, 100, 282, 218,
164367 /* 1880 */ 91, 218, 317, 106, 107, 221, 227, 282, 317, 82,
164368 /* 1890 */ 148, 114, 265, 116, 117, 118, 59, 145, 121, 22,
164369 /* 1900 */ 277, 158, 200, 265, 25, 202, 147, 250, 71, 279,
164370 /* 1910 */ 13, 146, 194, 194, 249, 248, 250, 140, 247, 246,
164371 /* 1920 */ 6, 192, 192, 192, 303, 303, 213, 207, 300, 213,
164372 /* 1930 */ 153, 154, 155, 156, 157, 213, 213, 100, 213, 222,
164373 /* 1940 */ 207, 214, 214, 106, 107, 4, 222, 207, 3, 22,
164374 /* 1950 */ 163, 114, 15, 116, 117, 118, 16, 23, 121, 23,
164375 /* 1960 */ 139, 151, 130, 25, 142, 16, 24, 20, 144, 1,
164376 /* 1970 */ 142, 130, 130, 61, 53, 53, 37, 151, 53, 53,
164377 /* 1980 */ 130, 116, 34, 1, 141, 5, 22, 115, 161, 141,
164378 /* 1990 */ 153, 154, 155, 156, 157, 25, 68, 68, 75, 41,
164379 /* 2000 */ 115, 24, 131, 20, 19, 125, 22, 96, 22, 22,
164380 /* 2010 */ 67, 23, 22, 67, 59, 24, 22, 28, 67, 23,
164381 /* 2020 */ 22, 22, 149, 23, 23, 23, 116, 23, 25, 37,
164382 /* 2030 */ 97, 141, 23, 23, 22, 143, 25, 75, 88, 34,
164383 /* 2040 */ 34, 34, 34, 86, 75, 93, 23, 34, 22, 34,
164384 /* 2050 */ 25, 24, 34, 25, 23, 142, 23, 142, 44, 23,
164385 /* 2060 */ 23, 23, 11, 23, 25, 22, 22, 22, 15, 23,
164386 /* 2070 */ 23, 22, 22, 25, 1, 1, 141, 25, 23, 135,
164387 /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164388 /* 2090 */ 319, 319, 319, 319, 141, 141, 319, 141, 319, 319,
164389 /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164390 /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164391 /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164392 /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164393 /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
@@ -164175,77 +164398,82 @@
164398 /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164399 /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164400 /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164401 /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164402 /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164403 /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164404 /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164405 /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164406 /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
164407 /* 2280 */ 319, 319, 319,
164408 };
164409 #define YY_SHIFT_COUNT (575)
164410 #define YY_SHIFT_MIN (0)
164411 #define YY_SHIFT_MAX (2074)
164412 static const unsigned short int yy_shift_ofst[] = {
164413 /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837,
164414 /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837,
164415 /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164416 /* 30 */ 271, 271, 1219, 1219, 216, 88, 1, 1, 1, 1,
164417 /* 40 */ 1, 40, 111, 258, 361, 469, 512, 583, 622, 693,
164418 /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093,
164419 /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
164420 /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662,
164421 /* 80 */ 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164422 /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164423 /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164424 /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164425 /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
164426 /* 130 */ 137, 181, 181, 181, 181, 181, 181, 181, 94, 430,
164427 /* 140 */ 66, 65, 112, 366, 533, 533, 740, 1261, 533, 533,
164428 /* 150 */ 79, 79, 533, 412, 412, 412, 77, 412, 123, 113,
164429 /* 160 */ 113, 22, 22, 2098, 2098, 328, 328, 328, 239, 468,
164430 /* 170 */ 468, 468, 468, 1015, 1015, 409, 366, 1129, 1186, 533,
164431 /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
164432 /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 969,
164433 /* 200 */ 621, 621, 533, 642, 788, 788, 1228, 1228, 822, 822,
164434 /* 210 */ 67, 1274, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 1307,
164435 /* 220 */ 954, 954, 585, 472, 640, 387, 695, 538, 541, 700,
164436 /* 230 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
164437 /* 240 */ 222, 533, 533, 533, 533, 533, 533, 533, 533, 533,
164438 /* 250 */ 533, 533, 533, 1179, 1179, 1179, 533, 533, 533, 565,
164439 /* 260 */ 533, 533, 533, 916, 1144, 533, 533, 1288, 533, 533,
164440 /* 270 */ 533, 533, 533, 533, 533, 533, 639, 1330, 209, 1076,
164441 /* 280 */ 1076, 1076, 1076, 580, 209, 209, 1313, 768, 917, 649,
164442 /* 290 */ 1181, 1316, 405, 1316, 1238, 249, 1181, 1181, 249, 1181,
164443 /* 300 */ 405, 1238, 1369, 464, 1259, 1012, 1012, 1012, 1368, 1368,
164444 /* 310 */ 1368, 1368, 184, 184, 1326, 904, 1287, 1480, 1712, 1712,
164445 /* 320 */ 1633, 1633, 1757, 1757, 1633, 1647, 1651, 1783, 1764, 1791,
164446 /* 330 */ 1791, 1791, 1791, 1633, 1806, 1677, 1651, 1651, 1677, 1783,
164447 /* 340 */ 1764, 1677, 1764, 1677, 1633, 1806, 1674, 1779, 1633, 1806,
164448 /* 350 */ 1823, 1633, 1806, 1633, 1806, 1823, 1732, 1732, 1732, 1794,
164449 /* 360 */ 1840, 1840, 1823, 1732, 1738, 1732, 1794, 1732, 1732, 1701,
164450 /* 370 */ 1844, 1758, 1758, 1823, 1633, 1789, 1789, 1807, 1807, 1742,
164451 /* 380 */ 1752, 1877, 1633, 1743, 1742, 1759, 1765, 1677, 1879, 1897,
164452 /* 390 */ 1897, 1914, 1914, 1914, 2098, 2098, 2098, 2098, 2098, 2098,
164453 /* 400 */ 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 207,
164454 /* 410 */ 1095, 331, 620, 903, 806, 1074, 1483, 1432, 1481, 1322,
164455 /* 420 */ 1370, 1394, 1515, 1291, 1546, 1547, 1557, 1595, 1598, 1599,
164456 /* 430 */ 1434, 1453, 1618, 1462, 1567, 1489, 1644, 1654, 1616, 1660,
164457 /* 440 */ 1548, 1549, 1682, 1685, 1597, 742, 1941, 1945, 1927, 1787,
164458 /* 450 */ 1937, 1940, 1934, 1936, 1821, 1810, 1832, 1938, 1938, 1942,
164459 /* 460 */ 1822, 1947, 1824, 1949, 1968, 1828, 1841, 1938, 1842, 1912,
164460 /* 470 */ 1939, 1938, 1826, 1921, 1922, 1925, 1926, 1850, 1865, 1948,
164461 /* 480 */ 1843, 1982, 1980, 1964, 1872, 1827, 1928, 1970, 1929, 1923,
164462 /* 490 */ 1958, 1848, 1885, 1977, 1983, 1985, 1871, 1880, 1984, 1943,
164463 /* 500 */ 1986, 1987, 1988, 1990, 1946, 1955, 1991, 1911, 1989, 1994,
164464 /* 510 */ 1951, 1992, 1996, 1873, 1998, 2000, 2001, 2002, 2003, 2004,
164465 /* 520 */ 1999, 1933, 1890, 2009, 2010, 1910, 2005, 2012, 1892, 2011,
164466 /* 530 */ 2006, 2007, 2008, 2013, 1950, 1962, 1957, 2014, 1969, 1952,
164467 /* 540 */ 2015, 2023, 2026, 2027, 2025, 2028, 2018, 1913, 1915, 2031,
164468 /* 550 */ 2011, 2033, 2036, 2037, 2038, 2039, 2040, 2043, 2051, 2044,
164469 /* 560 */ 2045, 2046, 2047, 2049, 2050, 2048, 1944, 1935, 1953, 1954,
164470 /* 570 */ 1956, 2052, 2055, 2053, 2073, 2074,
164471 };
164472 #define YY_REDUCE_COUNT (408)
164473 #define YY_REDUCE_MIN (-271)
164474 #define YY_REDUCE_MAX (1740)
164475 static const short yy_reduce_ofst[] = {
164476 /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187,
164477 /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489,
164478 /* 20 */ 576, -175, 598, 686, 615, 725, 860, 778, 781, 857,
164479 /* 30 */ 616, 887, 87, 240, -192, 408, 626, 796, 843, 854,
@@ -164255,98 +164483,99 @@
164483 /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 80, 83,
164484 /* 80 */ 313, 886, 888, 996, 1034, 1059, 1081, 1100, 1117, 1152,
164485 /* 90 */ 1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198,
164486 /* 100 */ 1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303,
164487 /* 110 */ 1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384,
164488 /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, 1475, 1479,
164489 /* 130 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
164490 /* 140 */ -271, 138, 459, 396, -158, 470, 302, -212, 521, 201,
164491 /* 150 */ -195, -92, 559, 630, 632, 630, -271, 632, 901, 63,
164492 /* 160 */ 407, -271, -271, -271, -271, 161, 161, 161, 251, 335,
164493 /* 170 */ 847, 960, 980, 537, 588, 618, 628, 688, 688, -166,
164494 /* 180 */ -161, 674, 790, 794, 799, 851, 852, -122, 680, -120,
164495 /* 190 */ 995, 1038, 415, 1051, 893, 798, 962, 400, 1086, 779,
164496 /* 200 */ 923, 924, 263, 1041, 979, 990, 1083, 1097, 1031, 1194,
164497 /* 210 */ 362, 994, 1139, 1005, 1037, 1202, 1205, 1195, 1210, -194,
164498 /* 220 */ 56, 185, -135, 232, 522, 560, 601, 617, 669, 683,
164499 /* 230 */ 711, 856, 908, 941, 1048, 1101, 1147, 1257, 1262, 1265,
164500 /* 240 */ 392, 1292, 1333, 1339, 1342, 1346, 1350, 1359, 1374, 1418,
164501 /* 250 */ 1421, 1436, 1437, 593, 755, 770, 997, 1445, 1459, 1209,
164502 /* 260 */ 1500, 1504, 1516, 1132, 1243, 1518, 1519, 1440, 1520, 560,
164503 /* 270 */ 1522, 1523, 1524, 1526, 1527, 1529, 1382, 1438, 1431, 1468,
164504 /* 280 */ 1469, 1472, 1476, 1209, 1431, 1431, 1485, 1525, 1539, 1435,
164505 /* 290 */ 1463, 1471, 1492, 1487, 1443, 1494, 1474, 1484, 1498, 1486,
164506 /* 300 */ 1502, 1455, 1530, 1531, 1533, 1540, 1542, 1544, 1505, 1506,
164507 /* 310 */ 1507, 1508, 1521, 1528, 1493, 1537, 1532, 1575, 1488, 1496,
164508 /* 320 */ 1584, 1594, 1509, 1510, 1600, 1538, 1534, 1541, 1574, 1577,
164509 /* 330 */ 1583, 1585, 1586, 1612, 1626, 1581, 1556, 1558, 1587, 1559,
164510 /* 340 */ 1601, 1588, 1603, 1592, 1631, 1640, 1550, 1553, 1643, 1645,
164511 /* 350 */ 1625, 1649, 1652, 1650, 1653, 1632, 1636, 1637, 1642, 1634,
164512 /* 360 */ 1639, 1641, 1646, 1656, 1655, 1658, 1659, 1661, 1663, 1560,
164513 /* 370 */ 1564, 1596, 1605, 1664, 1670, 1565, 1571, 1627, 1638, 1657,
164514 /* 380 */ 1665, 1623, 1702, 1630, 1666, 1667, 1671, 1673, 1703, 1718,
164515 /* 390 */ 1719, 1729, 1730, 1731, 1621, 1622, 1628, 1720, 1713, 1716,
164516 /* 400 */ 1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740,
164517 };
164518 static const YYACTIONTYPE yy_default[] = {
164519 /* 0 */ 1647, 1647, 1647, 1475, 1240, 1351, 1240, 1240, 1240, 1475,
164520 /* 10 */ 1475, 1475, 1240, 1381, 1381, 1528, 1273, 1240, 1240, 1240,
164521 /* 20 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1474, 1240, 1240,
164522 /* 30 */ 1240, 1240, 1563, 1563, 1240, 1240, 1240, 1240, 1240, 1240,
164523 /* 40 */ 1240, 1240, 1390, 1240, 1397, 1240, 1240, 1240, 1240, 1240,
164524 /* 50 */ 1476, 1477, 1240, 1240, 1240, 1527, 1529, 1492, 1404, 1403,
164525 /* 60 */ 1402, 1401, 1510, 1369, 1395, 1388, 1392, 1470, 1471, 1469,
164526 /* 70 */ 1473, 1477, 1476, 1240, 1391, 1438, 1454, 1437, 1240, 1240,
164527 /* 80 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164528 /* 90 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164529 /* 100 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164530 /* 110 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164531 /* 120 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164532 /* 130 */ 1446, 1453, 1452, 1451, 1460, 1450, 1447, 1440, 1439, 1441,
164533 /* 140 */ 1442, 1240, 1240, 1264, 1240, 1240, 1261, 1315, 1240, 1240,
164534 /* 150 */ 1240, 1240, 1240, 1547, 1546, 1240, 1443, 1240, 1273, 1432,
164535 /* 160 */ 1431, 1457, 1444, 1456, 1455, 1535, 1599, 1598, 1493, 1240,
164536 /* 170 */ 1240, 1240, 1240, 1240, 1240, 1563, 1240, 1240, 1240, 1240,
164537 /* 180 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164538 /* 190 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1371,
164539 /* 200 */ 1563, 1563, 1240, 1273, 1563, 1563, 1372, 1372, 1269, 1269,
164540 /* 210 */ 1375, 1240, 1542, 1342, 1342, 1342, 1342, 1351, 1342, 1240,
164541 /* 220 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164542 /* 230 */ 1240, 1240, 1240, 1240, 1532, 1530, 1240, 1240, 1240, 1240,
164543 /* 240 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164544 /* 250 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164545 /* 260 */ 1240, 1240, 1240, 1347, 1240, 1240, 1240, 1240, 1240, 1240,
164546 /* 270 */ 1240, 1240, 1240, 1240, 1240, 1592, 1240, 1505, 1329, 1347,
164547 /* 280 */ 1347, 1347, 1347, 1349, 1330, 1328, 1341, 1274, 1247, 1639,
164548 /* 290 */ 1407, 1396, 1348, 1396, 1636, 1394, 1407, 1407, 1394, 1407,
164549 /* 300 */ 1348, 1636, 1290, 1615, 1285, 1381, 1381, 1381, 1371, 1371,
164550 /* 310 */ 1371, 1371, 1375, 1375, 1472, 1348, 1341, 1240, 1639, 1639,
164551 /* 320 */ 1357, 1357, 1638, 1638, 1357, 1493, 1623, 1416, 1318, 1324,
164552 /* 330 */ 1324, 1324, 1324, 1357, 1258, 1394, 1623, 1623, 1394, 1416,
164553 /* 340 */ 1318, 1394, 1318, 1394, 1357, 1258, 1509, 1633, 1357, 1258,
164554 /* 350 */ 1483, 1357, 1258, 1357, 1258, 1483, 1316, 1316, 1316, 1305,
164555 /* 360 */ 1240, 1240, 1483, 1316, 1290, 1316, 1305, 1316, 1316, 1581,
164556 /* 370 */ 1240, 1487, 1487, 1483, 1357, 1573, 1573, 1384, 1384, 1389,
164557 /* 380 */ 1375, 1478, 1357, 1240, 1389, 1387, 1385, 1394, 1308, 1595,
164558 /* 390 */ 1595, 1591, 1591, 1591, 1644, 1644, 1542, 1608, 1273, 1273,
164559 /* 400 */ 1273, 1273, 1608, 1292, 1292, 1274, 1274, 1273, 1608, 1240,
164560 /* 410 */ 1240, 1240, 1240, 1240, 1240, 1603, 1240, 1537, 1494, 1361,
164561 /* 420 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164562 /* 430 */ 1240, 1240, 1240, 1240, 1548, 1240, 1240, 1240, 1240, 1240,
164563 /* 440 */ 1240, 1240, 1240, 1240, 1240, 1421, 1240, 1243, 1539, 1240,
164564 /* 450 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1398, 1399, 1362,
164565 /* 460 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1413, 1240, 1240,
164566 /* 470 */ 1240, 1408, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164567 /* 480 */ 1635, 1240, 1240, 1240, 1240, 1240, 1240, 1508, 1507, 1240,
164568 /* 490 */ 1240, 1359, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164569 /* 500 */ 1240, 1240, 1240, 1240, 1240, 1288, 1240, 1240, 1240, 1240,
164570 /* 510 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164571 /* 520 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1386,
164572 /* 530 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164573 /* 540 */ 1240, 1240, 1240, 1240, 1578, 1376, 1240, 1240, 1240, 1240,
164574 /* 550 */ 1626, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
164575 /* 560 */ 1240, 1240, 1240, 1240, 1240, 1619, 1332, 1423, 1240, 1422,
164576 /* 570 */ 1426, 1262, 1240, 1252, 1240, 1240,
164577 };
164578 /********** End of lemon-generated parsing tables *****************************/
164579
164580 /* The next table maps tokens (terminal symbols) into fallback tokens.
164581 ** If a construct like the following:
@@ -165170,204 +165399,206 @@
165399 /* 204 */ "expr ::= expr likeop expr ESCAPE expr",
165400 /* 205 */ "expr ::= expr ISNULL|NOTNULL",
165401 /* 206 */ "expr ::= expr NOT NULL",
165402 /* 207 */ "expr ::= expr IS expr",
165403 /* 208 */ "expr ::= expr IS NOT expr",
165404 /* 209 */ "expr ::= expr IS NOT DISTINCT FROM expr",
165405 /* 210 */ "expr ::= expr IS DISTINCT FROM expr",
165406 /* 211 */ "expr ::= NOT expr",
165407 /* 212 */ "expr ::= BITNOT expr",
165408 /* 213 */ "expr ::= PLUS|MINUS expr",
165409 /* 214 */ "expr ::= expr PTR expr",
165410 /* 215 */ "between_op ::= BETWEEN",
165411 /* 216 */ "between_op ::= NOT BETWEEN",
165412 /* 217 */ "expr ::= expr between_op expr AND expr",
165413 /* 218 */ "in_op ::= IN",
165414 /* 219 */ "in_op ::= NOT IN",
165415 /* 220 */ "expr ::= expr in_op LP exprlist RP",
165416 /* 221 */ "expr ::= LP select RP",
165417 /* 222 */ "expr ::= expr in_op LP select RP",
165418 /* 223 */ "expr ::= expr in_op nm dbnm paren_exprlist",
165419 /* 224 */ "expr ::= EXISTS LP select RP",
165420 /* 225 */ "expr ::= CASE case_operand case_exprlist case_else END",
165421 /* 226 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
165422 /* 227 */ "case_exprlist ::= WHEN expr THEN expr",
165423 /* 228 */ "case_else ::= ELSE expr",
165424 /* 229 */ "case_else ::=",
165425 /* 230 */ "case_operand ::= expr",
165426 /* 231 */ "case_operand ::=",
165427 /* 232 */ "exprlist ::=",
165428 /* 233 */ "nexprlist ::= nexprlist COMMA expr",
165429 /* 234 */ "nexprlist ::= expr",
165430 /* 235 */ "paren_exprlist ::=",
165431 /* 236 */ "paren_exprlist ::= LP exprlist RP",
165432 /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
165433 /* 238 */ "uniqueflag ::= UNIQUE",
165434 /* 239 */ "uniqueflag ::=",
165435 /* 240 */ "eidlist_opt ::=",
165436 /* 241 */ "eidlist_opt ::= LP eidlist RP",
165437 /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder",
165438 /* 243 */ "eidlist ::= nm collate sortorder",
165439 /* 244 */ "collate ::=",
165440 /* 245 */ "collate ::= COLLATE ID|STRING",
165441 /* 246 */ "cmd ::= DROP INDEX ifexists fullname",
165442 /* 247 */ "cmd ::= VACUUM vinto",
165443 /* 248 */ "cmd ::= VACUUM nm vinto",
165444 /* 249 */ "vinto ::= INTO expr",
165445 /* 250 */ "vinto ::=",
165446 /* 251 */ "cmd ::= PRAGMA nm dbnm",
165447 /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
165448 /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
165449 /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
165450 /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
165451 /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT",
165452 /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT",
165453 /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
165454 /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
165455 /* 260 */ "trigger_time ::= BEFORE|AFTER",
165456 /* 261 */ "trigger_time ::= INSTEAD OF",
165457 /* 262 */ "trigger_time ::=",
165458 /* 263 */ "trigger_event ::= DELETE|INSERT",
165459 /* 264 */ "trigger_event ::= UPDATE",
165460 /* 265 */ "trigger_event ::= UPDATE OF idlist",
165461 /* 266 */ "when_clause ::=",
165462 /* 267 */ "when_clause ::= WHEN expr",
165463 /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
165464 /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI",
165465 /* 270 */ "trnm ::= nm DOT nm",
165466 /* 271 */ "tridxby ::= INDEXED BY nm",
165467 /* 272 */ "tridxby ::= NOT INDEXED",
165468 /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
165469 /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
165470 /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
165471 /* 276 */ "trigger_cmd ::= scanpt select scanpt",
165472 /* 277 */ "expr ::= RAISE LP IGNORE RP",
165473 /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP",
165474 /* 279 */ "raisetype ::= ROLLBACK",
165475 /* 280 */ "raisetype ::= ABORT",
165476 /* 281 */ "raisetype ::= FAIL",
165477 /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname",
165478 /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
165479 /* 284 */ "cmd ::= DETACH database_kw_opt expr",
165480 /* 285 */ "key_opt ::=",
165481 /* 286 */ "key_opt ::= KEY expr",
165482 /* 287 */ "cmd ::= REINDEX",
165483 /* 288 */ "cmd ::= REINDEX nm dbnm",
165484 /* 289 */ "cmd ::= ANALYZE",
165485 /* 290 */ "cmd ::= ANALYZE nm dbnm",
165486 /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
165487 /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
165488 /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
165489 /* 294 */ "add_column_fullname ::= fullname",
165490 /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
165491 /* 296 */ "cmd ::= create_vtab",
165492 /* 297 */ "cmd ::= create_vtab LP vtabarglist RP",
165493 /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
165494 /* 299 */ "vtabarg ::=",
165495 /* 300 */ "vtabargtoken ::= ANY",
165496 /* 301 */ "vtabargtoken ::= lp anylist RP",
165497 /* 302 */ "lp ::= LP",
165498 /* 303 */ "with ::= WITH wqlist",
165499 /* 304 */ "with ::= WITH RECURSIVE wqlist",
165500 /* 305 */ "wqas ::= AS",
165501 /* 306 */ "wqas ::= AS MATERIALIZED",
165502 /* 307 */ "wqas ::= AS NOT MATERIALIZED",
165503 /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
165504 /* 309 */ "wqlist ::= wqitem",
165505 /* 310 */ "wqlist ::= wqlist COMMA wqitem",
165506 /* 311 */ "windowdefn_list ::= windowdefn",
165507 /* 312 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
165508 /* 313 */ "windowdefn ::= nm AS LP window RP",
165509 /* 314 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
165510 /* 315 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
165511 /* 316 */ "window ::= ORDER BY sortlist frame_opt",
165512 /* 317 */ "window ::= nm ORDER BY sortlist frame_opt",
165513 /* 318 */ "window ::= frame_opt",
165514 /* 319 */ "window ::= nm frame_opt",
165515 /* 320 */ "frame_opt ::=",
165516 /* 321 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
165517 /* 322 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
165518 /* 323 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
165519 /* 324 */ "frame_bound_s ::= frame_bound",
165520 /* 325 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
165521 /* 326 */ "frame_bound_e ::= frame_bound",
165522 /* 327 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
165523 /* 328 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
165524 /* 329 */ "frame_bound ::= CURRENT ROW",
165525 /* 330 */ "frame_exclude_opt ::=",
165526 /* 331 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
165527 /* 332 */ "frame_exclude ::= NO OTHERS",
165528 /* 333 */ "frame_exclude ::= CURRENT ROW",
165529 /* 334 */ "frame_exclude ::= GROUP|TIES",
165530 /* 335 */ "window_clause ::= WINDOW windowdefn_list",
165531 /* 336 */ "filter_over ::= filter_clause over_clause",
165532 /* 337 */ "filter_over ::= over_clause",
165533 /* 338 */ "filter_over ::= filter_clause",
165534 /* 339 */ "over_clause ::= OVER LP window RP",
165535 /* 340 */ "over_clause ::= OVER nm",
165536 /* 341 */ "filter_clause ::= FILTER LP WHERE expr RP",
165537 /* 342 */ "input ::= cmdlist",
165538 /* 343 */ "cmdlist ::= cmdlist ecmd",
165539 /* 344 */ "cmdlist ::= ecmd",
165540 /* 345 */ "ecmd ::= SEMI",
165541 /* 346 */ "ecmd ::= cmdx SEMI",
165542 /* 347 */ "ecmd ::= explain cmdx SEMI",
165543 /* 348 */ "trans_opt ::=",
165544 /* 349 */ "trans_opt ::= TRANSACTION",
165545 /* 350 */ "trans_opt ::= TRANSACTION nm",
165546 /* 351 */ "savepoint_opt ::= SAVEPOINT",
165547 /* 352 */ "savepoint_opt ::=",
165548 /* 353 */ "cmd ::= create_table create_table_args",
165549 /* 354 */ "table_option_set ::= table_option",
165550 /* 355 */ "columnlist ::= columnlist COMMA columnname carglist",
165551 /* 356 */ "columnlist ::= columnname carglist",
165552 /* 357 */ "nm ::= ID|INDEXED",
165553 /* 358 */ "nm ::= STRING",
165554 /* 359 */ "nm ::= JOIN_KW",
165555 /* 360 */ "typetoken ::= typename",
165556 /* 361 */ "typename ::= ID|STRING",
165557 /* 362 */ "signed ::= plus_num",
165558 /* 363 */ "signed ::= minus_num",
165559 /* 364 */ "carglist ::= carglist ccons",
165560 /* 365 */ "carglist ::=",
165561 /* 366 */ "ccons ::= NULL onconf",
165562 /* 367 */ "ccons ::= GENERATED ALWAYS AS generated",
165563 /* 368 */ "ccons ::= AS generated",
165564 /* 369 */ "conslist_opt ::= COMMA conslist",
165565 /* 370 */ "conslist ::= conslist tconscomma tcons",
165566 /* 371 */ "conslist ::= tcons",
165567 /* 372 */ "tconscomma ::=",
165568 /* 373 */ "defer_subclause_opt ::= defer_subclause",
165569 /* 374 */ "resolvetype ::= raisetype",
165570 /* 375 */ "selectnowith ::= oneselect",
165571 /* 376 */ "oneselect ::= values",
165572 /* 377 */ "sclp ::= selcollist COMMA",
165573 /* 378 */ "as ::= ID|STRING",
165574 /* 379 */ "indexed_opt ::= indexed_by",
165575 /* 380 */ "returning ::=",
165576 /* 381 */ "expr ::= term",
165577 /* 382 */ "likeop ::= LIKE_KW|MATCH",
165578 /* 383 */ "exprlist ::= nexprlist",
165579 /* 384 */ "nmnum ::= plus_num",
165580 /* 385 */ "nmnum ::= nm",
165581 /* 386 */ "nmnum ::= ON",
165582 /* 387 */ "nmnum ::= DELETE",
165583 /* 388 */ "nmnum ::= DEFAULT",
165584 /* 389 */ "plus_num ::= INTEGER|FLOAT",
165585 /* 390 */ "foreach_clause ::=",
165586 /* 391 */ "foreach_clause ::= FOR EACH ROW",
165587 /* 392 */ "trnm ::= nm",
165588 /* 393 */ "tridxby ::=",
165589 /* 394 */ "database_kw_opt ::= DATABASE",
165590 /* 395 */ "database_kw_opt ::=",
165591 /* 396 */ "kwcolumn_opt ::=",
165592 /* 397 */ "kwcolumn_opt ::= COLUMNKW",
165593 /* 398 */ "vtabarglist ::= vtabarg",
165594 /* 399 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
165595 /* 400 */ "vtabarg ::= vtabarg vtabargtoken",
165596 /* 401 */ "anylist ::=",
165597 /* 402 */ "anylist ::= anylist LP anylist RP",
165598 /* 403 */ "anylist ::= anylist ANY",
165599 /* 404 */ "with ::=",
165600 };
165601 #endif /* NDEBUG */
165602
165603
165604 #if YYSTACKDEPTH<=0
@@ -166079,204 +166310,206 @@
166310 217, /* (204) expr ::= expr likeop expr ESCAPE expr */
166311 217, /* (205) expr ::= expr ISNULL|NOTNULL */
166312 217, /* (206) expr ::= expr NOT NULL */
166313 217, /* (207) expr ::= expr IS expr */
166314 217, /* (208) expr ::= expr IS NOT expr */
166315 217, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */
166316 217, /* (210) expr ::= expr IS DISTINCT FROM expr */
166317 217, /* (211) expr ::= NOT expr */
166318 217, /* (212) expr ::= BITNOT expr */
166319 217, /* (213) expr ::= PLUS|MINUS expr */
166320 217, /* (214) expr ::= expr PTR expr */
166321 275, /* (215) between_op ::= BETWEEN */
166322 275, /* (216) between_op ::= NOT BETWEEN */
166323 217, /* (217) expr ::= expr between_op expr AND expr */
166324 276, /* (218) in_op ::= IN */
166325 276, /* (219) in_op ::= NOT IN */
166326 217, /* (220) expr ::= expr in_op LP exprlist RP */
166327 217, /* (221) expr ::= LP select RP */
166328 217, /* (222) expr ::= expr in_op LP select RP */
166329 217, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */
166330 217, /* (224) expr ::= EXISTS LP select RP */
166331 217, /* (225) expr ::= CASE case_operand case_exprlist case_else END */
166332 279, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166333 279, /* (227) case_exprlist ::= WHEN expr THEN expr */
166334 280, /* (228) case_else ::= ELSE expr */
166335 280, /* (229) case_else ::= */
166336 278, /* (230) case_operand ::= expr */
166337 278, /* (231) case_operand ::= */
166338 261, /* (232) exprlist ::= */
166339 253, /* (233) nexprlist ::= nexprlist COMMA expr */
166340 253, /* (234) nexprlist ::= expr */
166341 277, /* (235) paren_exprlist ::= */
166342 277, /* (236) paren_exprlist ::= LP exprlist RP */
166343 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166344 281, /* (238) uniqueflag ::= UNIQUE */
166345 281, /* (239) uniqueflag ::= */
166346 221, /* (240) eidlist_opt ::= */
166347 221, /* (241) eidlist_opt ::= LP eidlist RP */
166348 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
166349 232, /* (243) eidlist ::= nm collate sortorder */
166350 282, /* (244) collate ::= */
166351 282, /* (245) collate ::= COLLATE ID|STRING */
166352 190, /* (246) cmd ::= DROP INDEX ifexists fullname */
166353 190, /* (247) cmd ::= VACUUM vinto */
166354 190, /* (248) cmd ::= VACUUM nm vinto */
166355 283, /* (249) vinto ::= INTO expr */
166356 283, /* (250) vinto ::= */
166357 190, /* (251) cmd ::= PRAGMA nm dbnm */
166358 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
166359 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166360 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
166361 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166362 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */
166363 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */
166364 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166365 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166366 287, /* (260) trigger_time ::= BEFORE|AFTER */
166367 287, /* (261) trigger_time ::= INSTEAD OF */
166368 287, /* (262) trigger_time ::= */
166369 288, /* (263) trigger_event ::= DELETE|INSERT */
166370 288, /* (264) trigger_event ::= UPDATE */
166371 288, /* (265) trigger_event ::= UPDATE OF idlist */
166372 290, /* (266) when_clause ::= */
166373 290, /* (267) when_clause ::= WHEN expr */
166374 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166375 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
166376 292, /* (270) trnm ::= nm DOT nm */
166377 293, /* (271) tridxby ::= INDEXED BY nm */
166378 293, /* (272) tridxby ::= NOT INDEXED */
166379 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166380 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166381 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166382 291, /* (276) trigger_cmd ::= scanpt select scanpt */
166383 217, /* (277) expr ::= RAISE LP IGNORE RP */
166384 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
166385 236, /* (279) raisetype ::= ROLLBACK */
166386 236, /* (280) raisetype ::= ABORT */
166387 236, /* (281) raisetype ::= FAIL */
166388 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */
166389 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166390 190, /* (284) cmd ::= DETACH database_kw_opt expr */
166391 295, /* (285) key_opt ::= */
166392 295, /* (286) key_opt ::= KEY expr */
166393 190, /* (287) cmd ::= REINDEX */
166394 190, /* (288) cmd ::= REINDEX nm dbnm */
166395 190, /* (289) cmd ::= ANALYZE */
166396 190, /* (290) cmd ::= ANALYZE nm dbnm */
166397 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
166398 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166399 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166400 296, /* (294) add_column_fullname ::= fullname */
166401 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166402 190, /* (296) cmd ::= create_vtab */
166403 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */
166404 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166405 300, /* (299) vtabarg ::= */
166406 301, /* (300) vtabargtoken ::= ANY */
166407 301, /* (301) vtabargtoken ::= lp anylist RP */
166408 302, /* (302) lp ::= LP */
166409 266, /* (303) with ::= WITH wqlist */
166410 266, /* (304) with ::= WITH RECURSIVE wqlist */
166411 305, /* (305) wqas ::= AS */
166412 305, /* (306) wqas ::= AS MATERIALIZED */
166413 305, /* (307) wqas ::= AS NOT MATERIALIZED */
166414 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
166415 241, /* (309) wqlist ::= wqitem */
166416 241, /* (310) wqlist ::= wqlist COMMA wqitem */
166417 306, /* (311) windowdefn_list ::= windowdefn */
166418 306, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166419 307, /* (313) windowdefn ::= nm AS LP window RP */
166420 308, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166421 308, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166422 308, /* (316) window ::= ORDER BY sortlist frame_opt */
166423 308, /* (317) window ::= nm ORDER BY sortlist frame_opt */
166424 308, /* (318) window ::= frame_opt */
166425 308, /* (319) window ::= nm frame_opt */
166426 309, /* (320) frame_opt ::= */
166427 309, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166428 309, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166429 313, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */
166430 315, /* (324) frame_bound_s ::= frame_bound */
166431 315, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */
166432 316, /* (326) frame_bound_e ::= frame_bound */
166433 316, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */
166434 314, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */
166435 314, /* (329) frame_bound ::= CURRENT ROW */
166436 317, /* (330) frame_exclude_opt ::= */
166437 317, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */
166438 318, /* (332) frame_exclude ::= NO OTHERS */
166439 318, /* (333) frame_exclude ::= CURRENT ROW */
166440 318, /* (334) frame_exclude ::= GROUP|TIES */
166441 251, /* (335) window_clause ::= WINDOW windowdefn_list */
166442 273, /* (336) filter_over ::= filter_clause over_clause */
166443 273, /* (337) filter_over ::= over_clause */
166444 273, /* (338) filter_over ::= filter_clause */
166445 312, /* (339) over_clause ::= OVER LP window RP */
166446 312, /* (340) over_clause ::= OVER nm */
166447 311, /* (341) filter_clause ::= FILTER LP WHERE expr RP */
166448 185, /* (342) input ::= cmdlist */
166449 186, /* (343) cmdlist ::= cmdlist ecmd */
166450 186, /* (344) cmdlist ::= ecmd */
166451 187, /* (345) ecmd ::= SEMI */
166452 187, /* (346) ecmd ::= cmdx SEMI */
166453 187, /* (347) ecmd ::= explain cmdx SEMI */
166454 192, /* (348) trans_opt ::= */
166455 192, /* (349) trans_opt ::= TRANSACTION */
166456 192, /* (350) trans_opt ::= TRANSACTION nm */
166457 194, /* (351) savepoint_opt ::= SAVEPOINT */
166458 194, /* (352) savepoint_opt ::= */
166459 190, /* (353) cmd ::= create_table create_table_args */
166460 203, /* (354) table_option_set ::= table_option */
166461 201, /* (355) columnlist ::= columnlist COMMA columnname carglist */
166462 201, /* (356) columnlist ::= columnname carglist */
166463 193, /* (357) nm ::= ID|INDEXED */
166464 193, /* (358) nm ::= STRING */
166465 193, /* (359) nm ::= JOIN_KW */
166466 208, /* (360) typetoken ::= typename */
166467 209, /* (361) typename ::= ID|STRING */
166468 210, /* (362) signed ::= plus_num */
166469 210, /* (363) signed ::= minus_num */
166470 207, /* (364) carglist ::= carglist ccons */
166471 207, /* (365) carglist ::= */
166472 215, /* (366) ccons ::= NULL onconf */
166473 215, /* (367) ccons ::= GENERATED ALWAYS AS generated */
166474 215, /* (368) ccons ::= AS generated */
166475 202, /* (369) conslist_opt ::= COMMA conslist */
166476 228, /* (370) conslist ::= conslist tconscomma tcons */
166477 228, /* (371) conslist ::= tcons */
166478 229, /* (372) tconscomma ::= */
166479 233, /* (373) defer_subclause_opt ::= defer_subclause */
166480 235, /* (374) resolvetype ::= raisetype */
166481 239, /* (375) selectnowith ::= oneselect */
166482 240, /* (376) oneselect ::= values */
166483 254, /* (377) sclp ::= selcollist COMMA */
166484 255, /* (378) as ::= ID|STRING */
166485 264, /* (379) indexed_opt ::= indexed_by */
166486 272, /* (380) returning ::= */
166487 217, /* (381) expr ::= term */
166488 274, /* (382) likeop ::= LIKE_KW|MATCH */
166489 261, /* (383) exprlist ::= nexprlist */
166490 284, /* (384) nmnum ::= plus_num */
166491 284, /* (385) nmnum ::= nm */
166492 284, /* (386) nmnum ::= ON */
166493 284, /* (387) nmnum ::= DELETE */
166494 284, /* (388) nmnum ::= DEFAULT */
166495 211, /* (389) plus_num ::= INTEGER|FLOAT */
166496 289, /* (390) foreach_clause ::= */
166497 289, /* (391) foreach_clause ::= FOR EACH ROW */
166498 292, /* (392) trnm ::= nm */
166499 293, /* (393) tridxby ::= */
166500 294, /* (394) database_kw_opt ::= DATABASE */
166501 294, /* (395) database_kw_opt ::= */
166502 297, /* (396) kwcolumn_opt ::= */
166503 297, /* (397) kwcolumn_opt ::= COLUMNKW */
166504 299, /* (398) vtabarglist ::= vtabarg */
166505 299, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */
166506 300, /* (400) vtabarg ::= vtabarg vtabargtoken */
166507 303, /* (401) anylist ::= */
166508 303, /* (402) anylist ::= anylist LP anylist RP */
166509 303, /* (403) anylist ::= anylist ANY */
166510 266, /* (404) with ::= */
166511 };
166512
166513 /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
166514 ** of symbols on the right-hand side of that rule. */
166515 static const signed char yyRuleInfoNRhs[] = {
@@ -166487,204 +166720,206 @@
166720 -5, /* (204) expr ::= expr likeop expr ESCAPE expr */
166721 -2, /* (205) expr ::= expr ISNULL|NOTNULL */
166722 -3, /* (206) expr ::= expr NOT NULL */
166723 -3, /* (207) expr ::= expr IS expr */
166724 -4, /* (208) expr ::= expr IS NOT expr */
166725 -6, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */
166726 -5, /* (210) expr ::= expr IS DISTINCT FROM expr */
166727 -2, /* (211) expr ::= NOT expr */
166728 -2, /* (212) expr ::= BITNOT expr */
166729 -2, /* (213) expr ::= PLUS|MINUS expr */
166730 -3, /* (214) expr ::= expr PTR expr */
166731 -1, /* (215) between_op ::= BETWEEN */
166732 -2, /* (216) between_op ::= NOT BETWEEN */
166733 -5, /* (217) expr ::= expr between_op expr AND expr */
166734 -1, /* (218) in_op ::= IN */
166735 -2, /* (219) in_op ::= NOT IN */
166736 -5, /* (220) expr ::= expr in_op LP exprlist RP */
166737 -3, /* (221) expr ::= LP select RP */
166738 -5, /* (222) expr ::= expr in_op LP select RP */
166739 -5, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */
166740 -4, /* (224) expr ::= EXISTS LP select RP */
166741 -5, /* (225) expr ::= CASE case_operand case_exprlist case_else END */
166742 -5, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */
166743 -4, /* (227) case_exprlist ::= WHEN expr THEN expr */
166744 -2, /* (228) case_else ::= ELSE expr */
166745 0, /* (229) case_else ::= */
166746 -1, /* (230) case_operand ::= expr */
166747 0, /* (231) case_operand ::= */
166748 0, /* (232) exprlist ::= */
166749 -3, /* (233) nexprlist ::= nexprlist COMMA expr */
166750 -1, /* (234) nexprlist ::= expr */
166751 0, /* (235) paren_exprlist ::= */
166752 -3, /* (236) paren_exprlist ::= LP exprlist RP */
166753 -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
166754 -1, /* (238) uniqueflag ::= UNIQUE */
166755 0, /* (239) uniqueflag ::= */
166756 0, /* (240) eidlist_opt ::= */
166757 -3, /* (241) eidlist_opt ::= LP eidlist RP */
166758 -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
166759 -3, /* (243) eidlist ::= nm collate sortorder */
166760 0, /* (244) collate ::= */
166761 -2, /* (245) collate ::= COLLATE ID|STRING */
166762 -4, /* (246) cmd ::= DROP INDEX ifexists fullname */
166763 -2, /* (247) cmd ::= VACUUM vinto */
166764 -3, /* (248) cmd ::= VACUUM nm vinto */
166765 -2, /* (249) vinto ::= INTO expr */
166766 0, /* (250) vinto ::= */
166767 -3, /* (251) cmd ::= PRAGMA nm dbnm */
166768 -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
166769 -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
166770 -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
166771 -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
166772 -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */
166773 -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */
166774 -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
166775 -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
166776 -1, /* (260) trigger_time ::= BEFORE|AFTER */
166777 -2, /* (261) trigger_time ::= INSTEAD OF */
166778 0, /* (262) trigger_time ::= */
166779 -1, /* (263) trigger_event ::= DELETE|INSERT */
166780 -1, /* (264) trigger_event ::= UPDATE */
166781 -3, /* (265) trigger_event ::= UPDATE OF idlist */
166782 0, /* (266) when_clause ::= */
166783 -2, /* (267) when_clause ::= WHEN expr */
166784 -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
166785 -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
166786 -3, /* (270) trnm ::= nm DOT nm */
166787 -3, /* (271) tridxby ::= INDEXED BY nm */
166788 -2, /* (272) tridxby ::= NOT INDEXED */
166789 -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
166790 -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
166791 -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
166792 -3, /* (276) trigger_cmd ::= scanpt select scanpt */
166793 -4, /* (277) expr ::= RAISE LP IGNORE RP */
166794 -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
166795 -1, /* (279) raisetype ::= ROLLBACK */
166796 -1, /* (280) raisetype ::= ABORT */
166797 -1, /* (281) raisetype ::= FAIL */
166798 -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */
166799 -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
166800 -3, /* (284) cmd ::= DETACH database_kw_opt expr */
166801 0, /* (285) key_opt ::= */
166802 -2, /* (286) key_opt ::= KEY expr */
166803 -1, /* (287) cmd ::= REINDEX */
166804 -3, /* (288) cmd ::= REINDEX nm dbnm */
166805 -1, /* (289) cmd ::= ANALYZE */
166806 -3, /* (290) cmd ::= ANALYZE nm dbnm */
166807 -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
166808 -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
166809 -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
166810 -1, /* (294) add_column_fullname ::= fullname */
166811 -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
166812 -1, /* (296) cmd ::= create_vtab */
166813 -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */
166814 -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
166815 0, /* (299) vtabarg ::= */
166816 -1, /* (300) vtabargtoken ::= ANY */
166817 -3, /* (301) vtabargtoken ::= lp anylist RP */
166818 -1, /* (302) lp ::= LP */
166819 -2, /* (303) with ::= WITH wqlist */
166820 -3, /* (304) with ::= WITH RECURSIVE wqlist */
166821 -1, /* (305) wqas ::= AS */
166822 -2, /* (306) wqas ::= AS MATERIALIZED */
166823 -3, /* (307) wqas ::= AS NOT MATERIALIZED */
166824 -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
166825 -1, /* (309) wqlist ::= wqitem */
166826 -3, /* (310) wqlist ::= wqlist COMMA wqitem */
166827 -1, /* (311) windowdefn_list ::= windowdefn */
166828 -3, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */
166829 -5, /* (313) windowdefn ::= nm AS LP window RP */
166830 -5, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
166831 -6, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
166832 -4, /* (316) window ::= ORDER BY sortlist frame_opt */
166833 -5, /* (317) window ::= nm ORDER BY sortlist frame_opt */
166834 -1, /* (318) window ::= frame_opt */
166835 -2, /* (319) window ::= nm frame_opt */
166836 0, /* (320) frame_opt ::= */
166837 -3, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
166838 -6, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
166839 -1, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */
166840 -1, /* (324) frame_bound_s ::= frame_bound */
166841 -2, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */
166842 -1, /* (326) frame_bound_e ::= frame_bound */
166843 -2, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */
166844 -2, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */
166845 -2, /* (329) frame_bound ::= CURRENT ROW */
166846 0, /* (330) frame_exclude_opt ::= */
166847 -2, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */
166848 -2, /* (332) frame_exclude ::= NO OTHERS */
166849 -2, /* (333) frame_exclude ::= CURRENT ROW */
166850 -1, /* (334) frame_exclude ::= GROUP|TIES */
166851 -2, /* (335) window_clause ::= WINDOW windowdefn_list */
166852 -2, /* (336) filter_over ::= filter_clause over_clause */
166853 -1, /* (337) filter_over ::= over_clause */
166854 -1, /* (338) filter_over ::= filter_clause */
166855 -4, /* (339) over_clause ::= OVER LP window RP */
166856 -2, /* (340) over_clause ::= OVER nm */
166857 -5, /* (341) filter_clause ::= FILTER LP WHERE expr RP */
166858 -1, /* (342) input ::= cmdlist */
166859 -2, /* (343) cmdlist ::= cmdlist ecmd */
166860 -1, /* (344) cmdlist ::= ecmd */
166861 -1, /* (345) ecmd ::= SEMI */
166862 -2, /* (346) ecmd ::= cmdx SEMI */
166863 -3, /* (347) ecmd ::= explain cmdx SEMI */
166864 0, /* (348) trans_opt ::= */
166865 -1, /* (349) trans_opt ::= TRANSACTION */
166866 -2, /* (350) trans_opt ::= TRANSACTION nm */
166867 -1, /* (351) savepoint_opt ::= SAVEPOINT */
166868 0, /* (352) savepoint_opt ::= */
166869 -2, /* (353) cmd ::= create_table create_table_args */
166870 -1, /* (354) table_option_set ::= table_option */
166871 -4, /* (355) columnlist ::= columnlist COMMA columnname carglist */
166872 -2, /* (356) columnlist ::= columnname carglist */
166873 -1, /* (357) nm ::= ID|INDEXED */
166874 -1, /* (358) nm ::= STRING */
166875 -1, /* (359) nm ::= JOIN_KW */
166876 -1, /* (360) typetoken ::= typename */
166877 -1, /* (361) typename ::= ID|STRING */
166878 -1, /* (362) signed ::= plus_num */
166879 -1, /* (363) signed ::= minus_num */
166880 -2, /* (364) carglist ::= carglist ccons */
166881 0, /* (365) carglist ::= */
166882 -2, /* (366) ccons ::= NULL onconf */
166883 -4, /* (367) ccons ::= GENERATED ALWAYS AS generated */
166884 -2, /* (368) ccons ::= AS generated */
166885 -2, /* (369) conslist_opt ::= COMMA conslist */
166886 -3, /* (370) conslist ::= conslist tconscomma tcons */
166887 -1, /* (371) conslist ::= tcons */
166888 0, /* (372) tconscomma ::= */
166889 -1, /* (373) defer_subclause_opt ::= defer_subclause */
166890 -1, /* (374) resolvetype ::= raisetype */
166891 -1, /* (375) selectnowith ::= oneselect */
166892 -1, /* (376) oneselect ::= values */
166893 -2, /* (377) sclp ::= selcollist COMMA */
166894 -1, /* (378) as ::= ID|STRING */
166895 -1, /* (379) indexed_opt ::= indexed_by */
166896 0, /* (380) returning ::= */
166897 -1, /* (381) expr ::= term */
166898 -1, /* (382) likeop ::= LIKE_KW|MATCH */
166899 -1, /* (383) exprlist ::= nexprlist */
166900 -1, /* (384) nmnum ::= plus_num */
166901 -1, /* (385) nmnum ::= nm */
166902 -1, /* (386) nmnum ::= ON */
166903 -1, /* (387) nmnum ::= DELETE */
166904 -1, /* (388) nmnum ::= DEFAULT */
166905 -1, /* (389) plus_num ::= INTEGER|FLOAT */
166906 0, /* (390) foreach_clause ::= */
166907 -3, /* (391) foreach_clause ::= FOR EACH ROW */
166908 -1, /* (392) trnm ::= nm */
166909 0, /* (393) tridxby ::= */
166910 -1, /* (394) database_kw_opt ::= DATABASE */
166911 0, /* (395) database_kw_opt ::= */
166912 0, /* (396) kwcolumn_opt ::= */
166913 -1, /* (397) kwcolumn_opt ::= COLUMNKW */
166914 -1, /* (398) vtabarglist ::= vtabarg */
166915 -3, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */
166916 -2, /* (400) vtabarg ::= vtabarg vtabargtoken */
166917 0, /* (401) anylist ::= */
166918 -4, /* (402) anylist ::= anylist LP anylist RP */
166919 -2, /* (403) anylist ::= anylist ANY */
166920 0, /* (404) with ::= */
166921 };
166922
166923 static void yy_accept(yyParser*); /* Forward Declaration */
166924
166925 /*
@@ -166740,11 +166975,11 @@
166975 {yymsp[1].minor.yy394 = TK_DEFERRED;}
166976 break;
166977 case 5: /* transtype ::= DEFERRED */
166978 case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
166979 case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
166980 case 323: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==323);
166981 {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/}
166982 break;
166983 case 8: /* cmd ::= COMMIT|END trans_opt */
166984 case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
166985 {sqlite3EndTransaction(pParse,yymsp[-1].major);}
@@ -166777,11 +167012,11 @@
167012 case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
167013 case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
167014 case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
167015 case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
167016 case 98: /* distinct ::= */ yytestcase(yyruleno==98);
167017 case 244: /* collate ::= */ yytestcase(yyruleno==244);
167018 {yymsp[1].minor.yy394 = 0;}
167019 break;
167020 case 16: /* ifnotexists ::= IF NOT EXISTS */
167021 {yymsp[-2].minor.yy394 = 1;}
167022 break;
@@ -166961,13 +167196,13 @@
167196 case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171);
167197 {yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;}
167198 break;
167199 case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
167200 case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
167201 case 216: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==216);
167202 case 219: /* in_op ::= NOT IN */ yytestcase(yyruleno==219);
167203 case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245);
167204 {yymsp[-1].minor.yy394 = 1;}
167205 break;
167206 case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
167207 {yymsp[-1].minor.yy394 = 0;}
167208 break;
@@ -167113,13 +167348,13 @@
167348 {yymsp[0].minor.yy394 = SF_All;}
167349 break;
167350 case 99: /* sclp ::= */
167351 case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132);
167352 case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142);
167353 case 232: /* exprlist ::= */ yytestcase(yyruleno==232);
167354 case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235);
167355 case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240);
167356 {yymsp[1].minor.yy322 = 0;}
167357 break;
167358 case 100: /* selcollist ::= sclp scanpt expr scanpt as */
167359 {
167360 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
@@ -167141,12 +167376,12 @@
167376 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
167377 }
167378 break;
167379 case 103: /* as ::= AS nm */
167380 case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115);
167381 case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256);
167382 case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257);
167383 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
167384 break;
167385 case 105: /* from ::= */
167386 case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108);
167387 {yymsp[1].minor.yy131 = 0;}
@@ -167314,20 +167549,20 @@
167549 break;
167550 case 144: /* having_opt ::= */
167551 case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
167552 case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
167553 case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
167554 case 229: /* case_else ::= */ yytestcase(yyruleno==229);
167555 case 231: /* case_operand ::= */ yytestcase(yyruleno==231);
167556 case 250: /* vinto ::= */ yytestcase(yyruleno==250);
167557 {yymsp[1].minor.yy528 = 0;}
167558 break;
167559 case 145: /* having_opt ::= HAVING expr */
167560 case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
167561 case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
167562 case 228: /* case_else ::= ELSE expr */ yytestcase(yyruleno==228);
167563 case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249);
167564 {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
167565 break;
167566 case 147: /* limit_opt ::= LIMIT expr */
167567 {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
167568 break;
@@ -167351,11 +167586,22 @@
167586 break;
167587 case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
167588 {
167589 sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0);
167590 sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list");
167591 if( yymsp[-1].minor.yy131 ){
167592 SrcList *pFromClause = yymsp[-1].minor.yy131;
167593 if( pFromClause->nSrc>1 ){
167594 Select *pSubquery;
167595 Token as;
167596 pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0);
167597 as.n = 0;
167598 as.z = 0;
167599 pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
167600 }
167601 yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause);
167602 }
167603 sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0);
167604 }
167605 break;
167606 case 158: /* setlist ::= setlist COMMA nm EQ expr */
167607 {
@@ -167597,33 +167843,45 @@
167843 {
167844 yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528);
167845 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL);
167846 }
167847 break;
167848 case 209: /* expr ::= expr IS NOT DISTINCT FROM expr */
167849 {
167850 yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528);
167851 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL);
167852 }
167853 break;
167854 case 210: /* expr ::= expr IS DISTINCT FROM expr */
167855 {
167856 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528);
167857 binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL);
167858 }
167859 break;
167860 case 211: /* expr ::= NOT expr */
167861 case 212: /* expr ::= BITNOT expr */ yytestcase(yyruleno==212);
167862 {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/}
167863 break;
167864 case 213: /* expr ::= PLUS|MINUS expr */
167865 {
167866 yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0);
167867 /*A-overwrites-B*/
167868 }
167869 break;
167870 case 214: /* expr ::= expr PTR expr */
167871 {
167872 ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528);
167873 pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528);
167874 yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
167875 }
167876 yymsp[-2].minor.yy528 = yylhsminor.yy528;
167877 break;
167878 case 215: /* between_op ::= BETWEEN */
167879 case 218: /* in_op ::= IN */ yytestcase(yyruleno==218);
167880 {yymsp[0].minor.yy394 = 0;}
167881 break;
167882 case 217: /* expr ::= expr between_op expr AND expr */
167883 {
167884 ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
167885 pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528);
167886 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0);
167887 if( yymsp[-4].minor.yy528 ){
@@ -167632,11 +167890,11 @@
167890 sqlite3ExprListDelete(pParse->db, pList);
167891 }
167892 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167893 }
167894 break;
167895 case 220: /* expr ::= expr in_op LP exprlist RP */
167896 {
167897 if( yymsp[-1].minor.yy322==0 ){
167898 /* Expressions of the form
167899 **
167900 ** expr1 IN ()
@@ -167644,11 +167902,12 @@
167902 **
167903 ** simplify to constants 0 (false) and 1 (true), respectively,
167904 ** regardless of the value of expr1.
167905 */
167906 sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528);
167907 yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false");
167908 if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528);
167909 }else{
167910 Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
167911 if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){
167912 yymsp[-1].minor.yy322->a[0].pExpr = 0;
167913 sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
@@ -167672,41 +167931,41 @@
167931 }
167932 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167933 }
167934 }
167935 break;
167936 case 221: /* expr ::= LP select RP */
167937 {
167938 yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
167939 sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47);
167940 }
167941 break;
167942 case 222: /* expr ::= expr in_op LP select RP */
167943 {
167944 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
167945 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47);
167946 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167947 }
167948 break;
167949 case 223: /* expr ::= expr in_op nm dbnm paren_exprlist */
167950 {
167951 SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
167952 Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
167953 if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322);
167954 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
167955 sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect);
167956 if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
167957 }
167958 break;
167959 case 224: /* expr ::= EXISTS LP select RP */
167960 {
167961 Expr *p;
167962 p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
167963 sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47);
167964 }
167965 break;
167966 case 225: /* expr ::= CASE case_operand case_exprlist case_else END */
167967 {
167968 yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0);
167969 if( yymsp[-4].minor.yy528 ){
167970 yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322;
167971 sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528);
@@ -167714,406 +167973,406 @@
167973 sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
167974 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
167975 }
167976 }
167977 break;
167978 case 226: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
167979 {
167980 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
167981 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528);
167982 }
167983 break;
167984 case 227: /* case_exprlist ::= WHEN expr THEN expr */
167985 {
167986 yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
167987 yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528);
167988 }
167989 break;
167990 case 230: /* case_operand ::= expr */
167991 {yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/}
167992 break;
167993 case 233: /* nexprlist ::= nexprlist COMMA expr */
167994 {yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);}
167995 break;
167996 case 234: /* nexprlist ::= expr */
167997 {yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/}
167998 break;
167999 case 236: /* paren_exprlist ::= LP exprlist RP */
168000 case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241);
168001 {yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
168002 break;
168003 case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
168004 {
168005 sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
168006 sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394,
168007 &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF);
168008 if( IN_RENAME_OBJECT && pParse->pNewIndex ){
168009 sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
168010 }
168011 }
168012 break;
168013 case 238: /* uniqueflag ::= UNIQUE */
168014 case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280);
168015 {yymsp[0].minor.yy394 = OE_Abort;}
168016 break;
168017 case 239: /* uniqueflag ::= */
168018 {yymsp[1].minor.yy394 = OE_None;}
168019 break;
168020 case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */
168021 {
168022 yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394);
168023 }
168024 break;
168025 case 243: /* eidlist ::= nm collate sortorder */
168026 {
168027 yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/
168028 }
168029 break;
168030 case 246: /* cmd ::= DROP INDEX ifexists fullname */
168031 {sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);}
168032 break;
168033 case 247: /* cmd ::= VACUUM vinto */
168034 {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);}
168035 break;
168036 case 248: /* cmd ::= VACUUM nm vinto */
168037 {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);}
168038 break;
168039 case 251: /* cmd ::= PRAGMA nm dbnm */
168040 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
168041 break;
168042 case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
168043 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
168044 break;
168045 case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
168046 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
168047 break;
168048 case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
168049 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
168050 break;
168051 case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
168052 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
168053 break;
168054 case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
168055 {
168056 Token all;
168057 all.z = yymsp[-3].minor.yy0.z;
168058 all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
168059 sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all);
168060 }
168061 break;
168062 case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
168063 {
168064 sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394);
168065 yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
168066 }
168067 break;
168068 case 260: /* trigger_time ::= BEFORE|AFTER */
168069 { yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ }
168070 break;
168071 case 261: /* trigger_time ::= INSTEAD OF */
168072 { yymsp[-1].minor.yy394 = TK_INSTEAD;}
168073 break;
168074 case 262: /* trigger_time ::= */
168075 { yymsp[1].minor.yy394 = TK_BEFORE; }
168076 break;
168077 case 263: /* trigger_event ::= DELETE|INSERT */
168078 case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264);
168079 {yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;}
168080 break;
168081 case 265: /* trigger_event ::= UPDATE OF idlist */
168082 {yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;}
168083 break;
168084 case 266: /* when_clause ::= */
168085 case 285: /* key_opt ::= */ yytestcase(yyruleno==285);
168086 { yymsp[1].minor.yy528 = 0; }
168087 break;
168088 case 267: /* when_clause ::= WHEN expr */
168089 case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286);
168090 { yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; }
168091 break;
168092 case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
168093 {
168094 assert( yymsp[-2].minor.yy33!=0 );
168095 yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33;
168096 yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33;
168097 }
168098 break;
168099 case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */
168100 {
168101 assert( yymsp[-1].minor.yy33!=0 );
168102 yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33;
168103 }
168104 break;
168105 case 270: /* trnm ::= nm DOT nm */
168106 {
168107 yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
168108 sqlite3ErrorMsg(pParse,
168109 "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
168110 "statements within triggers");
168111 }
168112 break;
168113 case 271: /* tridxby ::= INDEXED BY nm */
168114 {
168115 sqlite3ErrorMsg(pParse,
168116 "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
168117 "within triggers");
168118 }
168119 break;
168120 case 272: /* tridxby ::= NOT INDEXED */
168121 {
168122 sqlite3ErrorMsg(pParse,
168123 "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
168124 "within triggers");
168125 }
168126 break;
168127 case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
168128 {yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);}
168129 yymsp[-8].minor.yy33 = yylhsminor.yy33;
168130 break;
168131 case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
168132 {
168133 yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/
168134 }
168135 yymsp[-7].minor.yy33 = yylhsminor.yy33;
168136 break;
168137 case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
168138 {yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);}
168139 yymsp[-5].minor.yy33 = yylhsminor.yy33;
168140 break;
168141 case 276: /* trigger_cmd ::= scanpt select scanpt */
168142 {yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/}
168143 yymsp[-2].minor.yy33 = yylhsminor.yy33;
168144 break;
168145 case 277: /* expr ::= RAISE LP IGNORE RP */
168146 {
168147 yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
168148 if( yymsp[-3].minor.yy528 ){
168149 yymsp[-3].minor.yy528->affExpr = OE_Ignore;
168150 }
168151 }
168152 break;
168153 case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */
168154 {
168155 yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
168156 if( yymsp[-5].minor.yy528 ) {
168157 yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394;
168158 }
168159 }
168160 break;
168161 case 279: /* raisetype ::= ROLLBACK */
168162 {yymsp[0].minor.yy394 = OE_Rollback;}
168163 break;
168164 case 281: /* raisetype ::= FAIL */
168165 {yymsp[0].minor.yy394 = OE_Fail;}
168166 break;
168167 case 282: /* cmd ::= DROP TRIGGER ifexists fullname */
168168 {
168169 sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394);
168170 }
168171 break;
168172 case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
168173 {
168174 sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528);
168175 }
168176 break;
168177 case 284: /* cmd ::= DETACH database_kw_opt expr */
168178 {
168179 sqlite3Detach(pParse, yymsp[0].minor.yy528);
168180 }
168181 break;
168182 case 287: /* cmd ::= REINDEX */
168183 {sqlite3Reindex(pParse, 0, 0);}
168184 break;
168185 case 288: /* cmd ::= REINDEX nm dbnm */
168186 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
168187 break;
168188 case 289: /* cmd ::= ANALYZE */
168189 {sqlite3Analyze(pParse, 0, 0);}
168190 break;
168191 case 290: /* cmd ::= ANALYZE nm dbnm */
168192 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
168193 break;
168194 case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
168195 {
168196 sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0);
168197 }
168198 break;
168199 case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
168200 {
168201 yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
168202 sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
168203 }
168204 break;
168205 case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
168206 {
168207 sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0);
168208 }
168209 break;
168210 case 294: /* add_column_fullname ::= fullname */
168211 {
168212 disableLookaside(pParse);
168213 sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131);
168214 }
168215 break;
168216 case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
168217 {
168218 sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
168219 }
168220 break;
168221 case 296: /* cmd ::= create_vtab */
168222 {sqlite3VtabFinishParse(pParse,0);}
168223 break;
168224 case 297: /* cmd ::= create_vtab LP vtabarglist RP */
168225 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
168226 break;
168227 case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
168228 {
168229 sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394);
168230 }
168231 break;
168232 case 299: /* vtabarg ::= */
168233 {sqlite3VtabArgInit(pParse);}
168234 break;
168235 case 300: /* vtabargtoken ::= ANY */
168236 case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301);
168237 case 302: /* lp ::= LP */ yytestcase(yyruleno==302);
168238 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
168239 break;
168240 case 303: /* with ::= WITH wqlist */
168241 case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304);
168242 { sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); }
168243 break;
168244 case 305: /* wqas ::= AS */
168245 {yymsp[0].minor.yy516 = M10d_Any;}
168246 break;
168247 case 306: /* wqas ::= AS MATERIALIZED */
168248 {yymsp[-1].minor.yy516 = M10d_Yes;}
168249 break;
168250 case 307: /* wqas ::= AS NOT MATERIALIZED */
168251 {yymsp[-2].minor.yy516 = M10d_No;}
168252 break;
168253 case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */
168254 {
168255 yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/
168256 }
168257 break;
168258 case 309: /* wqlist ::= wqitem */
168259 {
168260 yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/
168261 }
168262 break;
168263 case 310: /* wqlist ::= wqlist COMMA wqitem */
168264 {
168265 yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385);
168266 }
168267 break;
168268 case 311: /* windowdefn_list ::= windowdefn */
168269 { yylhsminor.yy41 = yymsp[0].minor.yy41; }
168270 yymsp[0].minor.yy41 = yylhsminor.yy41;
168271 break;
168272 case 312: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
168273 {
168274 assert( yymsp[0].minor.yy41!=0 );
168275 sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41);
168276 yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41;
168277 yylhsminor.yy41 = yymsp[0].minor.yy41;
168278 }
168279 yymsp[-2].minor.yy41 = yylhsminor.yy41;
168280 break;
168281 case 313: /* windowdefn ::= nm AS LP window RP */
168282 {
168283 if( ALWAYS(yymsp[-1].minor.yy41) ){
168284 yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
168285 }
168286 yylhsminor.yy41 = yymsp[-1].minor.yy41;
168287 }
168288 yymsp[-4].minor.yy41 = yylhsminor.yy41;
168289 break;
168290 case 314: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
168291 {
168292 yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0);
168293 }
168294 break;
168295 case 315: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
168296 {
168297 yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0);
168298 }
168299 yymsp[-5].minor.yy41 = yylhsminor.yy41;
168300 break;
168301 case 316: /* window ::= ORDER BY sortlist frame_opt */
168302 {
168303 yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0);
168304 }
168305 break;
168306 case 317: /* window ::= nm ORDER BY sortlist frame_opt */
168307 {
168308 yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
168309 }
168310 yymsp[-4].minor.yy41 = yylhsminor.yy41;
168311 break;
168312 case 318: /* window ::= frame_opt */
168313 case 337: /* filter_over ::= over_clause */ yytestcase(yyruleno==337);
168314 {
168315 yylhsminor.yy41 = yymsp[0].minor.yy41;
168316 }
168317 yymsp[0].minor.yy41 = yylhsminor.yy41;
168318 break;
168319 case 319: /* window ::= nm frame_opt */
168320 {
168321 yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0);
168322 }
168323 yymsp[-1].minor.yy41 = yylhsminor.yy41;
168324 break;
168325 case 320: /* frame_opt ::= */
168326 {
168327 yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
168328 }
168329 break;
168330 case 321: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
168331 {
168332 yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516);
168333 }
168334 yymsp[-2].minor.yy41 = yylhsminor.yy41;
168335 break;
168336 case 322: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
168337 {
168338 yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516);
168339 }
168340 yymsp[-5].minor.yy41 = yylhsminor.yy41;
168341 break;
168342 case 324: /* frame_bound_s ::= frame_bound */
168343 case 326: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==326);
168344 {yylhsminor.yy595 = yymsp[0].minor.yy595;}
168345 yymsp[0].minor.yy595 = yylhsminor.yy595;
168346 break;
168347 case 325: /* frame_bound_s ::= UNBOUNDED PRECEDING */
168348 case 327: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==327);
168349 case 329: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==329);
168350 {yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;}
168351 yymsp[-1].minor.yy595 = yylhsminor.yy595;
168352 break;
168353 case 328: /* frame_bound ::= expr PRECEDING|FOLLOWING */
168354 {yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;}
168355 yymsp[-1].minor.yy595 = yylhsminor.yy595;
168356 break;
168357 case 330: /* frame_exclude_opt ::= */
168358 {yymsp[1].minor.yy516 = 0;}
168359 break;
168360 case 331: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
168361 {yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;}
168362 break;
168363 case 332: /* frame_exclude ::= NO OTHERS */
168364 case 333: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==333);
168365 {yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/}
168366 break;
168367 case 334: /* frame_exclude ::= GROUP|TIES */
168368 {yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/}
168369 break;
168370 case 335: /* window_clause ::= WINDOW windowdefn_list */
168371 { yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; }
168372 break;
168373 case 336: /* filter_over ::= filter_clause over_clause */
168374 {
168375 if( yymsp[0].minor.yy41 ){
168376 yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528;
168377 }else{
168378 sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
@@ -168120,11 +168379,11 @@
168379 }
168380 yylhsminor.yy41 = yymsp[0].minor.yy41;
168381 }
168382 yymsp[-1].minor.yy41 = yylhsminor.yy41;
168383 break;
168384 case 338: /* filter_over ::= filter_clause */
168385 {
168386 yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
168387 if( yylhsminor.yy41 ){
168388 yylhsminor.yy41->eFrmType = TK_FILTER;
168389 yylhsminor.yy41->pFilter = yymsp[0].minor.yy528;
@@ -168132,91 +168391,91 @@
168391 sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528);
168392 }
168393 }
168394 yymsp[0].minor.yy41 = yylhsminor.yy41;
168395 break;
168396 case 339: /* over_clause ::= OVER LP window RP */
168397 {
168398 yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41;
168399 assert( yymsp[-3].minor.yy41!=0 );
168400 }
168401 break;
168402 case 340: /* over_clause ::= OVER nm */
168403 {
168404 yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
168405 if( yymsp[-1].minor.yy41 ){
168406 yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
168407 }
168408 }
168409 break;
168410 case 341: /* filter_clause ::= FILTER LP WHERE expr RP */
168411 { yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; }
168412 break;
168413 default:
168414 /* (342) input ::= cmdlist */ yytestcase(yyruleno==342);
168415 /* (343) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==343);
168416 /* (344) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=344);
168417 /* (345) ecmd ::= SEMI */ yytestcase(yyruleno==345);
168418 /* (346) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==346);
168419 /* (347) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=347);
168420 /* (348) trans_opt ::= */ yytestcase(yyruleno==348);
168421 /* (349) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==349);
168422 /* (350) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==350);
168423 /* (351) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==351);
168424 /* (352) savepoint_opt ::= */ yytestcase(yyruleno==352);
168425 /* (353) cmd ::= create_table create_table_args */ yytestcase(yyruleno==353);
168426 /* (354) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=354);
168427 /* (355) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==355);
168428 /* (356) columnlist ::= columnname carglist */ yytestcase(yyruleno==356);
168429 /* (357) nm ::= ID|INDEXED */ yytestcase(yyruleno==357);
168430 /* (358) nm ::= STRING */ yytestcase(yyruleno==358);
168431 /* (359) nm ::= JOIN_KW */ yytestcase(yyruleno==359);
168432 /* (360) typetoken ::= typename */ yytestcase(yyruleno==360);
168433 /* (361) typename ::= ID|STRING */ yytestcase(yyruleno==361);
168434 /* (362) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=362);
168435 /* (363) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=363);
168436 /* (364) carglist ::= carglist ccons */ yytestcase(yyruleno==364);
168437 /* (365) carglist ::= */ yytestcase(yyruleno==365);
168438 /* (366) ccons ::= NULL onconf */ yytestcase(yyruleno==366);
168439 /* (367) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==367);
168440 /* (368) ccons ::= AS generated */ yytestcase(yyruleno==368);
168441 /* (369) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==369);
168442 /* (370) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==370);
168443 /* (371) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=371);
168444 /* (372) tconscomma ::= */ yytestcase(yyruleno==372);
168445 /* (373) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=373);
168446 /* (374) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=374);
168447 /* (375) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=375);
168448 /* (376) oneselect ::= values */ yytestcase(yyruleno==376);
168449 /* (377) sclp ::= selcollist COMMA */ yytestcase(yyruleno==377);
168450 /* (378) as ::= ID|STRING */ yytestcase(yyruleno==378);
168451 /* (379) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=379);
168452 /* (380) returning ::= */ yytestcase(yyruleno==380);
168453 /* (381) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=381);
168454 /* (382) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==382);
168455 /* (383) exprlist ::= nexprlist */ yytestcase(yyruleno==383);
168456 /* (384) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=384);
168457 /* (385) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=385);
168458 /* (386) nmnum ::= ON */ yytestcase(yyruleno==386);
168459 /* (387) nmnum ::= DELETE */ yytestcase(yyruleno==387);
168460 /* (388) nmnum ::= DEFAULT */ yytestcase(yyruleno==388);
168461 /* (389) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==389);
168462 /* (390) foreach_clause ::= */ yytestcase(yyruleno==390);
168463 /* (391) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==391);
168464 /* (392) trnm ::= nm */ yytestcase(yyruleno==392);
168465 /* (393) tridxby ::= */ yytestcase(yyruleno==393);
168466 /* (394) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==394);
168467 /* (395) database_kw_opt ::= */ yytestcase(yyruleno==395);
168468 /* (396) kwcolumn_opt ::= */ yytestcase(yyruleno==396);
168469 /* (397) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==397);
168470 /* (398) vtabarglist ::= vtabarg */ yytestcase(yyruleno==398);
168471 /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==399);
168472 /* (400) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==400);
168473 /* (401) anylist ::= */ yytestcase(yyruleno==401);
168474 /* (402) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==402);
168475 /* (403) anylist ::= anylist ANY */ yytestcase(yyruleno==403);
168476 /* (404) with ::= */ yytestcase(yyruleno==404);
168477 break;
168478 /********** End reduce actions ************************************************/
168479 };
168480 assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
168481 yygoto = yyRuleInfoLhs[yyruleno];
@@ -174912,10 +175171,28 @@
175171 */
175172 SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
175173 int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
175174 return iDb<0 ? 0 : db->aDb[iDb].pBt;
175175 }
175176
175177 /*
175178 ** Return the name of the N-th database schema. Return NULL if N is out
175179 ** of range.
175180 */
175181 SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){
175182 #ifdef SQLITE_ENABLE_API_ARMOR
175183 if( !sqlite3SafetyCheckOk(db) ){
175184 (void)SQLITE_MISUSE_BKPT;
175185 return 0;
175186 }
175187 #endif
175188 if( N<0 || N>=db->nDb ){
175189 return 0;
175190 }else{
175191 return db->aDb[N].zDbSName;
175192 }
175193 }
175194
175195 /*
175196 ** Return the filename of the database associated with a database
175197 ** connection.
175198 */
@@ -190551,10 +190828,12 @@
190828 if( rc==SQLITE_OK ){
190829 if( pNode->key.n ){
190830 pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix);
190831 }
190832 pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix);
190833 assert( nPrefix+nSuffix<=nTerm );
190834 assert( nPrefix>=0 );
190835 memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix);
190836 pBlk->n += nSuffix;
190837
190838 memcpy(pNode->key.a, zTerm, nTerm);
190839 pNode->key.n = nTerm;
@@ -190673,10 +190952,11 @@
190952 NodeWriter *pLeaf; /* Object used to write leaf nodes */
190953
190954 pLeaf = &pWriter->aNodeWriter[0];
190955 nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm);
190956 nSuffix = nTerm - nPrefix;
190957 if(nSuffix<=0 ) return FTS_CORRUPT_VTAB;
190958
190959 nSpace = sqlite3Fts3VarintLen(nPrefix);
190960 nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
190961 nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
190962
@@ -236295,11 +236575,11 @@
236575 int nArg, /* Number of args */
236576 sqlite3_value **apUnused /* Function arguments */
236577 ){
236578 assert( nArg==0 );
236579 UNUSED_PARAM2(nArg, apUnused);
236580 sqlite3_result_text(pCtx, "fts5: 2022-06-15 16:26:37 56c60a35ea457f06db58ec3f694a1ae16fd03e6625da1d7879d63d72bbcb1c62", -1, SQLITE_TRANSIENT);
236581 }
236582
236583 /*
236584 ** Return true if zName is the extension on one of the shadow tables used
236585 ** by this module.
236586
+23 -1
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.39.0"
150150
#define SQLITE_VERSION_NUMBER 3039000
151
-#define SQLITE_SOURCE_ID "2022-05-10 00:24:01 c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527"
151
+#define SQLITE_SOURCE_ID "2022-06-15 16:26:37 56c60a35ea457f06db58ec3f694a1ae16fd03e6625da1d7879d63d72bbcb1c62"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -6274,10 +6274,32 @@
62746274
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
62756275
** create the statement in the first place.
62766276
*/
62776277
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
62786278
6279
+/*
6280
+** CAPI3REF: Return The Schema Name For A Database Connection
6281
+** METHOD: sqlite3
6282
+**
6283
+** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
6284
+** for the N-th database on database connection D, or a NULL pointer of N is
6285
+** out of range. An N alue of 0 means the main database file. An N of 1 is
6286
+** the "temp" schema. Larger values of N correspond to various ATTACH-ed
6287
+** databases.
6288
+**
6289
+** Space to hold the string that is returned by sqlite3_db_name() is managed
6290
+** by SQLite itself. The string might be deallocated by any operation that
6291
+** changes the schema, including [ATTACH] or [DETACH] or calls to
6292
+** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that
6293
+** occur on a different thread. Applications that need to
6294
+** remember the string long-term should make their own copy. Applications that
6295
+** are accessing the same database connection simultaneously on multiple
6296
+** threads should mutex-protect calls to this API and should make their own
6297
+** private copy of the result prior to releasing the mutex.
6298
+*/
6299
+SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N);
6300
+
62796301
/*
62806302
** CAPI3REF: Return The Filename For A Database Connection
62816303
** METHOD: sqlite3
62826304
**
62836305
** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
62846306
--- 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-05-10 00:24:01 c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -6274,10 +6274,32 @@
6274 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
6275 ** create the statement in the first place.
6276 */
6277 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
6278
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6279 /*
6280 ** CAPI3REF: Return The Filename For A Database Connection
6281 ** METHOD: sqlite3
6282 **
6283 ** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
6284
--- 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-06-15 16:26:37 56c60a35ea457f06db58ec3f694a1ae16fd03e6625da1d7879d63d72bbcb1c62"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -6274,10 +6274,32 @@
6274 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
6275 ** create the statement in the first place.
6276 */
6277 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
6278
6279 /*
6280 ** CAPI3REF: Return The Schema Name For A Database Connection
6281 ** METHOD: sqlite3
6282 **
6283 ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
6284 ** for the N-th database on database connection D, or a NULL pointer of N is
6285 ** out of range. An N alue of 0 means the main database file. An N of 1 is
6286 ** the "temp" schema. Larger values of N correspond to various ATTACH-ed
6287 ** databases.
6288 **
6289 ** Space to hold the string that is returned by sqlite3_db_name() is managed
6290 ** by SQLite itself. The string might be deallocated by any operation that
6291 ** changes the schema, including [ATTACH] or [DETACH] or calls to
6292 ** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that
6293 ** occur on a different thread. Applications that need to
6294 ** remember the string long-term should make their own copy. Applications that
6295 ** are accessing the same database connection simultaneously on multiple
6296 ** threads should mutex-protect calls to this API and should make their own
6297 ** private copy of the result prior to releasing the mutex.
6298 */
6299 SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N);
6300
6301 /*
6302 ** CAPI3REF: Return The Filename For A Database Connection
6303 ** METHOD: sqlite3
6304 **
6305 ** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
6306
--- skins/darkmode/css.txt
+++ skins/darkmode/css.txt
@@ -131,13 +131,12 @@
131131
.button:focus,
132132
button:focus,
133133
input[type=button]:focus,
134134
input[type=reset]:focus,
135135
input[type=submit]:focus {
136
- color: #333;
136
+ outline: 2px outset #333;
137137
border-color: #888;
138
- outline: 0
139138
}
140139
141140
/* All page content from the bottom of the menu or submenu down to
142141
** the footer */
143142
div.content {
144143
--- skins/darkmode/css.txt
+++ skins/darkmode/css.txt
@@ -131,13 +131,12 @@
131 .button:focus,
132 button:focus,
133 input[type=button]:focus,
134 input[type=reset]:focus,
135 input[type=submit]:focus {
136 color: #333;
137 border-color: #888;
138 outline: 0
139 }
140
141 /* All page content from the bottom of the menu or submenu down to
142 ** the footer */
143 div.content {
144
--- skins/darkmode/css.txt
+++ skins/darkmode/css.txt
@@ -131,13 +131,12 @@
131 .button:focus,
132 button:focus,
133 input[type=button]:focus,
134 input[type=reset]:focus,
135 input[type=submit]:focus {
136 outline: 2px outset #333;
137 border-color: #888;
 
138 }
139
140 /* All page content from the bottom of the menu or submenu down to
141 ** the footer */
142 div.content {
143
+3 -1
--- src/add.c
+++ src/add.c
@@ -882,11 +882,13 @@
882882
}
883883
}
884884
db_finalize(&q);
885885
/* show command summary */
886886
fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
887
-
887
+ if(dryRunFlag!=0){
888
+ fossil_print("Dry-run mode: no changes were made.\n");
889
+ }
888890
db_end_transaction(dryRunFlag);
889891
}
890892
891893
/*
892894
** Rename a single file.
893895
--- src/add.c
+++ src/add.c
@@ -882,11 +882,13 @@
882 }
883 }
884 db_finalize(&q);
885 /* show command summary */
886 fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
887
 
 
888 db_end_transaction(dryRunFlag);
889 }
890
891 /*
892 ** Rename a single file.
893
--- src/add.c
+++ src/add.c
@@ -882,11 +882,13 @@
882 }
883 }
884 db_finalize(&q);
885 /* show command summary */
886 fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
887 if(dryRunFlag!=0){
888 fossil_print("Dry-run mode: no changes were made.\n");
889 }
890 db_end_transaction(dryRunFlag);
891 }
892
893 /*
894 ** Rename a single file.
895
+20 -1
--- src/alerts.c
+++ src/alerts.c
@@ -278,10 +278,18 @@
278278
@ the "From:" address of the email notification.
279279
@ The system administrator should arrange for emails sent to this address
280280
@ to be handed off to the "fossil email incoming" command so that Fossil
281281
@ can handle bounces. (Property: "email-self")</p>
282282
@ <hr>
283
+
284
+ entry_attribute("List-ID", 40, "email-listid",
285
+ "elistid", "", 0);
286
+ @ <p>
287
+ @ If this is not an empty string, then it becomes the argument to
288
+ @ a "List-ID:" header on all out-bound notification emails.
289
+ @ (Property: "email-listid")</p>
290
+ @ <hr>
283291
284292
entry_attribute("Repository Nickname", 16, "email-subname",
285293
"enn", "", 0);
286294
@ <p><b>Required.</b>
287295
@ This is short name used to identifies the repository in the
@@ -409,10 +417,11 @@
409417
const char *zDest; /* How to send email. */
410418
const char *zDb; /* Name of database file */
411419
const char *zDir; /* Directory in which to store as email files */
412420
const char *zCmd; /* Command to run for each email */
413421
const char *zFrom; /* Emails come from here */
422
+ const char *zListId; /* Argument to List-ID header */
414423
SmtpSession *pSmtp; /* SMTP relay connection */
415424
Blob out; /* For zDest=="blob" */
416425
char *zErr; /* Error message */
417426
u32 mFlags; /* Flags */
418427
int bImmediateFail; /* On any error, call fossil_fatal() */
@@ -434,10 +443,11 @@
434443
sqlite3_close(p->db);
435444
p->db = 0;
436445
p->zDb = 0;
437446
p->zDir = 0;
438447
p->zCmd = 0;
448
+ p->zListId = 0;
439449
if( p->pSmtp ){
440450
smtp_client_quit(p->pSmtp);
441451
smtp_session_free(p->pSmtp);
442452
p->pSmtp = 0;
443453
}
@@ -514,10 +524,11 @@
514524
}else{
515525
p->zDest = db_get("email-send-method",0);
516526
}
517527
if( fossil_strcmp(p->zDest,"off")==0 ) return p;
518528
if( emailerGetSetting(p, &p->zFrom, "email-self") ) return p;
529
+ p->zListId = db_get("email-listid", 0);
519530
if( fossil_strcmp(p->zDest,"db")==0 ){
520531
char *zErr;
521532
int rc;
522533
if( emailerGetSetting(p, &p->zDb, "email-send-db") ) return p;
523534
rc = sqlite3_open(p->zDb, &p->db);
@@ -881,10 +892,13 @@
881892
blob_appendf(pOut, "Sender: <%s>\r\n", p->zFrom);
882893
}else{
883894
blob_appendf(pOut, "From: <%s>\r\n", p->zFrom);
884895
}
885896
blob_appendf(pOut, "Date: %z\r\n", cgi_rfc822_datestamp(time(0)));
897
+ if( p->zListId && p->zListId[0] ){
898
+ blob_appendf(pOut, "List-Id: %s\r\n", p->zListId);
899
+ }
886900
if( strstr(blob_str(pHdr), "\r\nMessage-Id:")==0 ){
887901
/* Message-id format: "<$(date)x$(random)@$(from-host)>" where $(date) is
888902
** the current unix-time in hex, $(random) is a 64-bit random number,
889903
** and $(from) is the domain part of the email-self setting. */
890904
sqlite3_randomness(sizeof(r1), &r1);
@@ -969,11 +983,11 @@
969983
** brackets. Examples: "[fossil-src]", "[sqlite-src]".
970984
*/
971985
/*
972986
** SETTING: email-renew-interval width=16
973987
** If this setting as an integer N that is 14 or greater then email
974
-** notification is suspected for subscriptions that have a "last contact
988
+** notification is suspended for subscriptions that have a "last contact
975989
** time" of more than N days ago. The "last contact time" is recorded
976990
** in the SUBSCRIBER.LASTCONTACT entry of the database. Logging in,
977991
** sending a forum post, editing a wiki page, changing subscription settings
978992
** at /alerts, or visiting /renew all update the last contact time.
979993
** If this setting is not an integer value or is less than 14 or undefined,
@@ -1029,10 +1043,15 @@
10291043
/*
10301044
** SETTING: email-self width=40
10311045
** This is the email address for the repository. Outbound emails add
10321046
** this email address as the "From:" field.
10331047
*/
1048
+/*
1049
+** SETTING: email-listid width=40
1050
+** If this setting is not an empty string, then it becomes the argument to
1051
+** a "List-ID:" header that is added to all out-bound notification emails.
1052
+*/
10341053
/*
10351054
** SETTING: email-send-relayhost width=40 sensitive
10361055
** This is the hostname and TCP port to which output email messages
10371056
** are sent when email-send-method is "relay". There should be an
10381057
** SMTP server configured as a Mail Submission Agent listening on the
10391058
--- src/alerts.c
+++ src/alerts.c
@@ -278,10 +278,18 @@
278 @ the "From:" address of the email notification.
279 @ The system administrator should arrange for emails sent to this address
280 @ to be handed off to the "fossil email incoming" command so that Fossil
281 @ can handle bounces. (Property: "email-self")</p>
282 @ <hr>
 
 
 
 
 
 
 
 
283
284 entry_attribute("Repository Nickname", 16, "email-subname",
285 "enn", "", 0);
286 @ <p><b>Required.</b>
287 @ This is short name used to identifies the repository in the
@@ -409,10 +417,11 @@
409 const char *zDest; /* How to send email. */
410 const char *zDb; /* Name of database file */
411 const char *zDir; /* Directory in which to store as email files */
412 const char *zCmd; /* Command to run for each email */
413 const char *zFrom; /* Emails come from here */
 
414 SmtpSession *pSmtp; /* SMTP relay connection */
415 Blob out; /* For zDest=="blob" */
416 char *zErr; /* Error message */
417 u32 mFlags; /* Flags */
418 int bImmediateFail; /* On any error, call fossil_fatal() */
@@ -434,10 +443,11 @@
434 sqlite3_close(p->db);
435 p->db = 0;
436 p->zDb = 0;
437 p->zDir = 0;
438 p->zCmd = 0;
 
439 if( p->pSmtp ){
440 smtp_client_quit(p->pSmtp);
441 smtp_session_free(p->pSmtp);
442 p->pSmtp = 0;
443 }
@@ -514,10 +524,11 @@
514 }else{
515 p->zDest = db_get("email-send-method",0);
516 }
517 if( fossil_strcmp(p->zDest,"off")==0 ) return p;
518 if( emailerGetSetting(p, &p->zFrom, "email-self") ) return p;
 
519 if( fossil_strcmp(p->zDest,"db")==0 ){
520 char *zErr;
521 int rc;
522 if( emailerGetSetting(p, &p->zDb, "email-send-db") ) return p;
523 rc = sqlite3_open(p->zDb, &p->db);
@@ -881,10 +892,13 @@
881 blob_appendf(pOut, "Sender: <%s>\r\n", p->zFrom);
882 }else{
883 blob_appendf(pOut, "From: <%s>\r\n", p->zFrom);
884 }
885 blob_appendf(pOut, "Date: %z\r\n", cgi_rfc822_datestamp(time(0)));
 
 
 
886 if( strstr(blob_str(pHdr), "\r\nMessage-Id:")==0 ){
887 /* Message-id format: "<$(date)x$(random)@$(from-host)>" where $(date) is
888 ** the current unix-time in hex, $(random) is a 64-bit random number,
889 ** and $(from) is the domain part of the email-self setting. */
890 sqlite3_randomness(sizeof(r1), &r1);
@@ -969,11 +983,11 @@
969 ** brackets. Examples: "[fossil-src]", "[sqlite-src]".
970 */
971 /*
972 ** SETTING: email-renew-interval width=16
973 ** If this setting as an integer N that is 14 or greater then email
974 ** notification is suspected for subscriptions that have a "last contact
975 ** time" of more than N days ago. The "last contact time" is recorded
976 ** in the SUBSCRIBER.LASTCONTACT entry of the database. Logging in,
977 ** sending a forum post, editing a wiki page, changing subscription settings
978 ** at /alerts, or visiting /renew all update the last contact time.
979 ** If this setting is not an integer value or is less than 14 or undefined,
@@ -1029,10 +1043,15 @@
1029 /*
1030 ** SETTING: email-self width=40
1031 ** This is the email address for the repository. Outbound emails add
1032 ** this email address as the "From:" field.
1033 */
 
 
 
 
 
1034 /*
1035 ** SETTING: email-send-relayhost width=40 sensitive
1036 ** This is the hostname and TCP port to which output email messages
1037 ** are sent when email-send-method is "relay". There should be an
1038 ** SMTP server configured as a Mail Submission Agent listening on the
1039
--- src/alerts.c
+++ src/alerts.c
@@ -278,10 +278,18 @@
278 @ the "From:" address of the email notification.
279 @ The system administrator should arrange for emails sent to this address
280 @ to be handed off to the "fossil email incoming" command so that Fossil
281 @ can handle bounces. (Property: "email-self")</p>
282 @ <hr>
283
284 entry_attribute("List-ID", 40, "email-listid",
285 "elistid", "", 0);
286 @ <p>
287 @ If this is not an empty string, then it becomes the argument to
288 @ a "List-ID:" header on all out-bound notification emails.
289 @ (Property: "email-listid")</p>
290 @ <hr>
291
292 entry_attribute("Repository Nickname", 16, "email-subname",
293 "enn", "", 0);
294 @ <p><b>Required.</b>
295 @ This is short name used to identifies the repository in the
@@ -409,10 +417,11 @@
417 const char *zDest; /* How to send email. */
418 const char *zDb; /* Name of database file */
419 const char *zDir; /* Directory in which to store as email files */
420 const char *zCmd; /* Command to run for each email */
421 const char *zFrom; /* Emails come from here */
422 const char *zListId; /* Argument to List-ID header */
423 SmtpSession *pSmtp; /* SMTP relay connection */
424 Blob out; /* For zDest=="blob" */
425 char *zErr; /* Error message */
426 u32 mFlags; /* Flags */
427 int bImmediateFail; /* On any error, call fossil_fatal() */
@@ -434,10 +443,11 @@
443 sqlite3_close(p->db);
444 p->db = 0;
445 p->zDb = 0;
446 p->zDir = 0;
447 p->zCmd = 0;
448 p->zListId = 0;
449 if( p->pSmtp ){
450 smtp_client_quit(p->pSmtp);
451 smtp_session_free(p->pSmtp);
452 p->pSmtp = 0;
453 }
@@ -514,10 +524,11 @@
524 }else{
525 p->zDest = db_get("email-send-method",0);
526 }
527 if( fossil_strcmp(p->zDest,"off")==0 ) return p;
528 if( emailerGetSetting(p, &p->zFrom, "email-self") ) return p;
529 p->zListId = db_get("email-listid", 0);
530 if( fossil_strcmp(p->zDest,"db")==0 ){
531 char *zErr;
532 int rc;
533 if( emailerGetSetting(p, &p->zDb, "email-send-db") ) return p;
534 rc = sqlite3_open(p->zDb, &p->db);
@@ -881,10 +892,13 @@
892 blob_appendf(pOut, "Sender: <%s>\r\n", p->zFrom);
893 }else{
894 blob_appendf(pOut, "From: <%s>\r\n", p->zFrom);
895 }
896 blob_appendf(pOut, "Date: %z\r\n", cgi_rfc822_datestamp(time(0)));
897 if( p->zListId && p->zListId[0] ){
898 blob_appendf(pOut, "List-Id: %s\r\n", p->zListId);
899 }
900 if( strstr(blob_str(pHdr), "\r\nMessage-Id:")==0 ){
901 /* Message-id format: "<$(date)x$(random)@$(from-host)>" where $(date) is
902 ** the current unix-time in hex, $(random) is a 64-bit random number,
903 ** and $(from) is the domain part of the email-self setting. */
904 sqlite3_randomness(sizeof(r1), &r1);
@@ -969,11 +983,11 @@
983 ** brackets. Examples: "[fossil-src]", "[sqlite-src]".
984 */
985 /*
986 ** SETTING: email-renew-interval width=16
987 ** If this setting as an integer N that is 14 or greater then email
988 ** notification is suspended for subscriptions that have a "last contact
989 ** time" of more than N days ago. The "last contact time" is recorded
990 ** in the SUBSCRIBER.LASTCONTACT entry of the database. Logging in,
991 ** sending a forum post, editing a wiki page, changing subscription settings
992 ** at /alerts, or visiting /renew all update the last contact time.
993 ** If this setting is not an integer value or is less than 14 or undefined,
@@ -1029,10 +1043,15 @@
1043 /*
1044 ** SETTING: email-self width=40
1045 ** This is the email address for the repository. Outbound emails add
1046 ** this email address as the "From:" field.
1047 */
1048 /*
1049 ** SETTING: email-listid width=40
1050 ** If this setting is not an empty string, then it becomes the argument to
1051 ** a "List-ID:" header that is added to all out-bound notification emails.
1052 */
1053 /*
1054 ** SETTING: email-send-relayhost width=40 sensitive
1055 ** This is the hostname and TCP port to which output email messages
1056 ** are sent when email-send-method is "relay". There should be an
1057 ** SMTP server configured as a Mail Submission Agent listening on the
1058
+19 -5
--- src/backlink.c
+++ src/backlink.c
@@ -179,11 +179,12 @@
179179
rid = db_int(0, "SELECT rid FROM tagxref WHERE tagid=%d"
180180
" ORDER BY mtime DESC LIMIT 1", tagid);
181181
if( rid==0 ) return;
182182
pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
183183
if( pWiki ){
184
- backlink_extract(pWiki->zWiki, pWiki->zMimetype, tagid, BKLNK_WIKI,
184
+ int mimetype = parse_mimetype( pWiki->zMimetype );
185
+ backlink_extract(pWiki->zWiki, mimetype, tagid, BKLNK_WIKI,
185186
pWiki->rDate, 1);
186187
manifest_destroy(pWiki);
187188
}
188189
}
189190
@@ -295,17 +296,28 @@
295296
markdown(&out, &in, &html_renderer);
296297
blob_reset(&out);
297298
blob_reset(&in);
298299
}
299300
301
+/*
302
+** Transform mimetype string into an integer code.
303
+** NOTE: In the sake of compatability empty string is parsed as MT_UNKNOWN;
304
+** it is yet unclear whether it can safely be changed to MT_NONE.
305
+*/
306
+int parse_mimetype(const char* zMimetype){
307
+ if( zMimetype==0 ) return MT_NONE;
308
+ if( strstr(zMimetype,"wiki")!=0 ) return MT_WIKI;
309
+ if( strstr(zMimetype,"markdown")!=0 ) return MT_MARKDOWN;
310
+ return MT_UNKNOWN;
311
+}
300312
/*
301313
** Parse text looking for hyperlinks. Insert references into the
302314
** BACKLINK table.
303315
*/
304316
void backlink_extract(
305317
char *zSrc, /* Input text from which links are extracted */
306
- const char *zMimetype, /* Mimetype of input. NULL means fossil-wiki */
318
+ int mimetype, /* Mimetype of input. MT_NONE works as MT_WIKI */
307319
int srcid, /* srcid for the source document */
308320
int srctype, /* One of BKLNK_*. 0=comment 1=ticket 2=wiki */
309321
double mtime, /* mtime field for new BACKLINK table entries */
310322
int replaceFlag /* True to overwrite prior BACKLINK entries */
311323
){
@@ -314,15 +326,16 @@
314326
db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid=%d",
315327
srctype, srcid);
316328
}
317329
bklnk.srcid = srcid;
318330
assert( ValidBklnk(srctype) );
331
+ assert( ValidMTC(mimetype) );
319332
bklnk.srctype = srctype;
320333
bklnk.mtime = mtime;
321
- if( zMimetype==0 || strstr(zMimetype,"wiki")!=0 ){
334
+ if( mimetype==MT_NONE || mimetype==MT_WIKI ){
322335
wiki_extract_links(zSrc, &bklnk, srctype==BKLNK_COMMENT ? WIKI_INLINE : 0);
323
- }else if( strstr(zMimetype,"markdown")!=0 ){
336
+ }else if( mimetype==MT_MARKDOWN ){
324337
markdown_extract_links(zSrc, &bklnk);
325338
}
326339
}
327340
328341
/*
@@ -340,10 +353,11 @@
340353
** --mimetype TYPE Use an alternative mimetype.
341354
*/
342355
void test_backlinks_cmd(void){
343356
const char *zMTime = find_option("mtime",0,1);
344357
const char *zMimetype = find_option("mimetype",0,1);
358
+ const int mimetype = parse_mimetype(zMimetype);
345359
Blob in;
346360
int srcid;
347361
int srctype;
348362
double mtime;
349363
@@ -371,11 +385,11 @@
371385
" ' srcid='||quote(new.srcid)||"
372386
" ' mtime='||datetime(new.mtime));\n"
373387
" SELECT raise(ignore);\n"
374388
"END;"
375389
);
376
- backlink_extract(blob_str(&in),zMimetype,srcid,srctype,mtime,0);
390
+ backlink_extract(blob_str(&in),mimetype,srcid,srctype,mtime,0);
377391
blob_reset(&in);
378392
}
379393
380394
381395
/*
382396
--- src/backlink.c
+++ src/backlink.c
@@ -179,11 +179,12 @@
179 rid = db_int(0, "SELECT rid FROM tagxref WHERE tagid=%d"
180 " ORDER BY mtime DESC LIMIT 1", tagid);
181 if( rid==0 ) return;
182 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
183 if( pWiki ){
184 backlink_extract(pWiki->zWiki, pWiki->zMimetype, tagid, BKLNK_WIKI,
 
185 pWiki->rDate, 1);
186 manifest_destroy(pWiki);
187 }
188 }
189
@@ -295,17 +296,28 @@
295 markdown(&out, &in, &html_renderer);
296 blob_reset(&out);
297 blob_reset(&in);
298 }
299
 
 
 
 
 
 
 
 
 
 
 
300 /*
301 ** Parse text looking for hyperlinks. Insert references into the
302 ** BACKLINK table.
303 */
304 void backlink_extract(
305 char *zSrc, /* Input text from which links are extracted */
306 const char *zMimetype, /* Mimetype of input. NULL means fossil-wiki */
307 int srcid, /* srcid for the source document */
308 int srctype, /* One of BKLNK_*. 0=comment 1=ticket 2=wiki */
309 double mtime, /* mtime field for new BACKLINK table entries */
310 int replaceFlag /* True to overwrite prior BACKLINK entries */
311 ){
@@ -314,15 +326,16 @@
314 db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid=%d",
315 srctype, srcid);
316 }
317 bklnk.srcid = srcid;
318 assert( ValidBklnk(srctype) );
 
319 bklnk.srctype = srctype;
320 bklnk.mtime = mtime;
321 if( zMimetype==0 || strstr(zMimetype,"wiki")!=0 ){
322 wiki_extract_links(zSrc, &bklnk, srctype==BKLNK_COMMENT ? WIKI_INLINE : 0);
323 }else if( strstr(zMimetype,"markdown")!=0 ){
324 markdown_extract_links(zSrc, &bklnk);
325 }
326 }
327
328 /*
@@ -340,10 +353,11 @@
340 ** --mimetype TYPE Use an alternative mimetype.
341 */
342 void test_backlinks_cmd(void){
343 const char *zMTime = find_option("mtime",0,1);
344 const char *zMimetype = find_option("mimetype",0,1);
 
345 Blob in;
346 int srcid;
347 int srctype;
348 double mtime;
349
@@ -371,11 +385,11 @@
371 " ' srcid='||quote(new.srcid)||"
372 " ' mtime='||datetime(new.mtime));\n"
373 " SELECT raise(ignore);\n"
374 "END;"
375 );
376 backlink_extract(blob_str(&in),zMimetype,srcid,srctype,mtime,0);
377 blob_reset(&in);
378 }
379
380
381 /*
382
--- src/backlink.c
+++ src/backlink.c
@@ -179,11 +179,12 @@
179 rid = db_int(0, "SELECT rid FROM tagxref WHERE tagid=%d"
180 " ORDER BY mtime DESC LIMIT 1", tagid);
181 if( rid==0 ) return;
182 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
183 if( pWiki ){
184 int mimetype = parse_mimetype( pWiki->zMimetype );
185 backlink_extract(pWiki->zWiki, mimetype, tagid, BKLNK_WIKI,
186 pWiki->rDate, 1);
187 manifest_destroy(pWiki);
188 }
189 }
190
@@ -295,17 +296,28 @@
296 markdown(&out, &in, &html_renderer);
297 blob_reset(&out);
298 blob_reset(&in);
299 }
300
301 /*
302 ** Transform mimetype string into an integer code.
303 ** NOTE: In the sake of compatability empty string is parsed as MT_UNKNOWN;
304 ** it is yet unclear whether it can safely be changed to MT_NONE.
305 */
306 int parse_mimetype(const char* zMimetype){
307 if( zMimetype==0 ) return MT_NONE;
308 if( strstr(zMimetype,"wiki")!=0 ) return MT_WIKI;
309 if( strstr(zMimetype,"markdown")!=0 ) return MT_MARKDOWN;
310 return MT_UNKNOWN;
311 }
312 /*
313 ** Parse text looking for hyperlinks. Insert references into the
314 ** BACKLINK table.
315 */
316 void backlink_extract(
317 char *zSrc, /* Input text from which links are extracted */
318 int mimetype, /* Mimetype of input. MT_NONE works as MT_WIKI */
319 int srcid, /* srcid for the source document */
320 int srctype, /* One of BKLNK_*. 0=comment 1=ticket 2=wiki */
321 double mtime, /* mtime field for new BACKLINK table entries */
322 int replaceFlag /* True to overwrite prior BACKLINK entries */
323 ){
@@ -314,15 +326,16 @@
326 db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid=%d",
327 srctype, srcid);
328 }
329 bklnk.srcid = srcid;
330 assert( ValidBklnk(srctype) );
331 assert( ValidMTC(mimetype) );
332 bklnk.srctype = srctype;
333 bklnk.mtime = mtime;
334 if( mimetype==MT_NONE || mimetype==MT_WIKI ){
335 wiki_extract_links(zSrc, &bklnk, srctype==BKLNK_COMMENT ? WIKI_INLINE : 0);
336 }else if( mimetype==MT_MARKDOWN ){
337 markdown_extract_links(zSrc, &bklnk);
338 }
339 }
340
341 /*
@@ -340,10 +353,11 @@
353 ** --mimetype TYPE Use an alternative mimetype.
354 */
355 void test_backlinks_cmd(void){
356 const char *zMTime = find_option("mtime",0,1);
357 const char *zMimetype = find_option("mimetype",0,1);
358 const int mimetype = parse_mimetype(zMimetype);
359 Blob in;
360 int srcid;
361 int srctype;
362 double mtime;
363
@@ -371,11 +385,11 @@
385 " ' srcid='||quote(new.srcid)||"
386 " ' mtime='||datetime(new.mtime));\n"
387 " SELECT raise(ignore);\n"
388 "END;"
389 );
390 backlink_extract(blob_str(&in),mimetype,srcid,srctype,mtime,0);
391 blob_reset(&in);
392 }
393
394
395 /*
396
+9 -2
--- src/bisect.c
+++ src/bisect.c
@@ -81,10 +81,11 @@
8181
"skip\"" },
8282
{ "direct-only", "on", "Follow only primary parent-child links, not "
8383
"merges\n" },
8484
{ "display", "chart", "Command to run after \"next\". \"chart\", "
8585
"\"log\", \"status\", or \"none\"" },
86
+ { "linear", "off", "Do a linear scan rather than a true bisect" },
8687
};
8788
8889
/*
8990
** Return the value of a boolean bisect option.
9091
*/
@@ -375,11 +376,12 @@
375376
** Reset the bisect subsystem.
376377
*/
377378
void bisect_reset(void){
378379
db_multi_exec(
379380
"DELETE FROM vvar WHERE name IN "
380
- " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete')"
381
+ " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete',"
382
+ " 'bisect-linear')"
381383
);
382384
}
383385
384386
/*
385387
** fossil bisect run [OPTIONS] COMMAND
@@ -630,11 +632,16 @@
630632
if( strncmp(zCmd, "next", n)==0 ){
631633
PathNode *pMid;
632634
char *zDisplay = db_lget("bisect-display","chart");
633635
int m = (int)strlen(zDisplay);
634636
bisect_path();
635
- pMid = path_midpoint();
637
+ if( db_lget_boolean("bisect-linear",0) ){
638
+ pMid = path_next();
639
+ if( pMid && pMid->rid==db_lget_int("checkout",0) ) pMid = 0;
640
+ }else{
641
+ pMid = path_midpoint();
642
+ }
636643
if( pMid==0 ){
637644
fossil_print("bisect complete\n");
638645
db_lset_int("bisect-complete",1);
639646
}else{
640647
int nSpan = path_length_not_hidden();
641648
--- src/bisect.c
+++ src/bisect.c
@@ -81,10 +81,11 @@
81 "skip\"" },
82 { "direct-only", "on", "Follow only primary parent-child links, not "
83 "merges\n" },
84 { "display", "chart", "Command to run after \"next\". \"chart\", "
85 "\"log\", \"status\", or \"none\"" },
 
86 };
87
88 /*
89 ** Return the value of a boolean bisect option.
90 */
@@ -375,11 +376,12 @@
375 ** Reset the bisect subsystem.
376 */
377 void bisect_reset(void){
378 db_multi_exec(
379 "DELETE FROM vvar WHERE name IN "
380 " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete')"
 
381 );
382 }
383
384 /*
385 ** fossil bisect run [OPTIONS] COMMAND
@@ -630,11 +632,16 @@
630 if( strncmp(zCmd, "next", n)==0 ){
631 PathNode *pMid;
632 char *zDisplay = db_lget("bisect-display","chart");
633 int m = (int)strlen(zDisplay);
634 bisect_path();
635 pMid = path_midpoint();
 
 
 
 
 
636 if( pMid==0 ){
637 fossil_print("bisect complete\n");
638 db_lset_int("bisect-complete",1);
639 }else{
640 int nSpan = path_length_not_hidden();
641
--- src/bisect.c
+++ src/bisect.c
@@ -81,10 +81,11 @@
81 "skip\"" },
82 { "direct-only", "on", "Follow only primary parent-child links, not "
83 "merges\n" },
84 { "display", "chart", "Command to run after \"next\". \"chart\", "
85 "\"log\", \"status\", or \"none\"" },
86 { "linear", "off", "Do a linear scan rather than a true bisect" },
87 };
88
89 /*
90 ** Return the value of a boolean bisect option.
91 */
@@ -375,11 +376,12 @@
376 ** Reset the bisect subsystem.
377 */
378 void bisect_reset(void){
379 db_multi_exec(
380 "DELETE FROM vvar WHERE name IN "
381 " ('bisect-good', 'bisect-bad', 'bisect-log', 'bisect-complete',"
382 " 'bisect-linear')"
383 );
384 }
385
386 /*
387 ** fossil bisect run [OPTIONS] COMMAND
@@ -630,11 +632,16 @@
632 if( strncmp(zCmd, "next", n)==0 ){
633 PathNode *pMid;
634 char *zDisplay = db_lget("bisect-display","chart");
635 int m = (int)strlen(zDisplay);
636 bisect_path();
637 if( db_lget_boolean("bisect-linear",0) ){
638 pMid = path_next();
639 if( pMid && pMid->rid==db_lget_int("checkout",0) ) pMid = 0;
640 }else{
641 pMid = path_midpoint();
642 }
643 if( pMid==0 ){
644 fossil_print("bisect complete\n");
645 db_lset_int("bisect-complete",1);
646 }else{
647 int nSpan = path_length_not_hidden();
648
+26 -5
--- src/builtin.c
+++ src/builtin.c
@@ -130,20 +130,19 @@
130130
blob_reset(&x);
131131
}
132132
133133
/*
134134
** Input zList is a list of numeric identifiers for files in
135
-** aBuiltinFiles[]. Return the concatenation of all of those
136
-** files using mimetype zType, or as application/javascript if
137
-** zType is 0.
135
+** aBuiltinFiles[]. Return the concatenation of all of those files
136
+** using mimetype zType, or as text/javascript if zType is 0.
138137
*/
139138
static void builtin_deliver_multiple_js_files(
140139
const char *zList, /* List of numeric identifiers */
141140
const char *zType /* Override mimetype */
142141
){
143142
Blob *pOut;
144
- if( zType==0 ) zType = "application/javascript";
143
+ if( zType==0 ) zType = "text/javascript";
145144
cgi_set_content_type(zType);
146145
pOut = cgi_output_blob();
147146
while( zList[0] ){
148147
int i = atoi(zList);
149148
if( i>0 && i<=count(aBuiltinFiles) ){
@@ -203,11 +202,11 @@
203202
@ File "%h(zName)" not found
204203
return;
205204
}
206205
if( zType==0 ){
207206
if( sqlite3_strglob("*.js", zName)==0 ){
208
- zType = "application/javascript";
207
+ zType = "text/javascript";
209208
}else{
210209
zType = mimetype_from_name(zName);
211210
}
212211
}
213212
cgi_set_content_type(zType);
@@ -231,10 +230,12 @@
231230
int eDelivery; /* Delivery mechanism */
232231
} builtin;
233232
234233
#if INTERFACE
235234
/* Various delivery mechanisms. The 0 option is the default.
235
+** MAINTENANCE NOTE: Review/update the builtin_set_js_delivery_mode() and
236
+** builtin_get_js_delivery_mode_name() functions if values are changed/added.
236237
*/
237238
#define JS_INLINE 0 /* inline, batched together at end of file */
238239
#define JS_SEPARATE 1 /* Separate HTTP request for each JS file */
239240
#define JS_BUNDLED 2 /* One HTTP request to load all JS files */
240241
/* concatenated together into a bundle */
@@ -268,10 +269,30 @@
268269
** JS_SEPARATE, JS_BUNDLED.
269270
*/
270271
int builtin_get_js_delivery_mode(void){
271272
return builtin.eDelivery;
272273
}
274
+
275
+/*
276
+** Returns the name of the current JS delivery mode for reuse with the --jsmode
277
+** option, i.e. the other way around than builtin_set_js_delivery_mode().
278
+*/
279
+const char *builtin_get_js_delivery_mode_name(void){
280
+ switch( builtin.eDelivery ){
281
+ case JS_SEPARATE: {
282
+ return "separate";
283
+ }
284
+ case JS_BUNDLED: {
285
+ return "bundled";
286
+ }
287
+ case JS_INLINE:
288
+ /*FALLTHROUGH*/
289
+ default: {
290
+ return "inline";
291
+ }
292
+ }
293
+}
273294
274295
/*
275296
** The caller wants the Javascript file named by zFilename to be
276297
** included in the generated page. Add the file to the queue of
277298
** requested javascript resources, if it is not there already.
278299
--- src/builtin.c
+++ src/builtin.c
@@ -130,20 +130,19 @@
130 blob_reset(&x);
131 }
132
133 /*
134 ** Input zList is a list of numeric identifiers for files in
135 ** aBuiltinFiles[]. Return the concatenation of all of those
136 ** files using mimetype zType, or as application/javascript if
137 ** zType is 0.
138 */
139 static void builtin_deliver_multiple_js_files(
140 const char *zList, /* List of numeric identifiers */
141 const char *zType /* Override mimetype */
142 ){
143 Blob *pOut;
144 if( zType==0 ) zType = "application/javascript";
145 cgi_set_content_type(zType);
146 pOut = cgi_output_blob();
147 while( zList[0] ){
148 int i = atoi(zList);
149 if( i>0 && i<=count(aBuiltinFiles) ){
@@ -203,11 +202,11 @@
203 @ File "%h(zName)" not found
204 return;
205 }
206 if( zType==0 ){
207 if( sqlite3_strglob("*.js", zName)==0 ){
208 zType = "application/javascript";
209 }else{
210 zType = mimetype_from_name(zName);
211 }
212 }
213 cgi_set_content_type(zType);
@@ -231,10 +230,12 @@
231 int eDelivery; /* Delivery mechanism */
232 } builtin;
233
234 #if INTERFACE
235 /* Various delivery mechanisms. The 0 option is the default.
 
 
236 */
237 #define JS_INLINE 0 /* inline, batched together at end of file */
238 #define JS_SEPARATE 1 /* Separate HTTP request for each JS file */
239 #define JS_BUNDLED 2 /* One HTTP request to load all JS files */
240 /* concatenated together into a bundle */
@@ -268,10 +269,30 @@
268 ** JS_SEPARATE, JS_BUNDLED.
269 */
270 int builtin_get_js_delivery_mode(void){
271 return builtin.eDelivery;
272 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
274 /*
275 ** The caller wants the Javascript file named by zFilename to be
276 ** included in the generated page. Add the file to the queue of
277 ** requested javascript resources, if it is not there already.
278
--- src/builtin.c
+++ src/builtin.c
@@ -130,20 +130,19 @@
130 blob_reset(&x);
131 }
132
133 /*
134 ** Input zList is a list of numeric identifiers for files in
135 ** aBuiltinFiles[]. Return the concatenation of all of those files
136 ** using mimetype zType, or as text/javascript if zType is 0.
 
137 */
138 static void builtin_deliver_multiple_js_files(
139 const char *zList, /* List of numeric identifiers */
140 const char *zType /* Override mimetype */
141 ){
142 Blob *pOut;
143 if( zType==0 ) zType = "text/javascript";
144 cgi_set_content_type(zType);
145 pOut = cgi_output_blob();
146 while( zList[0] ){
147 int i = atoi(zList);
148 if( i>0 && i<=count(aBuiltinFiles) ){
@@ -203,11 +202,11 @@
202 @ File "%h(zName)" not found
203 return;
204 }
205 if( zType==0 ){
206 if( sqlite3_strglob("*.js", zName)==0 ){
207 zType = "text/javascript";
208 }else{
209 zType = mimetype_from_name(zName);
210 }
211 }
212 cgi_set_content_type(zType);
@@ -231,10 +230,12 @@
230 int eDelivery; /* Delivery mechanism */
231 } builtin;
232
233 #if INTERFACE
234 /* Various delivery mechanisms. The 0 option is the default.
235 ** MAINTENANCE NOTE: Review/update the builtin_set_js_delivery_mode() and
236 ** builtin_get_js_delivery_mode_name() functions if values are changed/added.
237 */
238 #define JS_INLINE 0 /* inline, batched together at end of file */
239 #define JS_SEPARATE 1 /* Separate HTTP request for each JS file */
240 #define JS_BUNDLED 2 /* One HTTP request to load all JS files */
241 /* concatenated together into a bundle */
@@ -268,10 +269,30 @@
269 ** JS_SEPARATE, JS_BUNDLED.
270 */
271 int builtin_get_js_delivery_mode(void){
272 return builtin.eDelivery;
273 }
274
275 /*
276 ** Returns the name of the current JS delivery mode for reuse with the --jsmode
277 ** option, i.e. the other way around than builtin_set_js_delivery_mode().
278 */
279 const char *builtin_get_js_delivery_mode_name(void){
280 switch( builtin.eDelivery ){
281 case JS_SEPARATE: {
282 return "separate";
283 }
284 case JS_BUNDLED: {
285 return "bundled";
286 }
287 case JS_INLINE:
288 /*FALLTHROUGH*/
289 default: {
290 return "inline";
291 }
292 }
293 }
294
295 /*
296 ** The caller wants the Javascript file named by zFilename to be
297 ** included in the generated page. Add the file to the queue of
298 ** requested javascript resources, if it is not there already.
299
+58 -12
--- src/cgi.c
+++ src/cgi.c
@@ -307,11 +307,11 @@
307307
if(!g.isHTTP) return /* e.g. JSON CLI mode, where g.zTop is not set */;
308308
else if( zPath==0 ){
309309
zPath = g.zTop;
310310
if( zPath[0]==0 ) zPath = "/";
311311
}
312
- if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){
312
+ if( g.zBaseURL!=0 && fossil_strncmp(g.zBaseURL, "https:", 6)==0 ){
313313
zSecure = " secure;";
314314
}
315315
if( lifetime!=0 ){
316316
blob_appendf(&extraHeader,
317317
"Set-Cookie: %s=%t; Path=%s; max-age=%d; HttpOnly; "
@@ -330,13 +330,37 @@
330330
** Return true if the response should be sent with Content-Encoding: gzip.
331331
*/
332332
static int is_gzippable(void){
333333
if( g.fNoHttpCompress ) return 0;
334334
if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
335
- return strncmp(zContentType, "text/", 5)==0
336
- || sqlite3_strglob("application/*xml", zContentType)==0
337
- || sqlite3_strglob("application/*javascript", zContentType)==0;
335
+ /* Maintenance note: this oddball structure is intended to make
336
+ ** adding new mimetypes to this list less of a performance hit than
337
+ ** doing a strcmp/glob over a growing set of compressible types. */
338
+ switch(zContentType ? *zContentType : 0){
339
+ case (int)'a':
340
+ if(0==fossil_strncmp("application/",zContentType,12)){
341
+ const char * z = &zContentType[12];
342
+ switch(*z){
343
+ case (int)'j':
344
+ return fossil_strcmp("javascript", z)==0
345
+ || fossil_strcmp("json", z)==0;
346
+ case (int)'w': return fossil_strcmp("wasm", z)==0;
347
+ case (int)'x':
348
+ return fossil_strcmp("x-tcl", z)==0
349
+ || fossil_strcmp("x-tar", z)==0;
350
+ default:
351
+ return sqlite3_strglob("*xml", z)==0;
352
+ }
353
+ }
354
+ break;
355
+ case (int)'i':
356
+ return fossil_strcmp(zContentType, "image/svg+xml")==0
357
+ || fossil_strcmp(zContentType, "image/vnd.microsoft.icon")==0;
358
+ case (int)'t':
359
+ return fossil_strncmp(zContentType, "text/", 5)==0;
360
+ }
361
+ return 0;
338362
}
339363
340364
341365
/*
342366
** The following routines read or write content from/to the wire for
@@ -419,10 +443,29 @@
419443
if( !g.httpUseSSL ){
420444
fflush(g.httpOut);
421445
}
422446
}
423447
448
+/*
449
+** Given a Content-Type value, returns a string suitable for appending
450
+** to the Content-Type header for adding (or not) the "; charset=..."
451
+** part. It returns an empty string for most types or if zContentType
452
+** is NULL.
453
+**
454
+** See forum post f60dece061c364d1 for the discussions which lead to
455
+** this. Previously we always appended the charset, but WASM loaders
456
+** are pedantic and refuse to load any responses which have a
457
+** charset. Also, adding a charset is not strictly appropriate for
458
+** most types (and not required for many others which may ostensibly
459
+** benefit from one, as detailed in that forum post).
460
+*/
461
+static const char * content_type_charset(const char *zContentType){
462
+ if(0==fossil_strncmp(zContentType,"text/",5)){
463
+ return "; charset=utf-8";
464
+ }
465
+ return "";
466
+}
424467
425468
/*
426469
** Generate the reply to a web request. The output might be an
427470
** full HTTP response, or a CGI response, depending on how things have
428471
** be set up.
@@ -493,11 +536,12 @@
493536
494537
/* Content intended for logged in users should only be cached in
495538
** the browser, not some shared location.
496539
*/
497540
if( iReplyStatus!=304 ) {
498
- blob_appendf(&hdr, "Content-Type: %s; charset=utf-8\r\n", zContentType);
541
+ blob_appendf(&hdr, "Content-Type: %s%s\r\n", zContentType,
542
+ content_type_charset(zContentType));
499543
if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
500544
cgi_combine_header_and_body();
501545
blob_compress(&cgiContent[0], &cgiContent[0]);
502546
}
503547
@@ -569,11 +613,12 @@
569613
int iStat,
570614
const char *zStat
571615
){
572616
char *zLocation;
573617
CGIDEBUG(("redirect to %s\n", zURL));
574
- if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 ){
618
+ if( fossil_strncmp(zURL,"http:",5)==0
619
+ || fossil_strncmp(zURL,"https:",6)==0 ){
575620
zLocation = mprintf("Location: %s\r\n", zURL);
576621
}else if( *zURL=='/' ){
577622
int n1 = (int)strlen(g.zBaseURL);
578623
int n2 = (int)strlen(g.zTop);
579624
if( g.zBaseURL[n1-1]=='/' ) zURL++;
@@ -653,11 +698,11 @@
653698
const char *zMethod = P("REQUEST_METHOD");
654699
if( zMethod==0 ) return 0;
655700
if( strcmp(zMethod,"POST")!=0 ) return 0;
656701
}
657702
nBase = (int)strlen(g.zBaseURL);
658
- if( strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
703
+ if( fossil_strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
659704
if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
660705
return 1;
661706
}
662707
663708
/*
@@ -920,11 +965,12 @@
920965
int len = *pLen;
921966
int i;
922967
int nBoundary = strlen(zBoundary);
923968
*pnContent = len;
924969
for(i=0; i<len; i++){
925
- if( z[i]=='\n' && strncmp(zBoundary, &z[i+1], nBoundary)==0 ){
970
+ if( z[i]=='\n' && fossil_strncmp(zBoundary, &z[i+1],
971
+ nBoundary)==0 ){
926972
if( i>0 && z[i-1]=='\r' ) i--;
927973
z[i] = 0;
928974
*pnContent = i;
929975
i += nBoundary;
930976
break;
@@ -1348,11 +1394,11 @@
13481394
*/
13491395
void cgi_decode_post_parameters(void){
13501396
int len = blob_size(&g.cgiIn);
13511397
if( len==0 ) return;
13521398
if( fossil_strcmp(g.zContentType,"application/x-www-form-urlencoded")==0
1353
- || strncmp(g.zContentType,"multipart/form-data",19)==0
1399
+ || fossil_strncmp(g.zContentType,"multipart/form-data",19)==0
13541400
){
13551401
char *z = blob_str(&g.cgiIn);
13561402
cgi_trace(z);
13571403
if( g.zContentType[0]=='a' ){
13581404
add_param_list(z, '&');
@@ -2309,11 +2355,11 @@
23092355
}
23102356
break;
23112357
}
23122358
if( iPort>mxPort ){
23132359
if( mnPort==mxPort ){
2314
- fossil_fatal("unable to open listening socket on ports %d", mnPort);
2360
+ fossil_fatal("unable to open listening socket on port %d", mnPort);
23152361
}else{
23162362
fossil_fatal("unable to open listening socket on any"
23172363
" port in the range %d..%d", mnPort, mxPort);
23182364
}
23192365
}
@@ -2326,11 +2372,11 @@
23262372
if( zBrowser ){
23272373
assert( strstr(zBrowser,"%d")!=0 );
23282374
zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
23292375
#if defined(__CYGWIN__)
23302376
/* On Cygwin, we can do better than "echo" */
2331
- if( strncmp(zBrowser, "echo ", 5)==0 ){
2377
+ if( fossil_strncmp(zBrowser, "echo ", 5)==0 ){
23322378
wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
23332379
wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
23342380
if( (size_t)ShellExecuteW(0, L"open", wUrl, 0, 0, 1)<33 ){
23352381
fossil_warning("cannot start browser\n");
23362382
}
@@ -2486,11 +2532,11 @@
24862532
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0};
24872533
if( 7==sscanf(zDate, "%3[A-Za-z], %d %3[A-Za-z] %d %d:%d:%d", zIgnore,
24882534
&mday, zMonth, &year, &hour, &min, &sec)){
24892535
if( year > 1900 ) year -= 1900;
24902536
for(mon=0; azMonths[mon]; mon++){
2491
- if( !strncmp( azMonths[mon], zMonth, 3 )){
2537
+ if( !fossil_strncmp( azMonths[mon], zMonth, 3 )){
24922538
int nDay;
24932539
int isLeapYr;
24942540
static int priorDays[] =
24952541
{ 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
24962542
if( mon<0 ){
24972543
--- src/cgi.c
+++ src/cgi.c
@@ -307,11 +307,11 @@
307 if(!g.isHTTP) return /* e.g. JSON CLI mode, where g.zTop is not set */;
308 else if( zPath==0 ){
309 zPath = g.zTop;
310 if( zPath[0]==0 ) zPath = "/";
311 }
312 if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){
313 zSecure = " secure;";
314 }
315 if( lifetime!=0 ){
316 blob_appendf(&extraHeader,
317 "Set-Cookie: %s=%t; Path=%s; max-age=%d; HttpOnly; "
@@ -330,13 +330,37 @@
330 ** Return true if the response should be sent with Content-Encoding: gzip.
331 */
332 static int is_gzippable(void){
333 if( g.fNoHttpCompress ) return 0;
334 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
335 return strncmp(zContentType, "text/", 5)==0
336 || sqlite3_strglob("application/*xml", zContentType)==0
337 || sqlite3_strglob("application/*javascript", zContentType)==0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338 }
339
340
341 /*
342 ** The following routines read or write content from/to the wire for
@@ -419,10 +443,29 @@
419 if( !g.httpUseSSL ){
420 fflush(g.httpOut);
421 }
422 }
423
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
425 /*
426 ** Generate the reply to a web request. The output might be an
427 ** full HTTP response, or a CGI response, depending on how things have
428 ** be set up.
@@ -493,11 +536,12 @@
493
494 /* Content intended for logged in users should only be cached in
495 ** the browser, not some shared location.
496 */
497 if( iReplyStatus!=304 ) {
498 blob_appendf(&hdr, "Content-Type: %s; charset=utf-8\r\n", zContentType);
 
499 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
500 cgi_combine_header_and_body();
501 blob_compress(&cgiContent[0], &cgiContent[0]);
502 }
503
@@ -569,11 +613,12 @@
569 int iStat,
570 const char *zStat
571 ){
572 char *zLocation;
573 CGIDEBUG(("redirect to %s\n", zURL));
574 if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 ){
 
575 zLocation = mprintf("Location: %s\r\n", zURL);
576 }else if( *zURL=='/' ){
577 int n1 = (int)strlen(g.zBaseURL);
578 int n2 = (int)strlen(g.zTop);
579 if( g.zBaseURL[n1-1]=='/' ) zURL++;
@@ -653,11 +698,11 @@
653 const char *zMethod = P("REQUEST_METHOD");
654 if( zMethod==0 ) return 0;
655 if( strcmp(zMethod,"POST")!=0 ) return 0;
656 }
657 nBase = (int)strlen(g.zBaseURL);
658 if( strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
659 if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
660 return 1;
661 }
662
663 /*
@@ -920,11 +965,12 @@
920 int len = *pLen;
921 int i;
922 int nBoundary = strlen(zBoundary);
923 *pnContent = len;
924 for(i=0; i<len; i++){
925 if( z[i]=='\n' && strncmp(zBoundary, &z[i+1], nBoundary)==0 ){
 
926 if( i>0 && z[i-1]=='\r' ) i--;
927 z[i] = 0;
928 *pnContent = i;
929 i += nBoundary;
930 break;
@@ -1348,11 +1394,11 @@
1348 */
1349 void cgi_decode_post_parameters(void){
1350 int len = blob_size(&g.cgiIn);
1351 if( len==0 ) return;
1352 if( fossil_strcmp(g.zContentType,"application/x-www-form-urlencoded")==0
1353 || strncmp(g.zContentType,"multipart/form-data",19)==0
1354 ){
1355 char *z = blob_str(&g.cgiIn);
1356 cgi_trace(z);
1357 if( g.zContentType[0]=='a' ){
1358 add_param_list(z, '&');
@@ -2309,11 +2355,11 @@
2309 }
2310 break;
2311 }
2312 if( iPort>mxPort ){
2313 if( mnPort==mxPort ){
2314 fossil_fatal("unable to open listening socket on ports %d", mnPort);
2315 }else{
2316 fossil_fatal("unable to open listening socket on any"
2317 " port in the range %d..%d", mnPort, mxPort);
2318 }
2319 }
@@ -2326,11 +2372,11 @@
2326 if( zBrowser ){
2327 assert( strstr(zBrowser,"%d")!=0 );
2328 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
2329 #if defined(__CYGWIN__)
2330 /* On Cygwin, we can do better than "echo" */
2331 if( strncmp(zBrowser, "echo ", 5)==0 ){
2332 wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
2333 wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
2334 if( (size_t)ShellExecuteW(0, L"open", wUrl, 0, 0, 1)<33 ){
2335 fossil_warning("cannot start browser\n");
2336 }
@@ -2486,11 +2532,11 @@
2486 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0};
2487 if( 7==sscanf(zDate, "%3[A-Za-z], %d %3[A-Za-z] %d %d:%d:%d", zIgnore,
2488 &mday, zMonth, &year, &hour, &min, &sec)){
2489 if( year > 1900 ) year -= 1900;
2490 for(mon=0; azMonths[mon]; mon++){
2491 if( !strncmp( azMonths[mon], zMonth, 3 )){
2492 int nDay;
2493 int isLeapYr;
2494 static int priorDays[] =
2495 { 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
2496 if( mon<0 ){
2497
--- src/cgi.c
+++ src/cgi.c
@@ -307,11 +307,11 @@
307 if(!g.isHTTP) return /* e.g. JSON CLI mode, where g.zTop is not set */;
308 else if( zPath==0 ){
309 zPath = g.zTop;
310 if( zPath[0]==0 ) zPath = "/";
311 }
312 if( g.zBaseURL!=0 && fossil_strncmp(g.zBaseURL, "https:", 6)==0 ){
313 zSecure = " secure;";
314 }
315 if( lifetime!=0 ){
316 blob_appendf(&extraHeader,
317 "Set-Cookie: %s=%t; Path=%s; max-age=%d; HttpOnly; "
@@ -330,13 +330,37 @@
330 ** Return true if the response should be sent with Content-Encoding: gzip.
331 */
332 static int is_gzippable(void){
333 if( g.fNoHttpCompress ) return 0;
334 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
335 /* Maintenance note: this oddball structure is intended to make
336 ** adding new mimetypes to this list less of a performance hit than
337 ** doing a strcmp/glob over a growing set of compressible types. */
338 switch(zContentType ? *zContentType : 0){
339 case (int)'a':
340 if(0==fossil_strncmp("application/",zContentType,12)){
341 const char * z = &zContentType[12];
342 switch(*z){
343 case (int)'j':
344 return fossil_strcmp("javascript", z)==0
345 || fossil_strcmp("json", z)==0;
346 case (int)'w': return fossil_strcmp("wasm", z)==0;
347 case (int)'x':
348 return fossil_strcmp("x-tcl", z)==0
349 || fossil_strcmp("x-tar", z)==0;
350 default:
351 return sqlite3_strglob("*xml", z)==0;
352 }
353 }
354 break;
355 case (int)'i':
356 return fossil_strcmp(zContentType, "image/svg+xml")==0
357 || fossil_strcmp(zContentType, "image/vnd.microsoft.icon")==0;
358 case (int)'t':
359 return fossil_strncmp(zContentType, "text/", 5)==0;
360 }
361 return 0;
362 }
363
364
365 /*
366 ** The following routines read or write content from/to the wire for
@@ -419,10 +443,29 @@
443 if( !g.httpUseSSL ){
444 fflush(g.httpOut);
445 }
446 }
447
448 /*
449 ** Given a Content-Type value, returns a string suitable for appending
450 ** to the Content-Type header for adding (or not) the "; charset=..."
451 ** part. It returns an empty string for most types or if zContentType
452 ** is NULL.
453 **
454 ** See forum post f60dece061c364d1 for the discussions which lead to
455 ** this. Previously we always appended the charset, but WASM loaders
456 ** are pedantic and refuse to load any responses which have a
457 ** charset. Also, adding a charset is not strictly appropriate for
458 ** most types (and not required for many others which may ostensibly
459 ** benefit from one, as detailed in that forum post).
460 */
461 static const char * content_type_charset(const char *zContentType){
462 if(0==fossil_strncmp(zContentType,"text/",5)){
463 return "; charset=utf-8";
464 }
465 return "";
466 }
467
468 /*
469 ** Generate the reply to a web request. The output might be an
470 ** full HTTP response, or a CGI response, depending on how things have
471 ** be set up.
@@ -493,11 +536,12 @@
536
537 /* Content intended for logged in users should only be cached in
538 ** the browser, not some shared location.
539 */
540 if( iReplyStatus!=304 ) {
541 blob_appendf(&hdr, "Content-Type: %s%s\r\n", zContentType,
542 content_type_charset(zContentType));
543 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
544 cgi_combine_header_and_body();
545 blob_compress(&cgiContent[0], &cgiContent[0]);
546 }
547
@@ -569,11 +613,12 @@
613 int iStat,
614 const char *zStat
615 ){
616 char *zLocation;
617 CGIDEBUG(("redirect to %s\n", zURL));
618 if( fossil_strncmp(zURL,"http:",5)==0
619 || fossil_strncmp(zURL,"https:",6)==0 ){
620 zLocation = mprintf("Location: %s\r\n", zURL);
621 }else if( *zURL=='/' ){
622 int n1 = (int)strlen(g.zBaseURL);
623 int n2 = (int)strlen(g.zTop);
624 if( g.zBaseURL[n1-1]=='/' ) zURL++;
@@ -653,11 +698,11 @@
698 const char *zMethod = P("REQUEST_METHOD");
699 if( zMethod==0 ) return 0;
700 if( strcmp(zMethod,"POST")!=0 ) return 0;
701 }
702 nBase = (int)strlen(g.zBaseURL);
703 if( fossil_strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
704 if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
705 return 1;
706 }
707
708 /*
@@ -920,11 +965,12 @@
965 int len = *pLen;
966 int i;
967 int nBoundary = strlen(zBoundary);
968 *pnContent = len;
969 for(i=0; i<len; i++){
970 if( z[i]=='\n' && fossil_strncmp(zBoundary, &z[i+1],
971 nBoundary)==0 ){
972 if( i>0 && z[i-1]=='\r' ) i--;
973 z[i] = 0;
974 *pnContent = i;
975 i += nBoundary;
976 break;
@@ -1348,11 +1394,11 @@
1394 */
1395 void cgi_decode_post_parameters(void){
1396 int len = blob_size(&g.cgiIn);
1397 if( len==0 ) return;
1398 if( fossil_strcmp(g.zContentType,"application/x-www-form-urlencoded")==0
1399 || fossil_strncmp(g.zContentType,"multipart/form-data",19)==0
1400 ){
1401 char *z = blob_str(&g.cgiIn);
1402 cgi_trace(z);
1403 if( g.zContentType[0]=='a' ){
1404 add_param_list(z, '&');
@@ -2309,11 +2355,11 @@
2355 }
2356 break;
2357 }
2358 if( iPort>mxPort ){
2359 if( mnPort==mxPort ){
2360 fossil_fatal("unable to open listening socket on port %d", mnPort);
2361 }else{
2362 fossil_fatal("unable to open listening socket on any"
2363 " port in the range %d..%d", mnPort, mxPort);
2364 }
2365 }
@@ -2326,11 +2372,11 @@
2372 if( zBrowser ){
2373 assert( strstr(zBrowser,"%d")!=0 );
2374 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
2375 #if defined(__CYGWIN__)
2376 /* On Cygwin, we can do better than "echo" */
2377 if( fossil_strncmp(zBrowser, "echo ", 5)==0 ){
2378 wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
2379 wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
2380 if( (size_t)ShellExecuteW(0, L"open", wUrl, 0, 0, 1)<33 ){
2381 fossil_warning("cannot start browser\n");
2382 }
@@ -2486,11 +2532,11 @@
2532 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0};
2533 if( 7==sscanf(zDate, "%3[A-Za-z], %d %3[A-Za-z] %d %d:%d:%d", zIgnore,
2534 &mday, zMonth, &year, &hour, &min, &sec)){
2535 if( year > 1900 ) year -= 1900;
2536 for(mon=0; azMonths[mon]; mon++){
2537 if( !fossil_strncmp( azMonths[mon], zMonth, 3 )){
2538 int nDay;
2539 int isLeapYr;
2540 static int priorDays[] =
2541 { 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
2542 if( mon<0 ){
2543
+10
--- src/db.c
+++ src/db.c
@@ -3436,10 +3436,20 @@
34363436
void db_lset(const char *zName, const char *zValue){
34373437
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
34383438
}
34393439
int db_lget_int(const char *zName, int dflt){
34403440
return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
3441
+}
3442
+int db_lget_boolean(const char *zName, int dflt){
3443
+ char *zVal = db_lget(zName, dflt ? "on" : "off");
3444
+ if( is_truth(zVal) ){
3445
+ dflt = 1;
3446
+ }else if( is_false(zVal) ){
3447
+ dflt = 0;
3448
+ }
3449
+ fossil_free(zVal);
3450
+ return dflt;
34413451
}
34423452
void db_lset_int(const char *zName, int value){
34433453
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
34443454
}
34453455
34463456
--- src/db.c
+++ src/db.c
@@ -3436,10 +3436,20 @@
3436 void db_lset(const char *zName, const char *zValue){
3437 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
3438 }
3439 int db_lget_int(const char *zName, int dflt){
3440 return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
 
 
 
 
 
 
 
 
 
 
3441 }
3442 void db_lset_int(const char *zName, int value){
3443 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
3444 }
3445
3446
--- src/db.c
+++ src/db.c
@@ -3436,10 +3436,20 @@
3436 void db_lset(const char *zName, const char *zValue){
3437 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
3438 }
3439 int db_lget_int(const char *zName, int dflt){
3440 return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
3441 }
3442 int db_lget_boolean(const char *zName, int dflt){
3443 char *zVal = db_lget(zName, dflt ? "on" : "off");
3444 if( is_truth(zVal) ){
3445 dflt = 1;
3446 }else if( is_false(zVal) ){
3447 dflt = 0;
3448 }
3449 fossil_free(zVal);
3450 return dflt;
3451 }
3452 void db_lset_int(const char *zName, int value){
3453 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
3454 }
3455
3456
+14 -6
--- src/default.css
+++ src/default.css
@@ -1007,10 +1007,13 @@
10071007
background-color: #ffb;
10081008
}
10091009
label {
10101010
white-space: nowrap;
10111011
}
1012
+label[for] {
1013
+ cursor: pointer;
1014
+}
10121015
.copy-button {
10131016
display: inline-block;
10141017
width: 14px;
10151018
height: 14px;
10161019
/*Note: .24em is slightly smaller than the average width of a normal space.*/
@@ -1075,16 +1078,21 @@
10751078
}
10761079
.warning {
10771080
color: black;
10781081
background: yellow;
10791082
}
1080
-.hidden {
1081
- /* The framework-wide way of hiding elements is to assign them this
1082
- CSS class. To make them visible again, remove it. The !important
1083
- qualifiers are unfortunate but sometimes necessary when hidden
1084
- element has other classes which specify visibility-related
1085
- options. */
1083
+.hidden, .initially-hidden {
1084
+ /* The framework-wide way of hiding elements is to assign them th
1085
+ .hidden class. To make them visible again, remove it. The
1086
+ !important qualifiers are unfortunate but sometimes necessary
1087
+ when hidden element has other classes which specify
1088
+ visibility-related options. The .initially-hidden class is for
1089
+ pages which need to show, e.g., a progress widget while a large
1090
+ WASM blob loads. Elements aside from that load-time widget can be
1091
+ made .initially-hidden and then have that class removed once the
1092
+ long-running startup process is done. See /pikchrshow for an
1093
+ example. */
10861094
position: absolute !important;
10871095
opacity: 0 !important;
10881096
pointer-events: none !important;
10891097
display: none !important;
10901098
}
10911099
--- src/default.css
+++ src/default.css
@@ -1007,10 +1007,13 @@
1007 background-color: #ffb;
1008 }
1009 label {
1010 white-space: nowrap;
1011 }
 
 
 
1012 .copy-button {
1013 display: inline-block;
1014 width: 14px;
1015 height: 14px;
1016 /*Note: .24em is slightly smaller than the average width of a normal space.*/
@@ -1075,16 +1078,21 @@
1075 }
1076 .warning {
1077 color: black;
1078 background: yellow;
1079 }
1080 .hidden {
1081 /* The framework-wide way of hiding elements is to assign them this
1082 CSS class. To make them visible again, remove it. The !important
1083 qualifiers are unfortunate but sometimes necessary when hidden
1084 element has other classes which specify visibility-related
1085 options. */
 
 
 
 
 
1086 position: absolute !important;
1087 opacity: 0 !important;
1088 pointer-events: none !important;
1089 display: none !important;
1090 }
1091
--- src/default.css
+++ src/default.css
@@ -1007,10 +1007,13 @@
1007 background-color: #ffb;
1008 }
1009 label {
1010 white-space: nowrap;
1011 }
1012 label[for] {
1013 cursor: pointer;
1014 }
1015 .copy-button {
1016 display: inline-block;
1017 width: 14px;
1018 height: 14px;
1019 /*Note: .24em is slightly smaller than the average width of a normal space.*/
@@ -1075,16 +1078,21 @@
1078 }
1079 .warning {
1080 color: black;
1081 background: yellow;
1082 }
1083 .hidden, .initially-hidden {
1084 /* The framework-wide way of hiding elements is to assign them th
1085 .hidden class. To make them visible again, remove it. The
1086 !important qualifiers are unfortunate but sometimes necessary
1087 when hidden element has other classes which specify
1088 visibility-related options. The .initially-hidden class is for
1089 pages which need to show, e.g., a progress widget while a large
1090 WASM blob loads. Elements aside from that load-time widget can be
1091 made .initially-hidden and then have that class removed once the
1092 long-running startup process is done. See /pikchrshow for an
1093 example. */
1094 position: absolute !important;
1095 opacity: 0 !important;
1096 pointer-events: none !important;
1097 display: none !important;
1098 }
1099
+8 -1
--- src/doc.c
+++ src/doc.c
@@ -156,11 +156,16 @@
156156
{ "jad", 3, "text/vnd.sun.j2me.app-descriptor" },
157157
{ "jar", 3, "application/java-archive" },
158158
{ "jpe", 3, "image/jpeg" },
159159
{ "jpeg", 4, "image/jpeg" },
160160
{ "jpg", 3, "image/jpeg" },
161
- { "js", 2, "application/javascript" },
161
+ { "js", 2, "text/javascript" },
162
+ /* application/javascript is commonly used for JS, but the
163
+ ** spec says text/javascript is correct:
164
+ ** https://html.spec.whatwg.org/multipage/scripting.html
165
+ ** #scriptingLanguages:javascript-mime-type */
166
+ { "json", 4, "application/json" },
162167
{ "kar", 3, "audio/midi" },
163168
{ "latex", 5, "application/x-latex" },
164169
{ "lha", 3, "application/octet-stream" },
165170
{ "lsp", 3, "application/x-lisp" },
166171
{ "lzh", 3, "application/octet-stream" },
@@ -173,10 +178,11 @@
173178
{ "mesh", 4, "model/mesh" },
174179
{ "mid", 3, "audio/midi" },
175180
{ "midi", 4, "audio/midi" },
176181
{ "mif", 3, "application/x-mif" },
177182
{ "mime", 4, "www/mime" },
183
+ { "mjs", 3, "text/javascript" /*EM6 modules*/ },
178184
{ "mkd", 3, "text/x-markdown" },
179185
{ "mov", 3, "video/quicktime" },
180186
{ "movie", 5, "video/x-sgi-movie" },
181187
{ "mp2", 3, "audio/mpeg" },
182188
{ "mp3", 3, "audio/mpeg" },
@@ -277,10 +283,11 @@
277283
{ "vcd", 3, "application/x-cdlink" },
278284
{ "vda", 3, "application/vda" },
279285
{ "viv", 3, "video/vnd.vivo" },
280286
{ "vivo", 4, "video/vnd.vivo" },
281287
{ "vrml", 4, "model/vrml" },
288
+ { "wasm", 4, "application/wasm" },
282289
{ "wav", 3, "audio/x-wav" },
283290
{ "wax", 3, "audio/x-ms-wax" },
284291
{ "webp", 4, "image/webp" },
285292
{ "wiki", 4, "text/x-fossil-wiki" },
286293
{ "wma", 3, "audio/x-ms-wma" },
287294
--- src/doc.c
+++ src/doc.c
@@ -156,11 +156,16 @@
156 { "jad", 3, "text/vnd.sun.j2me.app-descriptor" },
157 { "jar", 3, "application/java-archive" },
158 { "jpe", 3, "image/jpeg" },
159 { "jpeg", 4, "image/jpeg" },
160 { "jpg", 3, "image/jpeg" },
161 { "js", 2, "application/javascript" },
 
 
 
 
 
162 { "kar", 3, "audio/midi" },
163 { "latex", 5, "application/x-latex" },
164 { "lha", 3, "application/octet-stream" },
165 { "lsp", 3, "application/x-lisp" },
166 { "lzh", 3, "application/octet-stream" },
@@ -173,10 +178,11 @@
173 { "mesh", 4, "model/mesh" },
174 { "mid", 3, "audio/midi" },
175 { "midi", 4, "audio/midi" },
176 { "mif", 3, "application/x-mif" },
177 { "mime", 4, "www/mime" },
 
178 { "mkd", 3, "text/x-markdown" },
179 { "mov", 3, "video/quicktime" },
180 { "movie", 5, "video/x-sgi-movie" },
181 { "mp2", 3, "audio/mpeg" },
182 { "mp3", 3, "audio/mpeg" },
@@ -277,10 +283,11 @@
277 { "vcd", 3, "application/x-cdlink" },
278 { "vda", 3, "application/vda" },
279 { "viv", 3, "video/vnd.vivo" },
280 { "vivo", 4, "video/vnd.vivo" },
281 { "vrml", 4, "model/vrml" },
 
282 { "wav", 3, "audio/x-wav" },
283 { "wax", 3, "audio/x-ms-wax" },
284 { "webp", 4, "image/webp" },
285 { "wiki", 4, "text/x-fossil-wiki" },
286 { "wma", 3, "audio/x-ms-wma" },
287
--- src/doc.c
+++ src/doc.c
@@ -156,11 +156,16 @@
156 { "jad", 3, "text/vnd.sun.j2me.app-descriptor" },
157 { "jar", 3, "application/java-archive" },
158 { "jpe", 3, "image/jpeg" },
159 { "jpeg", 4, "image/jpeg" },
160 { "jpg", 3, "image/jpeg" },
161 { "js", 2, "text/javascript" },
162 /* application/javascript is commonly used for JS, but the
163 ** spec says text/javascript is correct:
164 ** https://html.spec.whatwg.org/multipage/scripting.html
165 ** #scriptingLanguages:javascript-mime-type */
166 { "json", 4, "application/json" },
167 { "kar", 3, "audio/midi" },
168 { "latex", 5, "application/x-latex" },
169 { "lha", 3, "application/octet-stream" },
170 { "lsp", 3, "application/x-lisp" },
171 { "lzh", 3, "application/octet-stream" },
@@ -173,10 +178,11 @@
178 { "mesh", 4, "model/mesh" },
179 { "mid", 3, "audio/midi" },
180 { "midi", 4, "audio/midi" },
181 { "mif", 3, "application/x-mif" },
182 { "mime", 4, "www/mime" },
183 { "mjs", 3, "text/javascript" /*EM6 modules*/ },
184 { "mkd", 3, "text/x-markdown" },
185 { "mov", 3, "video/quicktime" },
186 { "movie", 5, "video/x-sgi-movie" },
187 { "mp2", 3, "audio/mpeg" },
188 { "mp3", 3, "audio/mpeg" },
@@ -277,10 +283,11 @@
283 { "vcd", 3, "application/x-cdlink" },
284 { "vda", 3, "application/vda" },
285 { "viv", 3, "video/vnd.vivo" },
286 { "vivo", 4, "video/vnd.vivo" },
287 { "vrml", 4, "model/vrml" },
288 { "wasm", 4, "application/wasm" },
289 { "wav", 3, "audio/x-wav" },
290 { "wax", 3, "audio/x-ms-wax" },
291 { "webp", 4, "image/webp" },
292 { "wiki", 4, "text/x-fossil-wiki" },
293 { "wma", 3, "audio/x-ms-wma" },
294
--- src/fossil.copybutton.js
+++ src/fossil.copybutton.js
@@ -17,13 +17,10 @@
1717
1818
.copyFromElement: DOM element
1919
2020
.copyFromId: DOM element ID
2121
22
- One of copyFromElement or copyFromId must be provided, but copyFromId
23
- may optionally be provided via e.dataset.copyFromId.
24
-
2522
.extractText: optional callback which is triggered when the copy
2623
button is clicked. It must return the text to copy to the
2724
clipboard. The default is to extract it from the copy-from
2825
element, using its [value] member, if it has one, else its
2926
[innerText]. A client-provided callback may use any data source
@@ -30,10 +27,15 @@
3027
it likes, so long as it's synchronous. If this function returns a
3128
falsy value then the clipboard is not modified. This function is
3229
called with the fully expanded/resolved options object as its
3330
"this" (that's a different instance than the one passed to this
3431
function!).
32
+
33
+ At least one of copyFromElement, copyFromId, or extractText must
34
+ be provided, but if copyFromId is not set and e.dataset.copyFromId
35
+ is then that value is used in its place. extractText() trumps the
36
+ other two options.
3537
3638
.cssClass: optional CSS class, or list of classes, to apply to e.
3739
3840
.style: optional object of properties to copy directly into
3941
e.style.
4042
--- src/fossil.copybutton.js
+++ src/fossil.copybutton.js
@@ -17,13 +17,10 @@
17
18 .copyFromElement: DOM element
19
20 .copyFromId: DOM element ID
21
22 One of copyFromElement or copyFromId must be provided, but copyFromId
23 may optionally be provided via e.dataset.copyFromId.
24
25 .extractText: optional callback which is triggered when the copy
26 button is clicked. It must return the text to copy to the
27 clipboard. The default is to extract it from the copy-from
28 element, using its [value] member, if it has one, else its
29 [innerText]. A client-provided callback may use any data source
@@ -30,10 +27,15 @@
30 it likes, so long as it's synchronous. If this function returns a
31 falsy value then the clipboard is not modified. This function is
32 called with the fully expanded/resolved options object as its
33 "this" (that's a different instance than the one passed to this
34 function!).
 
 
 
 
 
35
36 .cssClass: optional CSS class, or list of classes, to apply to e.
37
38 .style: optional object of properties to copy directly into
39 e.style.
40
--- src/fossil.copybutton.js
+++ src/fossil.copybutton.js
@@ -17,13 +17,10 @@
17
18 .copyFromElement: DOM element
19
20 .copyFromId: DOM element ID
21
 
 
 
22 .extractText: optional callback which is triggered when the copy
23 button is clicked. It must return the text to copy to the
24 clipboard. The default is to extract it from the copy-from
25 element, using its [value] member, if it has one, else its
26 [innerText]. A client-provided callback may use any data source
@@ -30,10 +27,15 @@
27 it likes, so long as it's synchronous. If this function returns a
28 falsy value then the clipboard is not modified. This function is
29 called with the fully expanded/resolved options object as its
30 "this" (that's a different instance than the one passed to this
31 function!).
32
33 At least one of copyFromElement, copyFromId, or extractText must
34 be provided, but if copyFromId is not set and e.dataset.copyFromId
35 is then that value is used in its place. extractText() trumps the
36 other two options.
37
38 .cssClass: optional CSS class, or list of classes, to apply to e.
39
40 .style: optional object of properties to copy directly into
41 e.style.
42
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -702,10 +702,15 @@
702702
}
703703
if(!e || !id) return false;
704704
else if(e.$isToggling) return;
705705
e.$isToggling = true;
706706
const content = e.querySelector('.content-target');
707
+ if(!content){
708
+ console.warn("Should not be possible: trying to toggle text",
709
+ "mode of a message with no .content-target.", e);
710
+ return;
711
+ }
707712
if(!content.$elems){
708713
content.$elems = [
709714
content.firstElementChild, // parsed elem
710715
undefined // plaintext elem
711716
];
@@ -714,21 +719,39 @@
714719
const child = (
715720
content.firstElementChild===content.$elems[0]
716721
? content.$elems[1]
717722
: content.$elems[0]
718723
);
724
+ D.clearElement(content);
725
+ if(child===content.$elems[1]){
726
+ /* When showing the unformatted version, inject a
727
+ copy-to-clipboard button. This is a workaround for
728
+ mouse-copying from that field collecting twice as many
729
+ newlines as it should (for unknown reasons). */
730
+ const cpId = 'copy-to-clipboard-'+id;
731
+ /* ^^^ copy button element ID, needed for LABEL element
732
+ pairing. Recall that we destroy all child elements of
733
+ `content` each time we hit this block, so we can reuse
734
+ that element ID on subsequent toggles. */
735
+ const btnCp = D.attr(D.addClass(D.span(),'copy-button'), 'id', cpId);
736
+ F.copyButton(btnCp, {extractText: ()=>child._xmsgRaw});
737
+ const lblCp = D.label(cpId, "Copy unformatted text");
738
+ lblCp.addEventListener('click',()=>btnCp.click(), false);
739
+ D.append(content, D.append(D.addClass(D.span(), 'nobr'), btnCp, lblCp));
740
+ }
719741
delete e.$isToggling;
720
- D.append(D.clearElement(content), child);
742
+ D.append(content, child);
721743
return;
722744
}
723745
// We need to fetch the plain-text version...
724746
const self = this;
725747
F.fetch('chat-fetch-one',{
726748
urlParams:{ name: id, raw: true},
727749
responseType: 'json',
728750
onload: function(msg){
729751
content.$elems[1] = D.append(D.pre(),msg.xmsg);
752
+ content.$elems[1]._xmsgRaw = msg.xmsg/*used for copy-to-clipboard feature*/;
730753
self.toggleTextMode(e);
731754
},
732755
aftersend:function(){
733756
delete e.$isToggling;
734757
Chat.ajaxEnd();
@@ -1135,15 +1158,19 @@
11351158
eMsg.scrollIntoView();
11361159
}
11371160
));
11381161
const toolbar2 = D.addClass(D.div(), 'toolbar');
11391162
D.append(this.e, toolbar2);
1140
- D.append(toolbar2, D.button(
1141
- "Toggle text mode", function(){
1142
- self.hide();
1143
- Chat.toggleTextMode(eMsg);
1144
- }));
1163
+ if(eMsg.querySelector('.content-target')){
1164
+ /* ^^^ messages with only an embedded image have no
1165
+ .content-target area. */
1166
+ D.append(toolbar2, D.button(
1167
+ "Toggle text mode", function(){
1168
+ self.hide();
1169
+ Chat.toggleTextMode(eMsg);
1170
+ }));
1171
+ }
11451172
if(eMsg.dataset.xfrom){
11461173
/* Add a link to the /timeline filtered on this user. */
11471174
const timelineLink = D.attr(
11481175
D.a(F.repoUrl('timeline',{
11491176
u: eMsg.dataset.xfrom,
@@ -1350,29 +1377,35 @@
13501377
*/
13511378
Chat.submitMessage = function f(){
13521379
if(!f.spaces){
13531380
f.spaces = /\s+$/;
13541381
f.markdownContinuation = /\\\s+$/;
1382
+ f.spaces2 = /\s{3,}$/;
13551383
}
13561384
this.setCurrentView(this.e.viewMessages);
13571385
const fd = new FormData();
13581386
const fallback = {msg: this.inputValue()};
1359
- var msg = fallback.msg.trim();
1387
+ var msg = fallback.msg;
13601388
if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
1361
- /* Cosmetic: trim whitespace from the ends of lines to try to
1389
+ /* Cosmetic: trim most whitespace from the ends of lines to try to
13621390
keep copy/paste from terminals, especially wide ones, from
13631391
forcing a horizontal scrollbar on all clients. This breaks
13641392
markdown's use of blackslash-space-space for paragraph
13651393
continuation, but *not* doing this affects all clients every
13661394
time someone pastes in console copy/paste from an affected
13671395
platform. We seem to have narrowed to the console pasting
1368
- problem to users of tmux. Most consoles don't behave
1369
- that way. */
1396
+ problem to users of tmux together with certain apps (vim, at
1397
+ a minimum). Most consoles don't behave that way.
1398
+
1399
+ We retain two trailing spaces so that markdown conventions
1400
+ which use end-of-line spacing aren't broken by this
1401
+ stripping.
1402
+ */
13701403
const xmsg = msg.split('\n');
13711404
xmsg.forEach(function(line,ndx){
13721405
if(!f.markdownContinuation.test(line)){
1373
- xmsg[ndx] = line.trimRight();
1406
+ xmsg[ndx] = line.replace(f.spaces2, ' ');
13741407
}
13751408
});
13761409
msg = xmsg.join('\n');
13771410
}
13781411
if(msg) fd.set('msg',msg);
13791412
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -702,10 +702,15 @@
702 }
703 if(!e || !id) return false;
704 else if(e.$isToggling) return;
705 e.$isToggling = true;
706 const content = e.querySelector('.content-target');
 
 
 
 
 
707 if(!content.$elems){
708 content.$elems = [
709 content.firstElementChild, // parsed elem
710 undefined // plaintext elem
711 ];
@@ -714,21 +719,39 @@
714 const child = (
715 content.firstElementChild===content.$elems[0]
716 ? content.$elems[1]
717 : content.$elems[0]
718 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
719 delete e.$isToggling;
720 D.append(D.clearElement(content), child);
721 return;
722 }
723 // We need to fetch the plain-text version...
724 const self = this;
725 F.fetch('chat-fetch-one',{
726 urlParams:{ name: id, raw: true},
727 responseType: 'json',
728 onload: function(msg){
729 content.$elems[1] = D.append(D.pre(),msg.xmsg);
 
730 self.toggleTextMode(e);
731 },
732 aftersend:function(){
733 delete e.$isToggling;
734 Chat.ajaxEnd();
@@ -1135,15 +1158,19 @@
1135 eMsg.scrollIntoView();
1136 }
1137 ));
1138 const toolbar2 = D.addClass(D.div(), 'toolbar');
1139 D.append(this.e, toolbar2);
1140 D.append(toolbar2, D.button(
1141 "Toggle text mode", function(){
1142 self.hide();
1143 Chat.toggleTextMode(eMsg);
1144 }));
 
 
 
 
1145 if(eMsg.dataset.xfrom){
1146 /* Add a link to the /timeline filtered on this user. */
1147 const timelineLink = D.attr(
1148 D.a(F.repoUrl('timeline',{
1149 u: eMsg.dataset.xfrom,
@@ -1350,29 +1377,35 @@
1350 */
1351 Chat.submitMessage = function f(){
1352 if(!f.spaces){
1353 f.spaces = /\s+$/;
1354 f.markdownContinuation = /\\\s+$/;
 
1355 }
1356 this.setCurrentView(this.e.viewMessages);
1357 const fd = new FormData();
1358 const fallback = {msg: this.inputValue()};
1359 var msg = fallback.msg.trim();
1360 if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
1361 /* Cosmetic: trim whitespace from the ends of lines to try to
1362 keep copy/paste from terminals, especially wide ones, from
1363 forcing a horizontal scrollbar on all clients. This breaks
1364 markdown's use of blackslash-space-space for paragraph
1365 continuation, but *not* doing this affects all clients every
1366 time someone pastes in console copy/paste from an affected
1367 platform. We seem to have narrowed to the console pasting
1368 problem to users of tmux. Most consoles don't behave
1369 that way. */
 
 
 
 
 
1370 const xmsg = msg.split('\n');
1371 xmsg.forEach(function(line,ndx){
1372 if(!f.markdownContinuation.test(line)){
1373 xmsg[ndx] = line.trimRight();
1374 }
1375 });
1376 msg = xmsg.join('\n');
1377 }
1378 if(msg) fd.set('msg',msg);
1379
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -702,10 +702,15 @@
702 }
703 if(!e || !id) return false;
704 else if(e.$isToggling) return;
705 e.$isToggling = true;
706 const content = e.querySelector('.content-target');
707 if(!content){
708 console.warn("Should not be possible: trying to toggle text",
709 "mode of a message with no .content-target.", e);
710 return;
711 }
712 if(!content.$elems){
713 content.$elems = [
714 content.firstElementChild, // parsed elem
715 undefined // plaintext elem
716 ];
@@ -714,21 +719,39 @@
719 const child = (
720 content.firstElementChild===content.$elems[0]
721 ? content.$elems[1]
722 : content.$elems[0]
723 );
724 D.clearElement(content);
725 if(child===content.$elems[1]){
726 /* When showing the unformatted version, inject a
727 copy-to-clipboard button. This is a workaround for
728 mouse-copying from that field collecting twice as many
729 newlines as it should (for unknown reasons). */
730 const cpId = 'copy-to-clipboard-'+id;
731 /* ^^^ copy button element ID, needed for LABEL element
732 pairing. Recall that we destroy all child elements of
733 `content` each time we hit this block, so we can reuse
734 that element ID on subsequent toggles. */
735 const btnCp = D.attr(D.addClass(D.span(),'copy-button'), 'id', cpId);
736 F.copyButton(btnCp, {extractText: ()=>child._xmsgRaw});
737 const lblCp = D.label(cpId, "Copy unformatted text");
738 lblCp.addEventListener('click',()=>btnCp.click(), false);
739 D.append(content, D.append(D.addClass(D.span(), 'nobr'), btnCp, lblCp));
740 }
741 delete e.$isToggling;
742 D.append(content, child);
743 return;
744 }
745 // We need to fetch the plain-text version...
746 const self = this;
747 F.fetch('chat-fetch-one',{
748 urlParams:{ name: id, raw: true},
749 responseType: 'json',
750 onload: function(msg){
751 content.$elems[1] = D.append(D.pre(),msg.xmsg);
752 content.$elems[1]._xmsgRaw = msg.xmsg/*used for copy-to-clipboard feature*/;
753 self.toggleTextMode(e);
754 },
755 aftersend:function(){
756 delete e.$isToggling;
757 Chat.ajaxEnd();
@@ -1135,15 +1158,19 @@
1158 eMsg.scrollIntoView();
1159 }
1160 ));
1161 const toolbar2 = D.addClass(D.div(), 'toolbar');
1162 D.append(this.e, toolbar2);
1163 if(eMsg.querySelector('.content-target')){
1164 /* ^^^ messages with only an embedded image have no
1165 .content-target area. */
1166 D.append(toolbar2, D.button(
1167 "Toggle text mode", function(){
1168 self.hide();
1169 Chat.toggleTextMode(eMsg);
1170 }));
1171 }
1172 if(eMsg.dataset.xfrom){
1173 /* Add a link to the /timeline filtered on this user. */
1174 const timelineLink = D.attr(
1175 D.a(F.repoUrl('timeline',{
1176 u: eMsg.dataset.xfrom,
@@ -1350,29 +1377,35 @@
1377 */
1378 Chat.submitMessage = function f(){
1379 if(!f.spaces){
1380 f.spaces = /\s+$/;
1381 f.markdownContinuation = /\\\s+$/;
1382 f.spaces2 = /\s{3,}$/;
1383 }
1384 this.setCurrentView(this.e.viewMessages);
1385 const fd = new FormData();
1386 const fallback = {msg: this.inputValue()};
1387 var msg = fallback.msg;
1388 if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
1389 /* Cosmetic: trim most whitespace from the ends of lines to try to
1390 keep copy/paste from terminals, especially wide ones, from
1391 forcing a horizontal scrollbar on all clients. This breaks
1392 markdown's use of blackslash-space-space for paragraph
1393 continuation, but *not* doing this affects all clients every
1394 time someone pastes in console copy/paste from an affected
1395 platform. We seem to have narrowed to the console pasting
1396 problem to users of tmux together with certain apps (vim, at
1397 a minimum). Most consoles don't behave that way.
1398
1399 We retain two trailing spaces so that markdown conventions
1400 which use end-of-line spacing aren't broken by this
1401 stripping.
1402 */
1403 const xmsg = msg.split('\n');
1404 xmsg.forEach(function(line,ndx){
1405 if(!f.markdownContinuation.test(line)){
1406 xmsg[ndx] = line.replace(f.spaces2, ' ');
1407 }
1408 });
1409 msg = xmsg.join('\n');
1410 }
1411 if(msg) fd.set('msg',msg);
1412
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -1,12 +1,20 @@
11
(function(F/*the fossil object*/){
22
"use strict";
33
/**
4
- Client-side implementation of the /pikchrshow app. Requires that
4
+ Client-side implementation of the /pikchrshowcs app. Requires that
55
the fossil JS bootstrapping is complete and that these fossil JS
66
APIs have been installed: fossil.fetch, fossil.dom,
77
fossil.copybutton, fossil.popupwidget, fossil.storage
8
+
9
+ Maintenance funkiness note: this file is for the legacy
10
+ /pikchrshowcs app, which was formerly named /pikchrshow. This
11
+ file and its replacement were not renamed because the replacement
12
+ impl would end up getting this file's name and cause confusion in
13
+ the file history. Whether that confusion would be less than this
14
+ file's name matching the _other_ /pikchrshow impl will cause more
15
+ or less confusion than that remains to be seen.
816
*/
917
const E = (s)=>document.querySelector(s),
1018
D = F.dom,
1119
P = F.page;
1220
1321
1422
ADDED src/fossil.page.pikchrshowasm.js
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -1,12 +1,20 @@
1 (function(F/*the fossil object*/){
2 "use strict";
3 /**
4 Client-side implementation of the /pikchrshow app. Requires that
5 the fossil JS bootstrapping is complete and that these fossil JS
6 APIs have been installed: fossil.fetch, fossil.dom,
7 fossil.copybutton, fossil.popupwidget, fossil.storage
 
 
 
 
 
 
 
 
8 */
9 const E = (s)=>document.querySelector(s),
10 D = F.dom,
11 P = F.page;
12
13
14 DDED src/fossil.page.pikchrshowasm.js
--- src/fossil.page.pikchrshow.js
+++ src/fossil.page.pikchrshow.js
@@ -1,12 +1,20 @@
1 (function(F/*the fossil object*/){
2 "use strict";
3 /**
4 Client-side implementation of the /pikchrshowcs app. Requires that
5 the fossil JS bootstrapping is complete and that these fossil JS
6 APIs have been installed: fossil.fetch, fossil.dom,
7 fossil.copybutton, fossil.popupwidget, fossil.storage
8
9 Maintenance funkiness note: this file is for the legacy
10 /pikchrshowcs app, which was formerly named /pikchrshow. This
11 file and its replacement were not renamed because the replacement
12 impl would end up getting this file's name and cause confusion in
13 the file history. Whether that confusion would be less than this
14 file's name matching the _other_ /pikchrshow impl will cause more
15 or less confusion than that remains to be seen.
16 */
17 const E = (s)=>document.querySelector(s),
18 D = F.dom,
19 P = F.page;
20
21
22 DDED src/fossil.page.pikchrshowasm.js
--- a/src/fossil.page.pikchrshowasm.js
+++ b/src/fossil.page.pikchrshowasm.js
@@ -0,0 +1,24 @@
1
+/*
2
+ 2022-05-20
3
+
4
+ The author disclaims copyright to this source code. In place of a
5
+ legal notice, here is a blessing:
6
+
7
+ * May you do good and not evil.
8
+ * May you find forgiveness for yourself and forgive others.
9
+ * May you share freely, never taking more than you give.
10
+
11
+ ***********************************************************************
12
+
13
+ This is the main entry point for the WASM r
14
+ * May you share fre/*
15
+ :div.didiv. ttr(selectScript, 'aria-label', 'Example Scripts');
16
+ D.attr(selectScript,...EAll('body > *:not(.content)let ht = whht -= F.dom.effectiveHeight(e))
17
+ ];
18
+
19
+
20
+})(window.fossil);
21
+E('body > header.header'),
22
+ E('body > nav.mainmenu'),
23
+ E('body > footer.footervar ht;
24
+ var extra = 0e ? extra + ht = wh - extradivdidivshowshow-ready',show
--- a/src/fossil.page.pikchrshowasm.js
+++ b/src/fossil.page.pikchrshowasm.js
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/fossil.page.pikchrshowasm.js
+++ b/src/fossil.page.pikchrshowasm.js
@@ -0,0 +1,24 @@
1 /*
2 2022-05-20
3
4 The author disclaims copyright to this source code. In place of a
5 legal notice, here is a blessing:
6
7 * May you do good and not evil.
8 * May you find forgiveness for yourself and forgive others.
9 * May you share freely, never taking more than you give.
10
11 ***********************************************************************
12
13 This is the main entry point for the WASM r
14 * May you share fre/*
15 :div.didiv. ttr(selectScript, 'aria-label', 'Example Scripts');
16 D.attr(selectScript,...EAll('body > *:not(.content)let ht = whht -= F.dom.effectiveHeight(e))
17 ];
18
19
20 })(window.fossil);
21 E('body > header.header'),
22 E('body > nav.mainmenu'),
23 E('body > footer.footervar ht;
24 var extra = 0e ? extra + ht = wh - extradivdidivshowshow-ready',show
+1 -1
--- src/hook.c
+++ src/hook.c
@@ -476,11 +476,11 @@
476476
int childPid;
477477
if( cnt==0 ){
478478
hook_changes(&chng, zLastRcvid, 0);
479479
}
480480
zCmd = hook_subst(db_column_text(&q,0), 0);
481
- if( popen2(zCmd, &fdFromChild, &toChild, &childPid, 0) ){
481
+ if( popen2(zCmd, &fdFromChild, &toChild, &childPid, 0)==0 ){
482482
if( toChild ){
483483
fwrite(blob_buffer(&chng),1,blob_size(&chng),toChild);
484484
}
485485
pclose2(fdFromChild, toChild, childPid);
486486
}
487487
--- src/hook.c
+++ src/hook.c
@@ -476,11 +476,11 @@
476 int childPid;
477 if( cnt==0 ){
478 hook_changes(&chng, zLastRcvid, 0);
479 }
480 zCmd = hook_subst(db_column_text(&q,0), 0);
481 if( popen2(zCmd, &fdFromChild, &toChild, &childPid, 0) ){
482 if( toChild ){
483 fwrite(blob_buffer(&chng),1,blob_size(&chng),toChild);
484 }
485 pclose2(fdFromChild, toChild, childPid);
486 }
487
--- src/hook.c
+++ src/hook.c
@@ -476,11 +476,11 @@
476 int childPid;
477 if( cnt==0 ){
478 hook_changes(&chng, zLastRcvid, 0);
479 }
480 zCmd = hook_subst(db_column_text(&q,0), 0);
481 if( popen2(zCmd, &fdFromChild, &toChild, &childPid, 0)==0 ){
482 if( toChild ){
483 fwrite(blob_buffer(&chng),1,blob_size(&chng),toChild);
484 }
485 pclose2(fdFromChild, toChild, childPid);
486 }
487
+1 -1
--- src/info.c
+++ src/info.c
@@ -988,11 +988,11 @@
988988
moderation_approve('w', rid);
989989
}
990990
}
991991
style_header("Update of \"%h\"", pWiki->zWikiTitle);
992992
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
993
- zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
993
+ zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pWiki->rDate);
994994
style_submenu_element("Raw", "%R/artifact/%s", zUuid);
995995
style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
996996
style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle);
997997
login_anonymous_available();
998998
@ <div class="section">Overview</div>
999999
--- src/info.c
+++ src/info.c
@@ -988,11 +988,11 @@
988 moderation_approve('w', rid);
989 }
990 }
991 style_header("Update of \"%h\"", pWiki->zWikiTitle);
992 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
993 zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
994 style_submenu_element("Raw", "%R/artifact/%s", zUuid);
995 style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
996 style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle);
997 login_anonymous_available();
998 @ <div class="section">Overview</div>
999
--- src/info.c
+++ src/info.c
@@ -988,11 +988,11 @@
988 moderation_approve('w', rid);
989 }
990 }
991 style_header("Update of \"%h\"", pWiki->zWikiTitle);
992 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
993 zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pWiki->rDate);
994 style_submenu_element("Raw", "%R/artifact/%s", zUuid);
995 style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
996 style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle);
997 login_anonymous_available();
998 @ <div class="section">Overview</div>
999
+10 -8
--- src/json.c
+++ src/json.c
@@ -558,11 +558,11 @@
558558
/*
559559
** Guesses a RESPONSE Content-Type value based (primarily) on the
560560
** HTTP_ACCEPT header.
561561
**
562562
** It will try to figure out if the client can support
563
-** application/json or application/javascript, and will fall back to
563
+** application/json, text/javascript, and will fall back to
564564
** text/plain if it cannot figure out anything more specific.
565565
**
566566
** Returned memory is static and immutable, but if the environment
567567
** changes after calling this then subsequent calls to this function
568568
** might return different (also static/immutable) values.
@@ -573,12 +573,12 @@
573573
cset = PD("HTTP_ACCEPT_CHARSET",NULL);
574574
doUtf8 = ((NULL == cset) || (NULL!=strstr("utf-8",cset)))
575575
? 1 : 0;
576576
if( g.json.jsonp ){
577577
return doUtf8
578
- ? "application/javascript; charset=utf-8"
579
- : "application/javascript";
578
+ ? "text/javascript; charset=utf-8"
579
+ : "text/javascript";
580580
}else{
581581
/*
582582
Content-type
583583
584584
If the browser does not sent an ACCEPT for application/json
@@ -605,18 +605,19 @@
605605
606606
/*
607607
** Given a request CONTENT_TYPE value, this function returns true
608608
** if it is of a type which the JSON API can ostensibly read.
609609
**
610
- ** It accepts any of application/json, text/plain, or
611
- ** application/javascript. The former is preferred, but was not
612
- ** widespread when this API was initially built, so the latter forms
613
- ** are permitted as fallbacks.
610
+ ** It accepts any of application/json, text/plain,
611
+ ** application/javascript, or text/javascript. The former is
612
+ ** preferred, but was not widespread when this API was initially
613
+ ** built, so the latter forms are permitted as fallbacks.
614614
*/
615615
int json_can_consume_content_type(const char * zType){
616616
return fossil_strcmp(zType, "application/json")==0
617617
|| fossil_strcmp(zType,"text/plain")==0/*assume this MIGHT be JSON*/
618
+ || fossil_strcmp(zType,"text/javascript")==0
618619
|| fossil_strcmp(zType,"application/javascript")==0;
619620
}
620621
621622
/*
622623
** Sends pResponse to the output stream as the response object. This
@@ -627,18 +628,19 @@
627628
** In CLI mode pResponse is sent to stdout immediately. In HTTP
628629
** mode pResponse replaces any current CGI content but cgi_reply()
629630
** is not called to flush the output.
630631
**
631632
** If g.json.jsonp is not NULL then the content type is set to
632
-** application/javascript and the output is wrapped in a jsonp
633
+** text/javascript and the output is wrapped in a jsonp
633634
** wrapper.
634635
*/
635636
void json_send_response( cson_value const * pResponse ){
636637
assert( NULL != pResponse );
637638
if( g.isHTTP ){
638639
cgi_reset_content();
639640
if( g.json.jsonp ){
641
+ cgi_set_content_type("text/javascript");
640642
cgi_printf("%s(",g.json.jsonp);
641643
}
642644
cson_output( pResponse, cson_data_dest_cgi, NULL, &g.json.outOpt );
643645
if( g.json.jsonp ){
644646
cgi_append_content(")",1);
645647
--- src/json.c
+++ src/json.c
@@ -558,11 +558,11 @@
558 /*
559 ** Guesses a RESPONSE Content-Type value based (primarily) on the
560 ** HTTP_ACCEPT header.
561 **
562 ** It will try to figure out if the client can support
563 ** application/json or application/javascript, and will fall back to
564 ** text/plain if it cannot figure out anything more specific.
565 **
566 ** Returned memory is static and immutable, but if the environment
567 ** changes after calling this then subsequent calls to this function
568 ** might return different (also static/immutable) values.
@@ -573,12 +573,12 @@
573 cset = PD("HTTP_ACCEPT_CHARSET",NULL);
574 doUtf8 = ((NULL == cset) || (NULL!=strstr("utf-8",cset)))
575 ? 1 : 0;
576 if( g.json.jsonp ){
577 return doUtf8
578 ? "application/javascript; charset=utf-8"
579 : "application/javascript";
580 }else{
581 /*
582 Content-type
583
584 If the browser does not sent an ACCEPT for application/json
@@ -605,18 +605,19 @@
605
606 /*
607 ** Given a request CONTENT_TYPE value, this function returns true
608 ** if it is of a type which the JSON API can ostensibly read.
609 **
610 ** It accepts any of application/json, text/plain, or
611 ** application/javascript. The former is preferred, but was not
612 ** widespread when this API was initially built, so the latter forms
613 ** are permitted as fallbacks.
614 */
615 int json_can_consume_content_type(const char * zType){
616 return fossil_strcmp(zType, "application/json")==0
617 || fossil_strcmp(zType,"text/plain")==0/*assume this MIGHT be JSON*/
 
618 || fossil_strcmp(zType,"application/javascript")==0;
619 }
620
621 /*
622 ** Sends pResponse to the output stream as the response object. This
@@ -627,18 +628,19 @@
627 ** In CLI mode pResponse is sent to stdout immediately. In HTTP
628 ** mode pResponse replaces any current CGI content but cgi_reply()
629 ** is not called to flush the output.
630 **
631 ** If g.json.jsonp is not NULL then the content type is set to
632 ** application/javascript and the output is wrapped in a jsonp
633 ** wrapper.
634 */
635 void json_send_response( cson_value const * pResponse ){
636 assert( NULL != pResponse );
637 if( g.isHTTP ){
638 cgi_reset_content();
639 if( g.json.jsonp ){
 
640 cgi_printf("%s(",g.json.jsonp);
641 }
642 cson_output( pResponse, cson_data_dest_cgi, NULL, &g.json.outOpt );
643 if( g.json.jsonp ){
644 cgi_append_content(")",1);
645
--- src/json.c
+++ src/json.c
@@ -558,11 +558,11 @@
558 /*
559 ** Guesses a RESPONSE Content-Type value based (primarily) on the
560 ** HTTP_ACCEPT header.
561 **
562 ** It will try to figure out if the client can support
563 ** application/json, text/javascript, and will fall back to
564 ** text/plain if it cannot figure out anything more specific.
565 **
566 ** Returned memory is static and immutable, but if the environment
567 ** changes after calling this then subsequent calls to this function
568 ** might return different (also static/immutable) values.
@@ -573,12 +573,12 @@
573 cset = PD("HTTP_ACCEPT_CHARSET",NULL);
574 doUtf8 = ((NULL == cset) || (NULL!=strstr("utf-8",cset)))
575 ? 1 : 0;
576 if( g.json.jsonp ){
577 return doUtf8
578 ? "text/javascript; charset=utf-8"
579 : "text/javascript";
580 }else{
581 /*
582 Content-type
583
584 If the browser does not sent an ACCEPT for application/json
@@ -605,18 +605,19 @@
605
606 /*
607 ** Given a request CONTENT_TYPE value, this function returns true
608 ** if it is of a type which the JSON API can ostensibly read.
609 **
610 ** It accepts any of application/json, text/plain,
611 ** application/javascript, or text/javascript. The former is
612 ** preferred, but was not widespread when this API was initially
613 ** built, so the latter forms are permitted as fallbacks.
614 */
615 int json_can_consume_content_type(const char * zType){
616 return fossil_strcmp(zType, "application/json")==0
617 || fossil_strcmp(zType,"text/plain")==0/*assume this MIGHT be JSON*/
618 || fossil_strcmp(zType,"text/javascript")==0
619 || fossil_strcmp(zType,"application/javascript")==0;
620 }
621
622 /*
623 ** Sends pResponse to the output stream as the response object. This
@@ -627,18 +628,19 @@
628 ** In CLI mode pResponse is sent to stdout immediately. In HTTP
629 ** mode pResponse replaces any current CGI content but cgi_reply()
630 ** is not called to flush the output.
631 **
632 ** If g.json.jsonp is not NULL then the content type is set to
633 ** text/javascript and the output is wrapped in a jsonp
634 ** wrapper.
635 */
636 void json_send_response( cson_value const * pResponse ){
637 assert( NULL != pResponse );
638 if( g.isHTTP ){
639 cgi_reset_content();
640 if( g.json.jsonp ){
641 cgi_set_content_type("text/javascript");
642 cgi_printf("%s(",g.json.jsonp);
643 }
644 cson_output( pResponse, cson_data_dest_cgi, NULL, &g.json.outOpt );
645 if( g.json.jsonp ){
646 cgi_append_content(")",1);
647
+1 -1
--- src/main.c
+++ src/main.c
@@ -177,11 +177,11 @@
177177
int fNoHttpCompress; /* Do not compress HTTP traffic (for debugging) */
178178
char *zSshCmd; /* SSH command string */
179179
const char *zHttpCmd; /* External program to do HTTP requests */
180180
int fNoSync; /* Do not do an autosync ever. --nosync */
181181
int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
182
- char *zPath; /* Name of webpage being served */
182
+ char *zPath; /* Name of webpage being served (may be NULL) */
183183
char *zExtra; /* Extra path information past the webpage name */
184184
char *zBaseURL; /* Full text of the URL being served */
185185
char *zHttpsURL; /* zBaseURL translated to https: */
186186
char *zTop; /* Parent directory of zPath */
187187
int nExtraURL; /* Extra bytes added to SCRIPT_NAME */
188188
--- src/main.c
+++ src/main.c
@@ -177,11 +177,11 @@
177 int fNoHttpCompress; /* Do not compress HTTP traffic (for debugging) */
178 char *zSshCmd; /* SSH command string */
179 const char *zHttpCmd; /* External program to do HTTP requests */
180 int fNoSync; /* Do not do an autosync ever. --nosync */
181 int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
182 char *zPath; /* Name of webpage being served */
183 char *zExtra; /* Extra path information past the webpage name */
184 char *zBaseURL; /* Full text of the URL being served */
185 char *zHttpsURL; /* zBaseURL translated to https: */
186 char *zTop; /* Parent directory of zPath */
187 int nExtraURL; /* Extra bytes added to SCRIPT_NAME */
188
--- src/main.c
+++ src/main.c
@@ -177,11 +177,11 @@
177 int fNoHttpCompress; /* Do not compress HTTP traffic (for debugging) */
178 char *zSshCmd; /* SSH command string */
179 const char *zHttpCmd; /* External program to do HTTP requests */
180 int fNoSync; /* Do not do an autosync ever. --nosync */
181 int fIPv4; /* Use only IPv4, not IPv6. --ipv4 */
182 char *zPath; /* Name of webpage being served (may be NULL) */
183 char *zExtra; /* Extra path information past the webpage name */
184 char *zBaseURL; /* Full text of the URL being served */
185 char *zHttpsURL; /* zBaseURL translated to https: */
186 char *zTop; /* Parent directory of zPath */
187 int nExtraURL; /* Extra bytes added to SCRIPT_NAME */
188
+10
--- src/main.mk
+++ src/main.mk
@@ -163,10 +163,13 @@
163163
$(SRCDIR)/xfer.c \
164164
$(SRCDIR)/xfersetup.c \
165165
$(SRCDIR)/zip.c
166166
167167
EXTRA_FILES = \
168
+ $(SRCDIR)/../extsrc/pikchr-worker.js \
169
+ $(SRCDIR)/../extsrc/pikchr.js \
170
+ $(SRCDIR)/../extsrc/pikchr.wasm \
168171
$(SRCDIR)/../skins/ardoise/css.txt \
169172
$(SRCDIR)/../skins/ardoise/details.txt \
170173
$(SRCDIR)/../skins/ardoise/footer.txt \
171174
$(SRCDIR)/../skins/ardoise/header.txt \
172175
$(SRCDIR)/../skins/black_and_white/css.txt \
@@ -231,10 +234,11 @@
231234
$(SRCDIR)/fossil.page.brlist.js \
232235
$(SRCDIR)/fossil.page.chat.js \
233236
$(SRCDIR)/fossil.page.fileedit.js \
234237
$(SRCDIR)/fossil.page.forumpost.js \
235238
$(SRCDIR)/fossil.page.pikchrshow.js \
239
+ $(SRCDIR)/fossil.page.pikchrshowasm.js \
236240
$(SRCDIR)/fossil.page.whistory.js \
237241
$(SRCDIR)/fossil.page.wikiedit.js \
238242
$(SRCDIR)/fossil.pikchr.js \
239243
$(SRCDIR)/fossil.popupwidget.js \
240244
$(SRCDIR)/fossil.storage.js \
@@ -266,10 +270,11 @@
266270
$(SRCDIR)/sounds/e.wav \
267271
$(SRCDIR)/sounds/f.wav \
268272
$(SRCDIR)/style.admin_log.css \
269273
$(SRCDIR)/style.chat.css \
270274
$(SRCDIR)/style.fileedit.css \
275
+ $(SRCDIR)/style.pikchrshow.css \
271276
$(SRCDIR)/style.wikiedit.css \
272277
$(SRCDIR)/tree.js \
273278
$(SRCDIR)/useredit.js \
274279
$(SRCDIR)/wiki.wiki
275280
@@ -2108,13 +2113,18 @@
21082113
$(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
21092114
$(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
21102115
21112116
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
21122117
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2118
+
2119
+$(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
2120
+ $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c -sENVIRONMENT=web -sMODULARIZE -sEXPORT_NAME=initPikchrModule --minify 0
2121
+ @chmod -x $(SRCDIR_extsrc)/pikchr.wasm
2122
+wasm: $(SRCDIR_extsrc)/pikchr.js
21132123
21142124
#
21152125
# The list of all the targets that do not correspond to real files. This stops
21162126
# 'make' from getting confused when someone makes an error in a rule.
21172127
#
21182128
21192129
.PHONY: all install test clean
21202130
21212131
--- src/main.mk
+++ src/main.mk
@@ -163,10 +163,13 @@
163 $(SRCDIR)/xfer.c \
164 $(SRCDIR)/xfersetup.c \
165 $(SRCDIR)/zip.c
166
167 EXTRA_FILES = \
 
 
 
168 $(SRCDIR)/../skins/ardoise/css.txt \
169 $(SRCDIR)/../skins/ardoise/details.txt \
170 $(SRCDIR)/../skins/ardoise/footer.txt \
171 $(SRCDIR)/../skins/ardoise/header.txt \
172 $(SRCDIR)/../skins/black_and_white/css.txt \
@@ -231,10 +234,11 @@
231 $(SRCDIR)/fossil.page.brlist.js \
232 $(SRCDIR)/fossil.page.chat.js \
233 $(SRCDIR)/fossil.page.fileedit.js \
234 $(SRCDIR)/fossil.page.forumpost.js \
235 $(SRCDIR)/fossil.page.pikchrshow.js \
 
236 $(SRCDIR)/fossil.page.whistory.js \
237 $(SRCDIR)/fossil.page.wikiedit.js \
238 $(SRCDIR)/fossil.pikchr.js \
239 $(SRCDIR)/fossil.popupwidget.js \
240 $(SRCDIR)/fossil.storage.js \
@@ -266,10 +270,11 @@
266 $(SRCDIR)/sounds/e.wav \
267 $(SRCDIR)/sounds/f.wav \
268 $(SRCDIR)/style.admin_log.css \
269 $(SRCDIR)/style.chat.css \
270 $(SRCDIR)/style.fileedit.css \
 
271 $(SRCDIR)/style.wikiedit.css \
272 $(SRCDIR)/tree.js \
273 $(SRCDIR)/useredit.js \
274 $(SRCDIR)/wiki.wiki
275
@@ -2108,13 +2113,18 @@
2108 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2109 $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2110
2111 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2112 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
 
 
 
 
 
2113
2114 #
2115 # The list of all the targets that do not correspond to real files. This stops
2116 # 'make' from getting confused when someone makes an error in a rule.
2117 #
2118
2119 .PHONY: all install test clean
2120
2121
--- src/main.mk
+++ src/main.mk
@@ -163,10 +163,13 @@
163 $(SRCDIR)/xfer.c \
164 $(SRCDIR)/xfersetup.c \
165 $(SRCDIR)/zip.c
166
167 EXTRA_FILES = \
168 $(SRCDIR)/../extsrc/pikchr-worker.js \
169 $(SRCDIR)/../extsrc/pikchr.js \
170 $(SRCDIR)/../extsrc/pikchr.wasm \
171 $(SRCDIR)/../skins/ardoise/css.txt \
172 $(SRCDIR)/../skins/ardoise/details.txt \
173 $(SRCDIR)/../skins/ardoise/footer.txt \
174 $(SRCDIR)/../skins/ardoise/header.txt \
175 $(SRCDIR)/../skins/black_and_white/css.txt \
@@ -231,10 +234,11 @@
234 $(SRCDIR)/fossil.page.brlist.js \
235 $(SRCDIR)/fossil.page.chat.js \
236 $(SRCDIR)/fossil.page.fileedit.js \
237 $(SRCDIR)/fossil.page.forumpost.js \
238 $(SRCDIR)/fossil.page.pikchrshow.js \
239 $(SRCDIR)/fossil.page.pikchrshowasm.js \
240 $(SRCDIR)/fossil.page.whistory.js \
241 $(SRCDIR)/fossil.page.wikiedit.js \
242 $(SRCDIR)/fossil.pikchr.js \
243 $(SRCDIR)/fossil.popupwidget.js \
244 $(SRCDIR)/fossil.storage.js \
@@ -266,10 +270,11 @@
270 $(SRCDIR)/sounds/e.wav \
271 $(SRCDIR)/sounds/f.wav \
272 $(SRCDIR)/style.admin_log.css \
273 $(SRCDIR)/style.chat.css \
274 $(SRCDIR)/style.fileedit.css \
275 $(SRCDIR)/style.pikchrshow.css \
276 $(SRCDIR)/style.wikiedit.css \
277 $(SRCDIR)/tree.js \
278 $(SRCDIR)/useredit.js \
279 $(SRCDIR)/wiki.wiki
280
@@ -2108,13 +2113,18 @@
2113 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2114 $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2115
2116 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2117 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2118
2119 $(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
2120 $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c -sENVIRONMENT=web -sMODULARIZE -sEXPORT_NAME=initPikchrModule --minify 0
2121 @chmod -x $(SRCDIR_extsrc)/pikchr.wasm
2122 wasm: $(SRCDIR_extsrc)/pikchr.js
2123
2124 #
2125 # The list of all the targets that do not correspond to real files. This stops
2126 # 'make' from getting confused when someone makes an error in a rule.
2127 #
2128
2129 .PHONY: all install test clean
2130
2131
+3 -2
--- src/manifest.c
+++ src/manifest.c
@@ -2395,11 +2395,11 @@
23952395
rid, p->zUser, p->zComment,
23962396
TAG_BGCOLOR, rid,
23972397
TAG_USER, rid,
23982398
TAG_COMMENT, rid, p->rDate
23992399
);
2400
- backlink_extract(zCom, 0, rid, BKLNK_COMMENT, p->rDate, 1);
2400
+ backlink_extract(zCom, MT_NONE, rid, BKLNK_COMMENT, p->rDate, 1);
24012401
fossil_free(zCom);
24022402
24032403
/* If this is a delta-manifest, record the fact that this repository
24042404
** contains delta manifests, to free the "commit" logic to generate
24052405
** new delta manifests.
@@ -2853,11 +2853,12 @@
28532853
p->rDate, rid, p->zUser, zFType, zTitle
28542854
);
28552855
fossil_free(zTitle);
28562856
}
28572857
if( p->zWiki[0] ){
2858
- backlink_extract(p->zWiki, p->zMimetype, rid, BKLNK_FORUM, p->rDate, 1);
2858
+ int mimetype = parse_mimetype(p->zMimetype);
2859
+ backlink_extract(p->zWiki, mimetype, rid, BKLNK_FORUM, p->rDate, 1);
28592860
}
28602861
}
28612862
28622863
db_end_transaction(0);
28632864
if( permitHooks ){
28642865
--- src/manifest.c
+++ src/manifest.c
@@ -2395,11 +2395,11 @@
2395 rid, p->zUser, p->zComment,
2396 TAG_BGCOLOR, rid,
2397 TAG_USER, rid,
2398 TAG_COMMENT, rid, p->rDate
2399 );
2400 backlink_extract(zCom, 0, rid, BKLNK_COMMENT, p->rDate, 1);
2401 fossil_free(zCom);
2402
2403 /* If this is a delta-manifest, record the fact that this repository
2404 ** contains delta manifests, to free the "commit" logic to generate
2405 ** new delta manifests.
@@ -2853,11 +2853,12 @@
2853 p->rDate, rid, p->zUser, zFType, zTitle
2854 );
2855 fossil_free(zTitle);
2856 }
2857 if( p->zWiki[0] ){
2858 backlink_extract(p->zWiki, p->zMimetype, rid, BKLNK_FORUM, p->rDate, 1);
 
2859 }
2860 }
2861
2862 db_end_transaction(0);
2863 if( permitHooks ){
2864
--- src/manifest.c
+++ src/manifest.c
@@ -2395,11 +2395,11 @@
2395 rid, p->zUser, p->zComment,
2396 TAG_BGCOLOR, rid,
2397 TAG_USER, rid,
2398 TAG_COMMENT, rid, p->rDate
2399 );
2400 backlink_extract(zCom, MT_NONE, rid, BKLNK_COMMENT, p->rDate, 1);
2401 fossil_free(zCom);
2402
2403 /* If this is a delta-manifest, record the fact that this repository
2404 ** contains delta manifests, to free the "commit" logic to generate
2405 ** new delta manifests.
@@ -2853,11 +2853,12 @@
2853 p->rDate, rid, p->zUser, zFType, zTitle
2854 );
2855 fossil_free(zTitle);
2856 }
2857 if( p->zWiki[0] ){
2858 int mimetype = parse_mimetype(p->zMimetype);
2859 backlink_extract(p->zWiki, mimetype, rid, BKLNK_FORUM, p->rDate, 1);
2860 }
2861 }
2862
2863 db_end_transaction(0);
2864 if( permitHooks ){
2865
+2 -1
--- src/markdown.md
+++ src/markdown.md
@@ -187,11 +187,12 @@
187187
> are subject to further interpretation as Markdown sources.
188188
189189
## Miscellaneous ##
190190
191191
> * In-line images are made using **\!\[alt-text\]\(image-URL\)**.
192
-> * Use HTML for advanced formatting such as forms.
192
+> * Use HTML for advanced formatting such as forms, noting that certain
193
+> tags are [disallowed in some contexts](/help?cmd=safe-html).
193194
> * **\<!--** HTML-style comments **-->** are supported.
194195
> * Escape special characters (ex: **\[** **\(** **\|** **\***)
195196
> using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
196197
> * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
197198
> rule. Spaces and extra **-**/**\***/**_** are allowed.
198199
--- src/markdown.md
+++ src/markdown.md
@@ -187,11 +187,12 @@
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 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
195 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
196 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
197 > rule. Spaces and extra **-**/**\***/**_** are allowed.
198
--- src/markdown.md
+++ src/markdown.md
@@ -187,11 +187,12 @@
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, noting that certain
193 > tags are [disallowed in some contexts](/help?cmd=safe-html).
194 > * **\<!--** HTML-style comments **-->** are supported.
195 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
196 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
197 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
198 > rule. Spaces and extra **-**/**\***/**_** are allowed.
199
+10
--- src/path.c
+++ src/path.c
@@ -205,10 +205,20 @@
205205
for(p=path.pEnd, i=0; p && (p->isHidden || i<path.nNotHidden/2); p=p->pFrom){
206206
if( !p->isHidden ) i++;
207207
}
208208
return p;
209209
}
210
+
211
+/*
212
+** Find the next most recent node on a path.
213
+*/
214
+PathNode *path_next(void){
215
+ PathNode *p;
216
+ p = path.pStart;
217
+ if( p ) p = p->u.pTo;
218
+ return p;
219
+}
210220
211221
/*
212222
** Return an estimate of the number of comparisons remaining in order
213223
** to bisect path. This is based on the log2() of path.nStep.
214224
*/
215225
--- src/path.c
+++ src/path.c
@@ -205,10 +205,20 @@
205 for(p=path.pEnd, i=0; p && (p->isHidden || i<path.nNotHidden/2); p=p->pFrom){
206 if( !p->isHidden ) i++;
207 }
208 return p;
209 }
 
 
 
 
 
 
 
 
 
 
210
211 /*
212 ** Return an estimate of the number of comparisons remaining in order
213 ** to bisect path. This is based on the log2() of path.nStep.
214 */
215
--- src/path.c
+++ src/path.c
@@ -205,10 +205,20 @@
205 for(p=path.pEnd, i=0; p && (p->isHidden || i<path.nNotHidden/2); p=p->pFrom){
206 if( !p->isHidden ) i++;
207 }
208 return p;
209 }
210
211 /*
212 ** Find the next most recent node on a path.
213 */
214 PathNode *path_next(void){
215 PathNode *p;
216 p = path.pStart;
217 if( p ) p = p->u.pTo;
218 return p;
219 }
220
221 /*
222 ** Return an estimate of the number of comparisons remaining in order
223 ** to bisect path. This is based on the log2() of path.nStep.
224 */
225
+146 -9
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -230,30 +230,36 @@
230230
blob_reset(&bIn);
231231
return isErr;
232232
}
233233
234234
/*
235
-** WEBPAGE: pikchrshow
235
+** Legacy impl of /pikchrshow. pikchrshow_page() will delegate to
236
+** this one if the "legacy" or "ajax" request arguments are set.
236237
**
237238
** A pikchr code editor and previewer, allowing users to experiment
238239
** with pikchr code or prototype it for use in copy/pasting into forum
239
-** posts, wiki pages, or embedded docs.
240
-**
241
-** It optionally accepts a p=pikchr-script-code URL parameter or POST
242
-** value to pre-populate the editor with that code.
240
+** posts, wiki pages, or embedded docs. This version of pikchrshow
241
+** uses JavaScript to send pikchr code to the server for
242
+** processing. The newer /pikchrshow applications runs pikchr on the
243
+** client machine, without the need for back-and-forth network
244
+** traffic.
243245
*/
244
-void pikchrshow_page(void){
246
+void pikchrshowcs_page(void){
245247
const char *zContent = 0;
246248
int isDark; /* true if the current skin is "dark" */
247249
int pikFlags =
248250
PIKCHR_PROCESS_DIV
249251
| PIKCHR_PROCESS_SRC
250252
| PIKCHR_PROCESS_ERR_PRE;
251253
252254
login_check_credentials();
253255
if( !g.perm.RdWiki && !g.perm.Read && !g.perm.RdForum ){
254
- cgi_redirectf("%R/login?g=pikchrshow");
256
+ cgi_redirectf("%R/login?g=pikchrshowcs");
257
+ }
258
+ if(P("wasm")){
259
+ pikchrshow_page();
260
+ return;
255261
}
256262
zContent = PD("content",P("p"));
257263
if(P("ajax")!=0){
258264
/* Called from the JS-side preview updater.
259265
TODO: respond with JSON instead.*/
@@ -279,11 +285,11 @@
279285
"box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
280286
"arrow right 200% \"HTML+SVG\" \"Output\"\n"
281287
"arrow <-> down from last box.s\n"
282288
"box same \"Pikchr\" \"Formatter\" \"(pikchr.c)\" fit\n";
283289
}
284
- style_header("PikchrShow");
290
+ style_header("PikchrShow Client/Server");
285291
CX("<style>"); {
286292
CX("div.content { padding-top: 0.5em }\n");
287293
CX("#sbs-wrapper {"
288294
"display: flex; flex-direction: column;"
289295
"}\n");
@@ -336,11 +342,11 @@
336342
"vertical-align: middle"
337343
"}\n");
338344
CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n");
339345
} CX("</style>");
340346
CX("<div>Input pikchr code and tap Preview (or Shift-Enter) to render "
341
- "it:</div>");
347
+ "it. <a href='?wasm'>Switch to WASM mode</a>.</div>");
342348
CX("<div id='sbs-wrapper'>"); {
343349
CX("<div id='pikchrshow-form'>"); {
344350
CX("<textarea id='content' name='content' rows='15'>"
345351
"%s</textarea>",zContent/*safe-for-%s*/);
346352
CX("<div id='pikchrshow-controls'>"); {
@@ -376,10 +382,141 @@
376382
"storage", "pikchr", NULL);
377383
builtin_request_js("fossil.page.pikchrshow.js");
378384
builtin_fulfill_js_requests();
379385
style_finish_page();
380386
}
387
+
388
+/*
389
+** WEBPAGE: pikchrshow
390
+**
391
+** A pikchr code editor and previewer, allowing users to experiment
392
+** with pikchr code or prototype it for use in copy/pasting into forum
393
+** posts, wiki pages, or embedded docs. This version of pikchrshow
394
+** uses WebAssembly to run entirely in the client browser, without a
395
+** need for back-and-forth client/server traffic to perform the
396
+** rendering. The "legacy" version of this application, which sends
397
+** all input to the server for rendering, can be accessed by adding
398
+** the "legacy" URL argument.
399
+**
400
+** It optionally accepts a p=pikchr-script-code URL parameter or POST
401
+** value to pre-populate the editor with that code.
402
+*/
403
+void pikchrshow_page(void){
404
+ const char *zContent = 0;
405
+
406
+ if(P("legacy") || P("ajax")){
407
+ pikchrshowcs_page();
408
+ return;
409
+ }
410
+ login_check_credentials();
411
+ if( !g.perm.RdWiki && !g.perm.Read && !g.perm.RdForum ){
412
+ cgi_redirectf("%R/login?g=pikchrshow");
413
+ }
414
+ style_emit_noscript_for_js_page();
415
+ style_header("PikchrShow");
416
+ zContent = PD("content",P("p"));
417
+ if(!zContent){
418
+ zContent = "arrow right 200% \"Markdown\" \"Source\"\n"
419
+ "box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
420
+ "arrow right 200% \"HTML+SVG\" \"Output\"\n"
421
+ "arrow <-> down from last box.s\n"
422
+ "box same \"Pikchr\" \"Formatter\" \"(pikchr.c)\" fit\n";
423
+ }
424
+ /* Wasm load/init progress widget... */
425
+ CX("<div class='emscripten'>"); {
426
+ CX("<figure id='module-spinner'>");
427
+ CX("<div class='spinner'></div>");
428
+ CX("<div class='center'><strong>Initializing app...</strong></div>");
429
+ CX("<div class='center'>");
430
+ CX("On a slow internet connection this may take a moment. If this ");
431
+ CX("message displays for \"a long time\", intialization may have ");
432
+ CX("failed and the JavaScript console may contain clues as to why. ");
433
+ CX("</div>");
434
+ CX("<div><a href='?legacy'>Switch to legacy mode</a></div>");
435
+ CX("</figure>");
436
+ CX("<div class='emscripten' id='module-status'>Downloading...</div>");
437
+ CX("<progress value='0' max='100' id='module-progress' hidden='1'>"
438
+ "</progress>");
439
+ } CX("</div><!-- .emscripten -->");
440
+ /* Main view... */
441
+ CX("<div id='view-split' class='app-view initially-hidden'>"); {
442
+ CX("<fieldset class='options collapsible'>"); {
443
+ CX("<legend><button class='fieldset-toggle'>Options</button></legend>");
444
+ CX("<div>");
445
+ CX("<span class='labeled-input'>");
446
+ CX("<input type='checkbox' id='opt-cb-sbs' ");
447
+ CX("data-csstgt='#main-wrapper' ");
448
+ CX("data-cssclass='side-by-side' ");
449
+ CX("data-config='sideBySide'>");
450
+ CX("<label for='opt-cb-sbs'>Side-by-side</label>");
451
+ CX("</span>");
452
+ CX("<span class='labeled-input'>");
453
+ CX("<input type='checkbox' id='opt-cb-swapio' ");
454
+ CX("data-csstgt='#main-wrapper' ");
455
+ CX("data-cssclass='swapio' ");
456
+ CX("data-config='swapInOut'>");
457
+ CX("<label for='opt-cb-swapio'>Swap in/out</label>");
458
+ CX("</span>");
459
+ CX("<span class='labeled-input'>");
460
+ CX("<input type='checkbox' id='opt-cb-autofit' ");
461
+ CX("data-config='renderAutofit'>");
462
+ CX("<label for='opt-cb-autofit' "
463
+ "title='Attempt to scale SVG to fit viewport. "
464
+ "Whether it will work depends in part on the size "
465
+ "and shape of the image and the viewport.'"
466
+ ">Auto-fit SVG</label>");
467
+ CX("</span>");
468
+ CX("<span class='labeled-input'>");
469
+ CX("<input type='checkbox' id='opt-cb-autorender' ");
470
+ CX("data-csstgt='#main-wrapper' ");
471
+ CX("data-cssclass='auto-render' ");
472
+ CX("data-config='renderWhileTyping'>");
473
+ CX("<label for='opt-cb-autorender'>Render while typing</label>");
474
+ CX("</span>");
475
+ CX("<span class='labeled-input'>");
476
+ CX("<a href='?legacy'>Legacy mode</a>");
477
+ CX("</span>");
478
+ CX("</div><!-- options wrapper -->");
479
+ } CX("</fieldset>");
480
+ CX("<div id='main-wrapper' class=''>"); {
481
+ CX("<fieldset class='zone-wrapper input'>"); {
482
+ CX("<legend><div class='button-bar'>");
483
+ CX("<button id='btn-render' "
484
+ "title='Ctrl-Enter/Shift-Enter'>Render</button>");
485
+ CX("<button id='btn-clear'>Clear Input</button>");
486
+ CX("</div></legend>");
487
+ CX("<div><textarea id='input'");
488
+ CX("placeholder='Pikchr input. Ctrl-enter/shift-enter runs it.'>");
489
+ CX("/**\n");
490
+ CX(" Use ctrl-enter or shift-enter to execute\n");
491
+ CX(" pikchr code. If only a subset is currently\n");
492
+ CX(" selected, only that part is evaluated.\n*/\n");
493
+ CX("%s</textarea></div>",zContent/*safe-for-%s*/);
494
+ } CX("</fieldset><!-- .zone-wrapper.input -->");
495
+ CX("<fieldset class='zone-wrapper output'>"); {
496
+ CX("<legend><div class='button-bar'>");
497
+ CX("<button id='btn-render-mode'>Render Mode</button> ");
498
+ CX("<span style='white-space:nowrap'>"
499
+ "<span id='preview-copy-button' "
500
+ "title='Tap to copy to clipboard.'></span>"
501
+ "<label for='preview-copy-button' "
502
+ "title='Tap to copy to clipboard.'></label>"
503
+ "</span>");
504
+ CX("</div></legend>");
505
+ CX("<div id='pikchr-output-wrapper'>");
506
+ CX("<div id='pikchr-output'></div>");
507
+ CX("<textarea class='hidden' id='pikchr-output-text'></textarea>");
508
+ CX("</div>");
509
+ } CX("</fieldset> <!-- .zone-wrapper.output -->");
510
+ } CX("</div><!-- #main-wrapper -->");
511
+ } CX("</div><!-- #view-split -->");
512
+ builtin_fossil_js_bundle_or("dom", "storage", "copybutton", NULL);
513
+ builtin_request_js("fossil.page.pikchrshowasm.js");
514
+ builtin_fulfill_js_requests();
515
+ style_finish_page();
516
+}
517
+
381518
382519
/*
383520
** COMMAND: pikchr*
384521
**
385522
** Usage: %fossil pikchr [options] ?INFILE? ?OUTFILE?
386523
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -230,30 +230,36 @@
230 blob_reset(&bIn);
231 return isErr;
232 }
233
234 /*
235 ** WEBPAGE: pikchrshow
 
236 **
237 ** A pikchr code editor and previewer, allowing users to experiment
238 ** with pikchr code or prototype it for use in copy/pasting into forum
239 ** posts, wiki pages, or embedded docs.
240 **
241 ** It optionally accepts a p=pikchr-script-code URL parameter or POST
242 ** value to pre-populate the editor with that code.
 
243 */
244 void pikchrshow_page(void){
245 const char *zContent = 0;
246 int isDark; /* true if the current skin is "dark" */
247 int pikFlags =
248 PIKCHR_PROCESS_DIV
249 | PIKCHR_PROCESS_SRC
250 | PIKCHR_PROCESS_ERR_PRE;
251
252 login_check_credentials();
253 if( !g.perm.RdWiki && !g.perm.Read && !g.perm.RdForum ){
254 cgi_redirectf("%R/login?g=pikchrshow");
 
 
 
 
255 }
256 zContent = PD("content",P("p"));
257 if(P("ajax")!=0){
258 /* Called from the JS-side preview updater.
259 TODO: respond with JSON instead.*/
@@ -279,11 +285,11 @@
279 "box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
280 "arrow right 200% \"HTML+SVG\" \"Output\"\n"
281 "arrow <-> down from last box.s\n"
282 "box same \"Pikchr\" \"Formatter\" \"(pikchr.c)\" fit\n";
283 }
284 style_header("PikchrShow");
285 CX("<style>"); {
286 CX("div.content { padding-top: 0.5em }\n");
287 CX("#sbs-wrapper {"
288 "display: flex; flex-direction: column;"
289 "}\n");
@@ -336,11 +342,11 @@
336 "vertical-align: middle"
337 "}\n");
338 CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n");
339 } CX("</style>");
340 CX("<div>Input pikchr code and tap Preview (or Shift-Enter) to render "
341 "it:</div>");
342 CX("<div id='sbs-wrapper'>"); {
343 CX("<div id='pikchrshow-form'>"); {
344 CX("<textarea id='content' name='content' rows='15'>"
345 "%s</textarea>",zContent/*safe-for-%s*/);
346 CX("<div id='pikchrshow-controls'>"); {
@@ -376,10 +382,141 @@
376 "storage", "pikchr", NULL);
377 builtin_request_js("fossil.page.pikchrshow.js");
378 builtin_fulfill_js_requests();
379 style_finish_page();
380 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
382 /*
383 ** COMMAND: pikchr*
384 **
385 ** Usage: %fossil pikchr [options] ?INFILE? ?OUTFILE?
386
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -230,30 +230,36 @@
230 blob_reset(&bIn);
231 return isErr;
232 }
233
234 /*
235 ** Legacy impl of /pikchrshow. pikchrshow_page() will delegate to
236 ** this one if the "legacy" or "ajax" request arguments are set.
237 **
238 ** A pikchr code editor and previewer, allowing users to experiment
239 ** with pikchr code or prototype it for use in copy/pasting into forum
240 ** posts, wiki pages, or embedded docs. This version of pikchrshow
241 ** uses JavaScript to send pikchr code to the server for
242 ** processing. The newer /pikchrshow applications runs pikchr on the
243 ** client machine, without the need for back-and-forth network
244 ** traffic.
245 */
246 void pikchrshowcs_page(void){
247 const char *zContent = 0;
248 int isDark; /* true if the current skin is "dark" */
249 int pikFlags =
250 PIKCHR_PROCESS_DIV
251 | PIKCHR_PROCESS_SRC
252 | PIKCHR_PROCESS_ERR_PRE;
253
254 login_check_credentials();
255 if( !g.perm.RdWiki && !g.perm.Read && !g.perm.RdForum ){
256 cgi_redirectf("%R/login?g=pikchrshowcs");
257 }
258 if(P("wasm")){
259 pikchrshow_page();
260 return;
261 }
262 zContent = PD("content",P("p"));
263 if(P("ajax")!=0){
264 /* Called from the JS-side preview updater.
265 TODO: respond with JSON instead.*/
@@ -279,11 +285,11 @@
285 "box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
286 "arrow right 200% \"HTML+SVG\" \"Output\"\n"
287 "arrow <-> down from last box.s\n"
288 "box same \"Pikchr\" \"Formatter\" \"(pikchr.c)\" fit\n";
289 }
290 style_header("PikchrShow Client/Server");
291 CX("<style>"); {
292 CX("div.content { padding-top: 0.5em }\n");
293 CX("#sbs-wrapper {"
294 "display: flex; flex-direction: column;"
295 "}\n");
@@ -336,11 +342,11 @@
342 "vertical-align: middle"
343 "}\n");
344 CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n");
345 } CX("</style>");
346 CX("<div>Input pikchr code and tap Preview (or Shift-Enter) to render "
347 "it. <a href='?wasm'>Switch to WASM mode</a>.</div>");
348 CX("<div id='sbs-wrapper'>"); {
349 CX("<div id='pikchrshow-form'>"); {
350 CX("<textarea id='content' name='content' rows='15'>"
351 "%s</textarea>",zContent/*safe-for-%s*/);
352 CX("<div id='pikchrshow-controls'>"); {
@@ -376,10 +382,141 @@
382 "storage", "pikchr", NULL);
383 builtin_request_js("fossil.page.pikchrshow.js");
384 builtin_fulfill_js_requests();
385 style_finish_page();
386 }
387
388 /*
389 ** WEBPAGE: pikchrshow
390 **
391 ** A pikchr code editor and previewer, allowing users to experiment
392 ** with pikchr code or prototype it for use in copy/pasting into forum
393 ** posts, wiki pages, or embedded docs. This version of pikchrshow
394 ** uses WebAssembly to run entirely in the client browser, without a
395 ** need for back-and-forth client/server traffic to perform the
396 ** rendering. The "legacy" version of this application, which sends
397 ** all input to the server for rendering, can be accessed by adding
398 ** the "legacy" URL argument.
399 **
400 ** It optionally accepts a p=pikchr-script-code URL parameter or POST
401 ** value to pre-populate the editor with that code.
402 */
403 void pikchrshow_page(void){
404 const char *zContent = 0;
405
406 if(P("legacy") || P("ajax")){
407 pikchrshowcs_page();
408 return;
409 }
410 login_check_credentials();
411 if( !g.perm.RdWiki && !g.perm.Read && !g.perm.RdForum ){
412 cgi_redirectf("%R/login?g=pikchrshow");
413 }
414 style_emit_noscript_for_js_page();
415 style_header("PikchrShow");
416 zContent = PD("content",P("p"));
417 if(!zContent){
418 zContent = "arrow right 200% \"Markdown\" \"Source\"\n"
419 "box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
420 "arrow right 200% \"HTML+SVG\" \"Output\"\n"
421 "arrow <-> down from last box.s\n"
422 "box same \"Pikchr\" \"Formatter\" \"(pikchr.c)\" fit\n";
423 }
424 /* Wasm load/init progress widget... */
425 CX("<div class='emscripten'>"); {
426 CX("<figure id='module-spinner'>");
427 CX("<div class='spinner'></div>");
428 CX("<div class='center'><strong>Initializing app...</strong></div>");
429 CX("<div class='center'>");
430 CX("On a slow internet connection this may take a moment. If this ");
431 CX("message displays for \"a long time\", intialization may have ");
432 CX("failed and the JavaScript console may contain clues as to why. ");
433 CX("</div>");
434 CX("<div><a href='?legacy'>Switch to legacy mode</a></div>");
435 CX("</figure>");
436 CX("<div class='emscripten' id='module-status'>Downloading...</div>");
437 CX("<progress value='0' max='100' id='module-progress' hidden='1'>"
438 "</progress>");
439 } CX("</div><!-- .emscripten -->");
440 /* Main view... */
441 CX("<div id='view-split' class='app-view initially-hidden'>"); {
442 CX("<fieldset class='options collapsible'>"); {
443 CX("<legend><button class='fieldset-toggle'>Options</button></legend>");
444 CX("<div>");
445 CX("<span class='labeled-input'>");
446 CX("<input type='checkbox' id='opt-cb-sbs' ");
447 CX("data-csstgt='#main-wrapper' ");
448 CX("data-cssclass='side-by-side' ");
449 CX("data-config='sideBySide'>");
450 CX("<label for='opt-cb-sbs'>Side-by-side</label>");
451 CX("</span>");
452 CX("<span class='labeled-input'>");
453 CX("<input type='checkbox' id='opt-cb-swapio' ");
454 CX("data-csstgt='#main-wrapper' ");
455 CX("data-cssclass='swapio' ");
456 CX("data-config='swapInOut'>");
457 CX("<label for='opt-cb-swapio'>Swap in/out</label>");
458 CX("</span>");
459 CX("<span class='labeled-input'>");
460 CX("<input type='checkbox' id='opt-cb-autofit' ");
461 CX("data-config='renderAutofit'>");
462 CX("<label for='opt-cb-autofit' "
463 "title='Attempt to scale SVG to fit viewport. "
464 "Whether it will work depends in part on the size "
465 "and shape of the image and the viewport.'"
466 ">Auto-fit SVG</label>");
467 CX("</span>");
468 CX("<span class='labeled-input'>");
469 CX("<input type='checkbox' id='opt-cb-autorender' ");
470 CX("data-csstgt='#main-wrapper' ");
471 CX("data-cssclass='auto-render' ");
472 CX("data-config='renderWhileTyping'>");
473 CX("<label for='opt-cb-autorender'>Render while typing</label>");
474 CX("</span>");
475 CX("<span class='labeled-input'>");
476 CX("<a href='?legacy'>Legacy mode</a>");
477 CX("</span>");
478 CX("</div><!-- options wrapper -->");
479 } CX("</fieldset>");
480 CX("<div id='main-wrapper' class=''>"); {
481 CX("<fieldset class='zone-wrapper input'>"); {
482 CX("<legend><div class='button-bar'>");
483 CX("<button id='btn-render' "
484 "title='Ctrl-Enter/Shift-Enter'>Render</button>");
485 CX("<button id='btn-clear'>Clear Input</button>");
486 CX("</div></legend>");
487 CX("<div><textarea id='input'");
488 CX("placeholder='Pikchr input. Ctrl-enter/shift-enter runs it.'>");
489 CX("/**\n");
490 CX(" Use ctrl-enter or shift-enter to execute\n");
491 CX(" pikchr code. If only a subset is currently\n");
492 CX(" selected, only that part is evaluated.\n*/\n");
493 CX("%s</textarea></div>",zContent/*safe-for-%s*/);
494 } CX("</fieldset><!-- .zone-wrapper.input -->");
495 CX("<fieldset class='zone-wrapper output'>"); {
496 CX("<legend><div class='button-bar'>");
497 CX("<button id='btn-render-mode'>Render Mode</button> ");
498 CX("<span style='white-space:nowrap'>"
499 "<span id='preview-copy-button' "
500 "title='Tap to copy to clipboard.'></span>"
501 "<label for='preview-copy-button' "
502 "title='Tap to copy to clipboard.'></label>"
503 "</span>");
504 CX("</div></legend>");
505 CX("<div id='pikchr-output-wrapper'>");
506 CX("<div id='pikchr-output'></div>");
507 CX("<textarea class='hidden' id='pikchr-output-text'></textarea>");
508 CX("</div>");
509 } CX("</fieldset> <!-- .zone-wrapper.output -->");
510 } CX("</div><!-- #main-wrapper -->");
511 } CX("</div><!-- #view-split -->");
512 builtin_fossil_js_bundle_or("dom", "storage", "copybutton", NULL);
513 builtin_request_js("fossil.page.pikchrshowasm.js");
514 builtin_fulfill_js_requests();
515 style_finish_page();
516 }
517
518
519 /*
520 ** COMMAND: pikchr*
521 **
522 ** Usage: %fossil pikchr [options] ?INFILE? ?OUTFILE?
523
+12
--- src/schema.c
+++ src/schema.c
@@ -458,10 +458,11 @@
458458
@ CREATE TABLE ticketchng(
459459
@ -- Do not change any column that begins with tkt_
460460
@ tkt_id INTEGER REFERENCES ticket,
461461
@ tkt_rid INTEGER REFERENCES blob,
462462
@ tkt_mtime DATE,
463
+@ tkt_user TEXT,
463464
@ -- Add as many fields as required below this line
464465
@ login TEXT,
465466
@ username TEXT,
466467
@ mimetype TEXT,
467468
@ icomment TEXT
@@ -488,10 +489,21 @@
488489
# define BKLNK_EVENT 3 /* Technote */
489490
# define BKLNK_FORUM 4 /* Forum post */
490491
# define ValidBklnk(X) (X>=0 && X<=4) /* True if backlink.srctype is valid */
491492
#endif
492493
494
+/*
495
+** Allowed values for MIMEtype codes
496
+*/
497
+#if INTERFACE
498
+# define MT_NONE 0 /* unspecified */
499
+# define MT_WIKI 1 /* Wiki */
500
+# define MT_MARKDOWN 2 /* Markdonw */
501
+# define MT_UNKNOWN 3 /* unknown */
502
+# define ValidMTC(X) ((X)>=0 && (X)<=3) /* True if MIMEtype code is valid */
503
+#endif
504
+
493505
/*
494506
** Predefined tagid values
495507
*/
496508
#if INTERFACE
497509
# define TAG_BGCOLOR 1 /* Set the background color for display */
498510
--- src/schema.c
+++ src/schema.c
@@ -458,10 +458,11 @@
458 @ CREATE TABLE ticketchng(
459 @ -- Do not change any column that begins with tkt_
460 @ tkt_id INTEGER REFERENCES ticket,
461 @ tkt_rid INTEGER REFERENCES blob,
462 @ tkt_mtime DATE,
 
463 @ -- Add as many fields as required below this line
464 @ login TEXT,
465 @ username TEXT,
466 @ mimetype TEXT,
467 @ icomment TEXT
@@ -488,10 +489,21 @@
488 # define BKLNK_EVENT 3 /* Technote */
489 # define BKLNK_FORUM 4 /* Forum post */
490 # define ValidBklnk(X) (X>=0 && X<=4) /* True if backlink.srctype is valid */
491 #endif
492
 
 
 
 
 
 
 
 
 
 
 
493 /*
494 ** Predefined tagid values
495 */
496 #if INTERFACE
497 # define TAG_BGCOLOR 1 /* Set the background color for display */
498
--- src/schema.c
+++ src/schema.c
@@ -458,10 +458,11 @@
458 @ CREATE TABLE ticketchng(
459 @ -- Do not change any column that begins with tkt_
460 @ tkt_id INTEGER REFERENCES ticket,
461 @ tkt_rid INTEGER REFERENCES blob,
462 @ tkt_mtime DATE,
463 @ tkt_user TEXT,
464 @ -- Add as many fields as required below this line
465 @ login TEXT,
466 @ username TEXT,
467 @ mimetype TEXT,
468 @ icomment TEXT
@@ -488,10 +489,21 @@
489 # define BKLNK_EVENT 3 /* Technote */
490 # define BKLNK_FORUM 4 /* Forum post */
491 # define ValidBklnk(X) (X>=0 && X<=4) /* True if backlink.srctype is valid */
492 #endif
493
494 /*
495 ** Allowed values for MIMEtype codes
496 */
497 #if INTERFACE
498 # define MT_NONE 0 /* unspecified */
499 # define MT_WIKI 1 /* Wiki */
500 # define MT_MARKDOWN 2 /* Markdonw */
501 # define MT_UNKNOWN 3 /* unknown */
502 # define ValidMTC(X) ((X)>=0 && (X)<=3) /* True if MIMEtype code is valid */
503 #endif
504
505 /*
506 ** Predefined tagid values
507 */
508 #if INTERFACE
509 # define TAG_BGCOLOR 1 /* Set the background color for display */
510
+2 -2
--- src/search.c
+++ src/search.c
@@ -18,12 +18,12 @@
1818
** This file contains code to implement a search functions
1919
** against timeline comments, check-in content, wiki pages, tickets,
2020
** and/or forum posts.
2121
**
2222
** The search can be either a per-query "grep"-like search that scans
23
-** the entire corpus. Or it can use the FTS4 or FTS5 search engine of
24
-** SQLite. The choice is a administrator configuration option.
23
+** the entire corpus. Or it can use the FTS4 search engine of SQLite.
24
+** The choice is a administrator configuration option.
2525
**
2626
** The first option is referred to as "full-scan search". The second
2727
** option is called "indexed search".
2828
**
2929
** The code in this file is ordered approximately as follows:
3030
--- src/search.c
+++ src/search.c
@@ -18,12 +18,12 @@
18 ** This file contains code to implement a search functions
19 ** against timeline comments, check-in content, wiki pages, tickets,
20 ** and/or forum posts.
21 **
22 ** The search can be either a per-query "grep"-like search that scans
23 ** the entire corpus. Or it can use the FTS4 or FTS5 search engine of
24 ** SQLite. The choice is a administrator configuration option.
25 **
26 ** The first option is referred to as "full-scan search". The second
27 ** option is called "indexed search".
28 **
29 ** The code in this file is ordered approximately as follows:
30
--- src/search.c
+++ src/search.c
@@ -18,12 +18,12 @@
18 ** This file contains code to implement a search functions
19 ** against timeline comments, check-in content, wiki pages, tickets,
20 ** and/or forum posts.
21 **
22 ** The search can be either a per-query "grep"-like search that scans
23 ** the entire corpus. Or it can use the FTS4 search engine of SQLite.
24 ** The choice is a administrator configuration option.
25 **
26 ** The first option is referred to as "full-scan search". The second
27 ** option is called "indexed search".
28 **
29 ** The code in this file is ordered approximately as follows:
30
+3 -1
--- src/skins.c
+++ src/skins.c
@@ -1014,11 +1014,13 @@
10141014
style_header("Customize Skin");
10151015
10161016
@ <p>Customize the look of this Fossil repository by making changes
10171017
@ to the CSS, Header, Footer, and Detail Settings in one of nine "draft"
10181018
@ configurations. Then, after verifying that all is working correctly,
1019
- @ publish the draft to become the new main Skin.<p>
1019
+ @ publish the draft to become the new main Skin. Users can select a skin
1020
+ @ of their choice from the built-in ones or the locally-edited one via
1021
+ @ <a href='%R/skins'>the /skins page</a>.</p>
10201022
@
10211023
@ <a name='step1'></a>
10221024
@ <h1>Step 1: Identify Which Draft To Use</h1>
10231025
@
10241026
@ <p>The main skin of Fossil cannot be edited directly. Instead,
10251027
--- src/skins.c
+++ src/skins.c
@@ -1014,11 +1014,13 @@
1014 style_header("Customize Skin");
1015
1016 @ <p>Customize the look of this Fossil repository by making changes
1017 @ to the CSS, Header, Footer, and Detail Settings in one of nine "draft"
1018 @ configurations. Then, after verifying that all is working correctly,
1019 @ publish the draft to become the new main Skin.<p>
 
 
1020 @
1021 @ <a name='step1'></a>
1022 @ <h1>Step 1: Identify Which Draft To Use</h1>
1023 @
1024 @ <p>The main skin of Fossil cannot be edited directly. Instead,
1025
--- src/skins.c
+++ src/skins.c
@@ -1014,11 +1014,13 @@
1014 style_header("Customize Skin");
1015
1016 @ <p>Customize the look of this Fossil repository by making changes
1017 @ to the CSS, Header, Footer, and Detail Settings in one of nine "draft"
1018 @ configurations. Then, after verifying that all is working correctly,
1019 @ publish the draft to become the new main Skin. Users can select a skin
1020 @ of their choice from the built-in ones or the locally-edited one via
1021 @ <a href='%R/skins'>the /skins page</a>.</p>
1022 @
1023 @ <a name='step1'></a>
1024 @ <h1>Step 1: Identify Which Draft To Use</h1>
1025 @
1026 @ <p>The main skin of Fossil cannot be edited directly. Instead,
1027
--- src/stash.c
+++ src/stash.c
@@ -597,10 +597,11 @@
597597
/* Make sure the stash has committed before running the revert, so that
598598
** we have a copy of the changes before deleting them. */
599599
db_commit_transaction();
600600
g.argv[1] = "revert";
601601
revert_cmd();
602
+ fossil_print("stash %d saved\n", stashid);
602603
return;
603604
}else
604605
if( memcmp(zCmd, "snapshot", nCmd)==0 ){
605606
stash_create();
606607
}else
607608
--- src/stash.c
+++ src/stash.c
@@ -597,10 +597,11 @@
597 /* Make sure the stash has committed before running the revert, so that
598 ** we have a copy of the changes before deleting them. */
599 db_commit_transaction();
600 g.argv[1] = "revert";
601 revert_cmd();
 
602 return;
603 }else
604 if( memcmp(zCmd, "snapshot", nCmd)==0 ){
605 stash_create();
606 }else
607
--- src/stash.c
+++ src/stash.c
@@ -597,10 +597,11 @@
597 /* Make sure the stash has committed before running the revert, so that
598 ** we have a copy of the changes before deleting them. */
599 db_commit_transaction();
600 g.argv[1] = "revert";
601 revert_cmd();
602 fossil_print("stash %d saved\n", stashid);
603 return;
604 }else
605 if( memcmp(zCmd, "snapshot", nCmd)==0 ){
606 stash_create();
607 }else
608
+51 -14
--- src/style.c
+++ src/style.c
@@ -749,11 +749,11 @@
749749
/*
750750
** Initialize all the default TH1 variables
751751
*/
752752
static void style_init_th1_vars(const char *zTitle){
753753
const char *zNonce = style_nonce();
754
- char *zDfltCsp, *zSlash = 0;
754
+ char *zDfltCsp;
755755
756756
zDfltCsp = style_csp(1);
757757
/*
758758
** Do not overwrite the TH1 variable "default_csp" if it exists, as this
759759
** allows it to be properly overridden via the TH1 setup script (i.e. it
@@ -769,15 +769,17 @@
769769
Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
770770
Th_Store("home", g.zTop);
771771
Th_Store("index_page", db_get("index-page","/home"));
772772
if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath);
773773
Th_Store("current_page", local_zCurrentPage);
774
- /* store the first segment of a path; make a temporary cut if necessary */
775
- if( g.zPath && (zSlash = strchr(g.zPath,'/'))!=0 ){
776
- *zSlash = 0;
774
+ if( g.zPath ){ /* store the first segment of a path; */
775
+ char *pSlash = strchr(g.zPath,'/');
776
+ if( pSlash ) *pSlash = 0; /* make a temporary cut if necessary */
777777
Th_Store("requested_page", escape_quotes(g.zPath));
778
- *zSlash = '/';
778
+ if( pSlash ) *pSlash = '/';
779
+ }else{
780
+ Th_Store("requested_page", "");
779781
}
780782
Th_Store("canonical_page", escape_quotes(g.zPhase+1));
781783
Th_Store("csrf_token", g.zCsrfToken);
782784
Th_Store("release_version", RELEASE_VERSION);
783785
Th_Store("manifest_version", MANIFEST_VERSION);
@@ -899,11 +901,11 @@
899901
static void style_load_all_js_files(void){
900902
if( needHrefJs && g.perm.Hyperlink ){
901903
int nDelay = db_get_int("auto-hyperlink-delay",0);
902904
int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
903905
&& sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
904
- @ <script id='href-data' type='application/json'>\
906
+ @ <script id='href-data' type='text/json'>\
905907
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
906908
}
907909
@ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
908910
@ function debugMsg(msg){
909911
@ var n = document.getElementById("debugMsg");
@@ -919,10 +921,41 @@
919921
cgi_append_content("\n}\n", -1);
920922
}
921923
@ </script>
922924
builtin_fulfill_js_requests();
923925
}
926
+
927
+/*
928
+** Transorm input string into a token that is safe for inclusion into
929
+** class attribute. Digits and low-case letter are passed unchanged,
930
+** upper-case letters are transformed to low-case, everything else is
931
+** tranformed into hyphens; consequtive and pending hyphens are squeezed.
932
+** If result does not fit into szOut chars then it is truncated.
933
+** Result is always terminated with null.
934
+*/
935
+void style_derive_classname(const char *zIn, char *zOut, int szOut){
936
+ assert( zOut );
937
+ assert( szOut>0 );
938
+ if( zIn ){
939
+ int n = 0; /* number of chars written to zOut */
940
+ char c;
941
+ for(--szOut; (c=*zIn) && n<szOut; zIn++) {
942
+ if( ('a'<=c && c<='z') || ('0'<=c && c<='9') ){
943
+ *zOut = c;
944
+ }else if( 'A'<=c && c<='Z' ){
945
+ *zOut = c - 'A' + 'a';
946
+ }else{
947
+ if( n==0 || zOut[-1]=='-' ) continue;
948
+ *zOut = '-';
949
+ }
950
+ zOut++;
951
+ n++;
952
+ }
953
+ if( n && zOut[-1]=='-' ) zOut--;
954
+ }
955
+ *zOut = 0;
956
+}
924957
925958
/*
926959
** Invoke this routine after all of the content for a webpage has been
927960
** generated. This routine should be called once for every webpage, at
928961
** or near the end of page generation. This routine does the following:
@@ -948,10 +981,11 @@
948981
** to the submenu while generating page text.
949982
*/
950983
cgi_destination(CGI_HEADER);
951984
if( submenuEnable && nSubmenu+nSubmenuCtrl>0 ){
952985
int i;
986
+ char zClass[32]; /* reduced form of the main attribute */
953987
if( nSubmenuCtrl ){
954988
@ <form id='f01' method='GET' action='%R/%s(g.zPath)'>
955989
@ <input type='hidden' name='udc' value='1'>
956990
cgi_tag_query_parameter("udc");
957991
}
@@ -958,33 +992,36 @@
958992
@ <div class="submenu">
959993
if( nSubmenu>0 ){
960994
qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
961995
for(i=0; i<nSubmenu; i++){
962996
struct Submenu *p = &aSubmenu[i];
997
+ style_derive_classname(p->zLabel, zClass, sizeof zClass);
963998
/* switching away from the %h formatting below might be dangerous
964999
** because some places use %s to compose zLabel and zLink;
965
- ** e.g. /rptview page
1000
+ ** e.g. /rptview page. "sml" stands for submenu link.
9661001
*/
9671002
if( p->zLink==0 ){
968
- @ <span class="label">%h(p->zLabel)</span>
1003
+ @ <span class="label sml-%s(zClass)">%h(p->zLabel)</span>
9691004
}else{
970
- @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
1005
+ @ <a class="label sml-%s(zClass)" href="%h(p->zLink)">%h(p->zLabel)</a>
9711006
}
9721007
}
9731008
}
1009
+ strcpy(zClass,"smc-"); /* common prefix for submenu controls */
9741010
for(i=0; i<nSubmenuCtrl; i++){
9751011
const char *zQPN = aSubmenuCtrl[i].zName;
9761012
const char *zDisabled = "";
9771013
const char *zXtraClass = "";
9781014
if( aSubmenuCtrl[i].eVisible & STYLE_DISABLED ){
9791015
zDisabled = " disabled";
9801016
}else if( zQPN ){
9811017
cgi_tag_query_parameter(zQPN);
9821018
}
1019
+ style_derive_classname(zQPN, zClass+4, sizeof(zClass)-4);
9831020
switch( aSubmenuCtrl[i].eType ){
9841021
case FF_ENTRY:
985
- @ <span class='submenuctrl%s(zXtraClass)'>\
1022
+ @ <span class='submenuctrl%s(zXtraClass) %s(zClass)'>\
9861023
@ &nbsp;%h(aSubmenuCtrl[i].zLabel)\
9871024
@ <input type='text' name='%s(zQPN)' value='%h(PD(zQPN, ""))' \
9881025
if( aSubmenuCtrl[i].iSize<0 ){
9891026
@ size='%d(-aSubmenuCtrl[i].iSize)' \
9901027
}else if( aSubmenuCtrl[i].iSize>0 ){
@@ -995,16 +1032,16 @@
9951032
break;
9961033
case FF_MULTI: {
9971034
int j;
9981035
const char *zVal = P(zQPN);
9991036
if( zXtraClass[0] ){
1000
- @ <span class='%s(zXtraClass+1)'>
1037
+ @ <span class='%s(zXtraClass+1) %s(zClass)'>
10011038
}
10021039
if( aSubmenuCtrl[i].zLabel ){
10031040
@ &nbsp;%h(aSubmenuCtrl[i].zLabel)\
10041041
}
1005
- @ <select class='submenuctrl' size='1' name='%s(zQPN)' \
1042
+ @ <select class='submenuctrl %s(zClass)' size='1' name='%s(zQPN)' \
10061043
@ id='submenuctrl-%d(i)'%s(zDisabled)>
10071044
for(j=0; j<aSubmenuCtrl[i].iSize*2; j+=2){
10081045
const char *zQPV = aSubmenuCtrl[i].azChoice[j];
10091046
@ <option value='%h(zQPV)'\
10101047
if( fossil_strcmp(zVal, zQPV)==0 ){
@@ -1034,11 +1071,11 @@
10341071
@ >%h(aSubmenuCtrl[i].zFalse)</option>
10351072
@ </select>
10361073
break;
10371074
}
10381075
case FF_CHECKBOX: {
1039
- @ <label class='submenuctrl submenuckbox%s(zXtraClass)'>\
1076
+ @ <label class='submenuctrl submenuckbox%s(zXtraClass) %s(zClass)'>\
10401077
@ <input type='checkbox' name='%s(zQPN)' id='submenuctrl-%d(i)' \
10411078
if( PB(zQPN) ){
10421079
@ checked \
10431080
}
10441081
if( aSubmenuCtrl[i].zJS ){
@@ -1183,11 +1220,11 @@
11831220
/* Render the script as plain-text for testing purposes, if the "test"
11841221
** query parameter is present */
11851222
cgi_set_content_type("text/plain");
11861223
}else{
11871224
/* Default behavior is to return javascript */
1188
- cgi_set_content_type("application/javascript");
1225
+ cgi_set_content_type("text/javascript");
11891226
}
11901227
style_init_th1_vars(0);
11911228
Th_Render(zScript?zScript:"");
11921229
}
11931230
11941231
11951232
ADDED src/style.pikchrshow.css
--- src/style.c
+++ src/style.c
@@ -749,11 +749,11 @@
749 /*
750 ** Initialize all the default TH1 variables
751 */
752 static void style_init_th1_vars(const char *zTitle){
753 const char *zNonce = style_nonce();
754 char *zDfltCsp, *zSlash = 0;
755
756 zDfltCsp = style_csp(1);
757 /*
758 ** Do not overwrite the TH1 variable "default_csp" if it exists, as this
759 ** allows it to be properly overridden via the TH1 setup script (i.e. it
@@ -769,15 +769,17 @@
769 Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
770 Th_Store("home", g.zTop);
771 Th_Store("index_page", db_get("index-page","/home"));
772 if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath);
773 Th_Store("current_page", local_zCurrentPage);
774 /* store the first segment of a path; make a temporary cut if necessary */
775 if( g.zPath && (zSlash = strchr(g.zPath,'/'))!=0 ){
776 *zSlash = 0;
777 Th_Store("requested_page", escape_quotes(g.zPath));
778 *zSlash = '/';
 
 
779 }
780 Th_Store("canonical_page", escape_quotes(g.zPhase+1));
781 Th_Store("csrf_token", g.zCsrfToken);
782 Th_Store("release_version", RELEASE_VERSION);
783 Th_Store("manifest_version", MANIFEST_VERSION);
@@ -899,11 +901,11 @@
899 static void style_load_all_js_files(void){
900 if( needHrefJs && g.perm.Hyperlink ){
901 int nDelay = db_get_int("auto-hyperlink-delay",0);
902 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
903 && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
904 @ <script id='href-data' type='application/json'>\
905 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
906 }
907 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
908 @ function debugMsg(msg){
909 @ var n = document.getElementById("debugMsg");
@@ -919,10 +921,41 @@
919 cgi_append_content("\n}\n", -1);
920 }
921 @ </script>
922 builtin_fulfill_js_requests();
923 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
924
925 /*
926 ** Invoke this routine after all of the content for a webpage has been
927 ** generated. This routine should be called once for every webpage, at
928 ** or near the end of page generation. This routine does the following:
@@ -948,10 +981,11 @@
948 ** to the submenu while generating page text.
949 */
950 cgi_destination(CGI_HEADER);
951 if( submenuEnable && nSubmenu+nSubmenuCtrl>0 ){
952 int i;
 
953 if( nSubmenuCtrl ){
954 @ <form id='f01' method='GET' action='%R/%s(g.zPath)'>
955 @ <input type='hidden' name='udc' value='1'>
956 cgi_tag_query_parameter("udc");
957 }
@@ -958,33 +992,36 @@
958 @ <div class="submenu">
959 if( nSubmenu>0 ){
960 qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
961 for(i=0; i<nSubmenu; i++){
962 struct Submenu *p = &aSubmenu[i];
 
963 /* switching away from the %h formatting below might be dangerous
964 ** because some places use %s to compose zLabel and zLink;
965 ** e.g. /rptview page
966 */
967 if( p->zLink==0 ){
968 @ <span class="label">%h(p->zLabel)</span>
969 }else{
970 @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
971 }
972 }
973 }
 
974 for(i=0; i<nSubmenuCtrl; i++){
975 const char *zQPN = aSubmenuCtrl[i].zName;
976 const char *zDisabled = "";
977 const char *zXtraClass = "";
978 if( aSubmenuCtrl[i].eVisible & STYLE_DISABLED ){
979 zDisabled = " disabled";
980 }else if( zQPN ){
981 cgi_tag_query_parameter(zQPN);
982 }
 
983 switch( aSubmenuCtrl[i].eType ){
984 case FF_ENTRY:
985 @ <span class='submenuctrl%s(zXtraClass)'>\
986 @ &nbsp;%h(aSubmenuCtrl[i].zLabel)\
987 @ <input type='text' name='%s(zQPN)' value='%h(PD(zQPN, ""))' \
988 if( aSubmenuCtrl[i].iSize<0 ){
989 @ size='%d(-aSubmenuCtrl[i].iSize)' \
990 }else if( aSubmenuCtrl[i].iSize>0 ){
@@ -995,16 +1032,16 @@
995 break;
996 case FF_MULTI: {
997 int j;
998 const char *zVal = P(zQPN);
999 if( zXtraClass[0] ){
1000 @ <span class='%s(zXtraClass+1)'>
1001 }
1002 if( aSubmenuCtrl[i].zLabel ){
1003 @ &nbsp;%h(aSubmenuCtrl[i].zLabel)\
1004 }
1005 @ <select class='submenuctrl' size='1' name='%s(zQPN)' \
1006 @ id='submenuctrl-%d(i)'%s(zDisabled)>
1007 for(j=0; j<aSubmenuCtrl[i].iSize*2; j+=2){
1008 const char *zQPV = aSubmenuCtrl[i].azChoice[j];
1009 @ <option value='%h(zQPV)'\
1010 if( fossil_strcmp(zVal, zQPV)==0 ){
@@ -1034,11 +1071,11 @@
1034 @ >%h(aSubmenuCtrl[i].zFalse)</option>
1035 @ </select>
1036 break;
1037 }
1038 case FF_CHECKBOX: {
1039 @ <label class='submenuctrl submenuckbox%s(zXtraClass)'>\
1040 @ <input type='checkbox' name='%s(zQPN)' id='submenuctrl-%d(i)' \
1041 if( PB(zQPN) ){
1042 @ checked \
1043 }
1044 if( aSubmenuCtrl[i].zJS ){
@@ -1183,11 +1220,11 @@
1183 /* Render the script as plain-text for testing purposes, if the "test"
1184 ** query parameter is present */
1185 cgi_set_content_type("text/plain");
1186 }else{
1187 /* Default behavior is to return javascript */
1188 cgi_set_content_type("application/javascript");
1189 }
1190 style_init_th1_vars(0);
1191 Th_Render(zScript?zScript:"");
1192 }
1193
1194
1195 DDED src/style.pikchrshow.css
--- src/style.c
+++ src/style.c
@@ -749,11 +749,11 @@
749 /*
750 ** Initialize all the default TH1 variables
751 */
752 static void style_init_th1_vars(const char *zTitle){
753 const char *zNonce = style_nonce();
754 char *zDfltCsp;
755
756 zDfltCsp = style_csp(1);
757 /*
758 ** Do not overwrite the TH1 variable "default_csp" if it exists, as this
759 ** allows it to be properly overridden via the TH1 setup script (i.e. it
@@ -769,15 +769,17 @@
769 Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
770 Th_Store("home", g.zTop);
771 Th_Store("index_page", db_get("index-page","/home"));
772 if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath);
773 Th_Store("current_page", local_zCurrentPage);
774 if( g.zPath ){ /* store the first segment of a path; */
775 char *pSlash = strchr(g.zPath,'/');
776 if( pSlash ) *pSlash = 0; /* make a temporary cut if necessary */
777 Th_Store("requested_page", escape_quotes(g.zPath));
778 if( pSlash ) *pSlash = '/';
779 }else{
780 Th_Store("requested_page", "");
781 }
782 Th_Store("canonical_page", escape_quotes(g.zPhase+1));
783 Th_Store("csrf_token", g.zCsrfToken);
784 Th_Store("release_version", RELEASE_VERSION);
785 Th_Store("manifest_version", MANIFEST_VERSION);
@@ -899,11 +901,11 @@
901 static void style_load_all_js_files(void){
902 if( needHrefJs && g.perm.Hyperlink ){
903 int nDelay = db_get_int("auto-hyperlink-delay",0);
904 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
905 && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
906 @ <script id='href-data' type='text/json'>\
907 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
908 }
909 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
910 @ function debugMsg(msg){
911 @ var n = document.getElementById("debugMsg");
@@ -919,10 +921,41 @@
921 cgi_append_content("\n}\n", -1);
922 }
923 @ </script>
924 builtin_fulfill_js_requests();
925 }
926
927 /*
928 ** Transorm input string into a token that is safe for inclusion into
929 ** class attribute. Digits and low-case letter are passed unchanged,
930 ** upper-case letters are transformed to low-case, everything else is
931 ** tranformed into hyphens; consequtive and pending hyphens are squeezed.
932 ** If result does not fit into szOut chars then it is truncated.
933 ** Result is always terminated with null.
934 */
935 void style_derive_classname(const char *zIn, char *zOut, int szOut){
936 assert( zOut );
937 assert( szOut>0 );
938 if( zIn ){
939 int n = 0; /* number of chars written to zOut */
940 char c;
941 for(--szOut; (c=*zIn) && n<szOut; zIn++) {
942 if( ('a'<=c && c<='z') || ('0'<=c && c<='9') ){
943 *zOut = c;
944 }else if( 'A'<=c && c<='Z' ){
945 *zOut = c - 'A' + 'a';
946 }else{
947 if( n==0 || zOut[-1]=='-' ) continue;
948 *zOut = '-';
949 }
950 zOut++;
951 n++;
952 }
953 if( n && zOut[-1]=='-' ) zOut--;
954 }
955 *zOut = 0;
956 }
957
958 /*
959 ** Invoke this routine after all of the content for a webpage has been
960 ** generated. This routine should be called once for every webpage, at
961 ** or near the end of page generation. This routine does the following:
@@ -948,10 +981,11 @@
981 ** to the submenu while generating page text.
982 */
983 cgi_destination(CGI_HEADER);
984 if( submenuEnable && nSubmenu+nSubmenuCtrl>0 ){
985 int i;
986 char zClass[32]; /* reduced form of the main attribute */
987 if( nSubmenuCtrl ){
988 @ <form id='f01' method='GET' action='%R/%s(g.zPath)'>
989 @ <input type='hidden' name='udc' value='1'>
990 cgi_tag_query_parameter("udc");
991 }
@@ -958,33 +992,36 @@
992 @ <div class="submenu">
993 if( nSubmenu>0 ){
994 qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
995 for(i=0; i<nSubmenu; i++){
996 struct Submenu *p = &aSubmenu[i];
997 style_derive_classname(p->zLabel, zClass, sizeof zClass);
998 /* switching away from the %h formatting below might be dangerous
999 ** because some places use %s to compose zLabel and zLink;
1000 ** e.g. /rptview page. "sml" stands for submenu link.
1001 */
1002 if( p->zLink==0 ){
1003 @ <span class="label sml-%s(zClass)">%h(p->zLabel)</span>
1004 }else{
1005 @ <a class="label sml-%s(zClass)" href="%h(p->zLink)">%h(p->zLabel)</a>
1006 }
1007 }
1008 }
1009 strcpy(zClass,"smc-"); /* common prefix for submenu controls */
1010 for(i=0; i<nSubmenuCtrl; i++){
1011 const char *zQPN = aSubmenuCtrl[i].zName;
1012 const char *zDisabled = "";
1013 const char *zXtraClass = "";
1014 if( aSubmenuCtrl[i].eVisible & STYLE_DISABLED ){
1015 zDisabled = " disabled";
1016 }else if( zQPN ){
1017 cgi_tag_query_parameter(zQPN);
1018 }
1019 style_derive_classname(zQPN, zClass+4, sizeof(zClass)-4);
1020 switch( aSubmenuCtrl[i].eType ){
1021 case FF_ENTRY:
1022 @ <span class='submenuctrl%s(zXtraClass) %s(zClass)'>\
1023 @ &nbsp;%h(aSubmenuCtrl[i].zLabel)\
1024 @ <input type='text' name='%s(zQPN)' value='%h(PD(zQPN, ""))' \
1025 if( aSubmenuCtrl[i].iSize<0 ){
1026 @ size='%d(-aSubmenuCtrl[i].iSize)' \
1027 }else if( aSubmenuCtrl[i].iSize>0 ){
@@ -995,16 +1032,16 @@
1032 break;
1033 case FF_MULTI: {
1034 int j;
1035 const char *zVal = P(zQPN);
1036 if( zXtraClass[0] ){
1037 @ <span class='%s(zXtraClass+1) %s(zClass)'>
1038 }
1039 if( aSubmenuCtrl[i].zLabel ){
1040 @ &nbsp;%h(aSubmenuCtrl[i].zLabel)\
1041 }
1042 @ <select class='submenuctrl %s(zClass)' size='1' name='%s(zQPN)' \
1043 @ id='submenuctrl-%d(i)'%s(zDisabled)>
1044 for(j=0; j<aSubmenuCtrl[i].iSize*2; j+=2){
1045 const char *zQPV = aSubmenuCtrl[i].azChoice[j];
1046 @ <option value='%h(zQPV)'\
1047 if( fossil_strcmp(zVal, zQPV)==0 ){
@@ -1034,11 +1071,11 @@
1071 @ >%h(aSubmenuCtrl[i].zFalse)</option>
1072 @ </select>
1073 break;
1074 }
1075 case FF_CHECKBOX: {
1076 @ <label class='submenuctrl submenuckbox%s(zXtraClass) %s(zClass)'>\
1077 @ <input type='checkbox' name='%s(zQPN)' id='submenuctrl-%d(i)' \
1078 if( PB(zQPN) ){
1079 @ checked \
1080 }
1081 if( aSubmenuCtrl[i].zJS ){
@@ -1183,11 +1220,11 @@
1220 /* Render the script as plain-text for testing purposes, if the "test"
1221 ** query parameter is present */
1222 cgi_set_content_type("text/plain");
1223 }else{
1224 /* Default behavior is to return javascript */
1225 cgi_set_content_type("text/javascript");
1226 }
1227 style_init_th1_vars(0);
1228 Th_Render(zScript?zScript:"");
1229 }
1230
1231
1232 DDED src/style.pikchrshow.css
--- a/src/style.pikchrshow.css
+++ b/src/style.pikchrshow.css
@@ -0,0 +1,91 @@
1
+ during the module load/initialization processes... */
2
+.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
3
+div.emscripten { text-align: center; }
4
+div.emscripten_border { border: 1px solid black; }
5
+#module-spinner { overflow: visible; }
6
+#module-spinner > * {
7
+ margin-top: 1em;
8
+}
9
+.spinner {
10
+ height: 50px;
11
+ width: 50px;
12
+ margin: 0px auto;
13
+ animation: rotation 0.8s linear infinite;
14
+ border-left: 10px solid rgb(0,150,240);
15
+ border-right: 10px solid rgb(0,150,240);
16
+ border-bottom: 10px solid rgb(0,150,240);
17
+ border-top: 10px solid rgb(100,0,200);
18
+ border-radius: 100%;
19
+ background-color: rgb(200,100,250);
20
+}
21
+@keyframes rotation {
22
+ from {transform: rotate(0deg);}
23
+ to {transform: rotate(360deg);}
24
+}
25
+
26
+/* The following styles are for app-level use. */
27
+/* TODO: consolidate the WASM- and legacy-mode CSS into this file.
28
+ Since both versions of /pikchrshow share a URI, they both load this
29
+ file. */
30
+textarea {
31
+ font-family: monospace;
32
+ flex: 1 1 auto;
33
+}
34
+#main-wrapper {
35
+ display: flex;
36
+ flex-direction: column-reverse;
37
+ flex: 1 1 auto;
38
+ margin: 0.5em 0;
39
+ overflow: hidden;
40
+}
41
+#main-wrapper.side-by-side {
42
+ flex-direction: row;
43
+}
44
+#main-wrapper.side-by-side > fieldset {
45
+ margin-left: 0.25em;
46
+ margin-right: 0.25em;
47
+}
48
+#main-wrapper:not(.side-by-side) > fieldset {
49
+ margin-bottom: 0.25em;
50
+}
51
+#main-wrapper.swapio {
52
+ flex-direction: column;
53
+}
54
+#main-wrapper.side-by-side.swapio {
55
+ flex-direction: row-reverse;
56
+}
57
+.zone-wrapper{
58
+ display: flex;
59
+ margin: 0;
60
+ flex: 1 1 0%;
61
+ border-radius: 0.5em;
62
+ min-width: inherit/*important: resolves inability to scroll fieldset child element!*/;
63
+ padding: 0.35em 0 0 0;
64
+}
65
+.zone-wrapper > div {
66
+ display:flex;
67
+ flex: 1 1 0%;
68
+}
69
+.zone-wrapper.output {
70
+}
71
+#main-wrapper.side-by-side .zone-wrapper {
72
+ /* Keep the layout from "flopping around" when
73
+ render-while-typing mode is on. */
74
+ /*max-width: 50%;*/
75
+}
76
+#pikchr-output {
77
+ padding: 0;
78
+ margin: 0 auto/*auto resolves a weird left-shift truncation of the SVG*/;
79
+}
80
+#pikchr-output-wrapper {
81
+ flex: 1 1 auto;
82
+ overflow: auto;
83
+}
84
+#pikchr-output-wrapper.text {
85
+ display: flex;
86
+ align-items: stretch;
87
+}
88
+#pikchr-output-wrapper.text > #pikchr-output {
89
+ display: flex;
90
+ align-items: stretch;
91
+ fle
--- a/src/style.pikchrshow.css
+++ b/src/style.pikchrshow.css
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/style.pikchrshow.css
+++ b/src/style.pikchrshow.css
@@ -0,0 +1,91 @@
1 during the module load/initialization processes... */
2 .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
3 div.emscripten { text-align: center; }
4 div.emscripten_border { border: 1px solid black; }
5 #module-spinner { overflow: visible; }
6 #module-spinner > * {
7 margin-top: 1em;
8 }
9 .spinner {
10 height: 50px;
11 width: 50px;
12 margin: 0px auto;
13 animation: rotation 0.8s linear infinite;
14 border-left: 10px solid rgb(0,150,240);
15 border-right: 10px solid rgb(0,150,240);
16 border-bottom: 10px solid rgb(0,150,240);
17 border-top: 10px solid rgb(100,0,200);
18 border-radius: 100%;
19 background-color: rgb(200,100,250);
20 }
21 @keyframes rotation {
22 from {transform: rotate(0deg);}
23 to {transform: rotate(360deg);}
24 }
25
26 /* The following styles are for app-level use. */
27 /* TODO: consolidate the WASM- and legacy-mode CSS into this file.
28 Since both versions of /pikchrshow share a URI, they both load this
29 file. */
30 textarea {
31 font-family: monospace;
32 flex: 1 1 auto;
33 }
34 #main-wrapper {
35 display: flex;
36 flex-direction: column-reverse;
37 flex: 1 1 auto;
38 margin: 0.5em 0;
39 overflow: hidden;
40 }
41 #main-wrapper.side-by-side {
42 flex-direction: row;
43 }
44 #main-wrapper.side-by-side > fieldset {
45 margin-left: 0.25em;
46 margin-right: 0.25em;
47 }
48 #main-wrapper:not(.side-by-side) > fieldset {
49 margin-bottom: 0.25em;
50 }
51 #main-wrapper.swapio {
52 flex-direction: column;
53 }
54 #main-wrapper.side-by-side.swapio {
55 flex-direction: row-reverse;
56 }
57 .zone-wrapper{
58 display: flex;
59 margin: 0;
60 flex: 1 1 0%;
61 border-radius: 0.5em;
62 min-width: inherit/*important: resolves inability to scroll fieldset child element!*/;
63 padding: 0.35em 0 0 0;
64 }
65 .zone-wrapper > div {
66 display:flex;
67 flex: 1 1 0%;
68 }
69 .zone-wrapper.output {
70 }
71 #main-wrapper.side-by-side .zone-wrapper {
72 /* Keep the layout from "flopping around" when
73 render-while-typing mode is on. */
74 /*max-width: 50%;*/
75 }
76 #pikchr-output {
77 padding: 0;
78 margin: 0 auto/*auto resolves a weird left-shift truncation of the SVG*/;
79 }
80 #pikchr-output-wrapper {
81 flex: 1 1 auto;
82 overflow: auto;
83 }
84 #pikchr-output-wrapper.text {
85 display: flex;
86 align-items: stretch;
87 }
88 #pikchr-output-wrapper.text > #pikchr-output {
89 display: flex;
90 align-items: stretch;
91 fle
+1 -1
--- src/tag.c
+++ src/tag.c
@@ -220,11 +220,11 @@
220220
if( zCol ){
221221
db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
222222
zCol, zValue, rid);
223223
if( tagid==TAG_COMMENT ){
224224
char *zCopy = mprintf("%s", zValue);
225
- backlink_extract(zCopy, 0, rid, BKLNK_COMMENT, mtime, 1);
225
+ backlink_extract(zCopy, MT_NONE, rid, BKLNK_COMMENT, mtime, 1);
226226
free(zCopy);
227227
}
228228
}
229229
if( tagid==TAG_DATE ){
230230
db_multi_exec("UPDATE event "
231231
--- src/tag.c
+++ src/tag.c
@@ -220,11 +220,11 @@
220 if( zCol ){
221 db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
222 zCol, zValue, rid);
223 if( tagid==TAG_COMMENT ){
224 char *zCopy = mprintf("%s", zValue);
225 backlink_extract(zCopy, 0, rid, BKLNK_COMMENT, mtime, 1);
226 free(zCopy);
227 }
228 }
229 if( tagid==TAG_DATE ){
230 db_multi_exec("UPDATE event "
231
--- src/tag.c
+++ src/tag.c
@@ -220,11 +220,11 @@
220 if( zCol ){
221 db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
222 zCol, zValue, rid);
223 if( tagid==TAG_COMMENT ){
224 char *zCopy = mprintf("%s", zValue);
225 backlink_extract(zCopy, MT_NONE, rid, BKLNK_COMMENT, mtime, 1);
226 free(zCopy);
227 }
228 }
229 if( tagid==TAG_DATE ){
230 db_multi_exec("UPDATE event "
231
+90 -35
--- src/tkt.c
+++ src/tkt.c
@@ -23,11 +23,11 @@
2323
#include <assert.h>
2424
2525
/*
2626
** The list of database user-defined fields in the TICKET table.
2727
** The real table also contains some addition fields for internal
28
-** used. The internal-use fields begin with "tkt_".
28
+** use. The internal-use fields begin with "tkt_".
2929
*/
3030
static int nField = 0;
3131
static struct tktFieldInfo {
3232
char *zName; /* Name of the database field */
3333
char *zValue; /* Value to store */
@@ -39,10 +39,14 @@
3939
#define USEDBY_BOTH 03
4040
static u8 haveTicket = 0; /* True if the TICKET table exists */
4141
static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
4242
static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
4343
static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
44
+static u8 haveTicketChngUser = 0;/* True if TICKETCHNG.TKT_USER exists */
45
+static u8 useTicketGenMt = 0; /* use generated TICKET.MIMETYPE */
46
+static u8 useTicketChngGenMt = 0;/* use generated TICKETCHNG.MIMETYPE */
47
+
4448
4549
/*
4650
** Compare two entries in aField[] for sorting purposes
4751
*/
4852
static int nameCmpr(const void *a, const void *b){
@@ -69,11 +73,11 @@
6973
** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
7074
** TICKETCHANGE tables exist, respectively.
7175
*/
7276
static void getAllTicketFields(void){
7377
Stmt q;
74
- int i;
78
+ int i, noRegularMimetype;
7579
static int once = 0;
7680
if( once ) return;
7781
once = 1;
7882
db_prepare(&q, "PRAGMA table_info(ticket)");
7983
while( db_step(&q)==SQLITE_ROW ){
@@ -81,10 +85,11 @@
8185
haveTicket = 1;
8286
if( memcmp(zFieldName,"tkt_",4)==0 ){
8387
if( strcmp(zFieldName, "tkt_ctime")==0 ) haveTicketCTime = 1;
8488
continue;
8589
}
90
+ if( strchr(zFieldName,' ')!=0 ) continue;
8691
if( nField%10==0 ){
8792
aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
8893
}
8994
aField[nField].zName = mprintf("%s", zFieldName);
9095
aField[nField].mUsed = USEDBY_TICKET;
@@ -94,13 +99,18 @@
9499
db_prepare(&q, "PRAGMA table_info(ticketchng)");
95100
while( db_step(&q)==SQLITE_ROW ){
96101
const char *zFieldName = db_column_text(&q, 1);
97102
haveTicketChng = 1;
98103
if( memcmp(zFieldName,"tkt_",4)==0 ){
99
- if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
104
+ if( strcmp(zFieldName+4,"rid")==0 ){
105
+ haveTicketChngRid = 1; /* tkt_rid */
106
+ }else if( strcmp(zFieldName+4,"user")==0 ){
107
+ haveTicketChngUser = 1; /* tkt_user */
108
+ }
100109
continue;
101110
}
111
+ if( strchr(zFieldName,' ')!=0 ) continue;
102112
if( (i = fieldId(zFieldName))>=0 ){
103113
aField[i].mUsed |= USEDBY_TICKETCHNG;
104114
continue;
105115
}
106116
if( nField%10==0 ){
@@ -110,13 +120,25 @@
110120
aField[nField].mUsed = USEDBY_TICKETCHNG;
111121
nField++;
112122
}
113123
db_finalize(&q);
114124
qsort(aField, nField, sizeof(aField[0]), nameCmpr);
125
+ noRegularMimetype = 1;
115126
for(i=0; i<nField; i++){
116127
aField[i].zValue = "";
117128
aField[i].zAppend = 0;
129
+ if( strcmp(aField[i].zName,"mimetype")==0 ){
130
+ noRegularMimetype = 0;
131
+ }
132
+ }
133
+ if( noRegularMimetype ){ /* check for generated "mimetype" columns */
134
+ useTicketGenMt = db_exists(
135
+ "SELECT 1 FROM pragma_table_xinfo('ticket') "
136
+ "WHERE name = 'mimetype'");
137
+ useTicketChngGenMt = db_exists(
138
+ "SELECT 1 FROM pragma_table_xinfo('ticketchng') "
139
+ "WHERE name = 'mimetype'");
118140
}
119141
}
120142
121143
/*
122144
** Query the database for all TICKET fields for the specific
@@ -189,16 +211,18 @@
189211
**
190212
** Parameter rid is the recordID for the ticket artifact in the BLOB table.
191213
**
192214
** Return the new rowid of the TICKET table entry.
193215
*/
194
-static int ticket_insert(const Manifest *p, int rid, int tktid){
195
- Blob sql1, sql2, sql3;
216
+static int ticket_insert(const Manifest *p, const int rid, int tktid){
217
+ Blob sql1; /* update or replace TICKET ... */
218
+ Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
219
+ Blob sql3; /* list of values which correspond to the previous list */
196220
Stmt q;
197221
int i, j;
198222
char *aUsed;
199
- const char *zMimetype = 0;
223
+ int mimetype_tkt = MT_NONE, mimetype_tktchng = MT_NONE;
200224
201225
if( tktid==0 ){
202226
db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
203227
"VALUES(%Q, 0)", p->zTicketUuid);
204228
tktid = db_last_insert_rowid();
@@ -211,59 +235,60 @@
211235
blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
212236
}
213237
aUsed = fossil_malloc( nField );
214238
memset(aUsed, 0, nField);
215239
for(i=0; i<p->nField; i++){
216
- const char *zName = p->aField[i].zName;
217
- const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
240
+ const char * const zName = p->aField[i].zName;
241
+ const char * const zBaseName = zName[0]=='+' ? zName+1 : zName;
218242
j = fieldId(zBaseName);
219243
if( j<0 ) continue;
220244
aUsed[j] = 1;
221245
if( aField[j].mUsed & USEDBY_TICKET ){
222
- const char *zUsedByName = zName;
223
- if( zUsedByName[0]=='+' ){
224
- zUsedByName++;
246
+ if( zName[0]=='+' ){
225247
blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
226
- zUsedByName, zUsedByName, p->aField[i].zValue);
248
+ zBaseName, zBaseName, p->aField[i].zValue);
227249
}else{
228
- blob_append_sql(&sql1,", \"%w\"=%Q", zUsedByName, p->aField[i].zValue);
250
+ blob_append_sql(&sql1,", \"%w\"=%Q", zBaseName, p->aField[i].zValue);
229251
}
230252
}
231253
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
232
- const char *zUsedByName = zName;
233
- if( zUsedByName[0]=='+' ){
234
- zUsedByName++;
235
- }
236
- blob_append_sql(&sql2, ",\"%w\"", zUsedByName);
254
+ blob_append_sql(&sql2, ",\"%w\"", zBaseName);
237255
blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
238256
}
239257
if( strcmp(zBaseName,"mimetype")==0 ){
240
- zMimetype = p->aField[i].zValue;
241
- }
242
- }
243
- if( rid>0 ){
244
- for(i=0; i<p->nField; i++){
245
- const char *zName = p->aField[i].zName;
246
- const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
247
- j = fieldId(zBaseName);
248
- if( j<0 ) continue;
249
- backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
250
- p->rDate, i==0);
258
+ const char *zMimetype = p->aField[i].zValue;
259
+ /* "mimetype" is a regular column => these two flags must be 0 */
260
+ assert(!useTicketGenMt);
261
+ assert(!useTicketChngGenMt);
262
+ mimetype_tkt = mimetype_tktchng = parse_mimetype( zMimetype );
251263
}
252264
}
253265
blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
266
+ if( useTicketGenMt ){
267
+ blob_append_literal(&sql1, " RETURNING mimetype");
268
+ }
254269
db_prepare(&q, "%s", blob_sql_text(&sql1));
255270
db_bind_double(&q, ":mtime", p->rDate);
256271
db_step(&q);
272
+ if( useTicketGenMt ){
273
+ mimetype_tkt = parse_mimetype( db_column_text(&q,0) );
274
+ if( !useTicketChngGenMt ){
275
+ mimetype_tktchng = mimetype_tkt;
276
+ }
277
+ }
257278
db_finalize(&q);
258279
blob_reset(&sql1);
259
- if( blob_size(&sql2)>0 || haveTicketChngRid ){
280
+ if( blob_size(&sql2)>0 || haveTicketChngRid || haveTicketChngUser ){
260281
int fromTkt = 0;
261282
if( haveTicketChngRid ){
262
- blob_append(&sql2, ",tkt_rid", -1);
283
+ blob_append_literal(&sql2, ",tkt_rid");
263284
blob_append_sql(&sql3, ",%d", rid);
264285
}
286
+ if( haveTicketChngUser && p->zUser ){
287
+ blob_append_literal(&sql2, ",tkt_user");
288
+ blob_append_sql(&sql3, ",%Q", p->zUser);
289
+ }
265290
for(i=0; i<nField; i++){
266291
if( aUsed[i]==0
267292
&& (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
268293
){
269294
const char *z = aField[i].zName;
@@ -273,25 +298,55 @@
273298
blob_append_sql(&sql3, ",\"%w\"", z);
274299
}
275300
}
276301
if( fromTkt ){
277302
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
278
- "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
303
+ "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d%s",
279304
blob_sql_text(&sql2), tktid,
280
- blob_sql_text(&sql3), tktid);
305
+ blob_sql_text(&sql3), tktid,
306
+ useTicketChngGenMt ? " RETURNING mimetype" : "");
281307
}else{
282308
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
283
- "VALUES(%d,:mtime%s)",
284
- blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
309
+ "VALUES(%d,:mtime%s)%s",
310
+ blob_sql_text(&sql2), tktid, blob_sql_text(&sql3),
311
+ useTicketChngGenMt ? " RETURNING mimetype" : "");
285312
}
286313
db_bind_double(&q, ":mtime", p->rDate);
287314
db_step(&q);
315
+ if( useTicketChngGenMt ){
316
+ mimetype_tktchng = parse_mimetype( db_column_text(&q, 0) );
317
+ /* substitute NULL with a value generated within another table */
318
+ if( !useTicketGenMt ){
319
+ mimetype_tkt = mimetype_tktchng;
320
+ }else if( mimetype_tktchng==MT_NONE ){
321
+ mimetype_tktchng = mimetype_tkt;
322
+ }else if( mimetype_tkt==MT_NONE ){
323
+ mimetype_tkt = mimetype_tktchng;
324
+ }
325
+ }
288326
db_finalize(&q);
289327
}
290328
blob_reset(&sql2);
291329
blob_reset(&sql3);
292330
fossil_free(aUsed);
331
+ if( rid>0 ){ /* extract backlinks */
332
+ int bReplace = 1, mimetype;
333
+ for(i=0; i<p->nField; i++){
334
+ const char *zName = p->aField[i].zName;
335
+ const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
336
+ j = fieldId(zBaseName);
337
+ if( j<0 ) continue;
338
+ if( aField[j].mUsed & USEDBY_TICKETCHNG ){
339
+ mimetype = mimetype_tktchng;
340
+ }else{
341
+ mimetype = mimetype_tkt;
342
+ }
343
+ backlink_extract(p->aField[i].zValue, mimetype, rid, BKLNK_TICKET,
344
+ p->rDate, bReplace);
345
+ bReplace = 0;
346
+ }
347
+ }
293348
return tktid;
294349
}
295350
296351
/*
297352
** Returns non-zero if moderation is required for ticket changes and ticket
298353
--- src/tkt.c
+++ src/tkt.c
@@ -23,11 +23,11 @@
23 #include <assert.h>
24
25 /*
26 ** The list of database user-defined fields in the TICKET table.
27 ** The real table also contains some addition fields for internal
28 ** used. The internal-use fields begin with "tkt_".
29 */
30 static int nField = 0;
31 static struct tktFieldInfo {
32 char *zName; /* Name of the database field */
33 char *zValue; /* Value to store */
@@ -39,10 +39,14 @@
39 #define USEDBY_BOTH 03
40 static u8 haveTicket = 0; /* True if the TICKET table exists */
41 static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
42 static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
43 static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
 
 
 
 
44
45 /*
46 ** Compare two entries in aField[] for sorting purposes
47 */
48 static int nameCmpr(const void *a, const void *b){
@@ -69,11 +73,11 @@
69 ** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
70 ** TICKETCHANGE tables exist, respectively.
71 */
72 static void getAllTicketFields(void){
73 Stmt q;
74 int i;
75 static int once = 0;
76 if( once ) return;
77 once = 1;
78 db_prepare(&q, "PRAGMA table_info(ticket)");
79 while( db_step(&q)==SQLITE_ROW ){
@@ -81,10 +85,11 @@
81 haveTicket = 1;
82 if( memcmp(zFieldName,"tkt_",4)==0 ){
83 if( strcmp(zFieldName, "tkt_ctime")==0 ) haveTicketCTime = 1;
84 continue;
85 }
 
86 if( nField%10==0 ){
87 aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
88 }
89 aField[nField].zName = mprintf("%s", zFieldName);
90 aField[nField].mUsed = USEDBY_TICKET;
@@ -94,13 +99,18 @@
94 db_prepare(&q, "PRAGMA table_info(ticketchng)");
95 while( db_step(&q)==SQLITE_ROW ){
96 const char *zFieldName = db_column_text(&q, 1);
97 haveTicketChng = 1;
98 if( memcmp(zFieldName,"tkt_",4)==0 ){
99 if( strcmp(zFieldName,"tkt_rid")==0 ) haveTicketChngRid = 1;
 
 
 
 
100 continue;
101 }
 
102 if( (i = fieldId(zFieldName))>=0 ){
103 aField[i].mUsed |= USEDBY_TICKETCHNG;
104 continue;
105 }
106 if( nField%10==0 ){
@@ -110,13 +120,25 @@
110 aField[nField].mUsed = USEDBY_TICKETCHNG;
111 nField++;
112 }
113 db_finalize(&q);
114 qsort(aField, nField, sizeof(aField[0]), nameCmpr);
 
115 for(i=0; i<nField; i++){
116 aField[i].zValue = "";
117 aField[i].zAppend = 0;
 
 
 
 
 
 
 
 
 
 
 
118 }
119 }
120
121 /*
122 ** Query the database for all TICKET fields for the specific
@@ -189,16 +211,18 @@
189 **
190 ** Parameter rid is the recordID for the ticket artifact in the BLOB table.
191 **
192 ** Return the new rowid of the TICKET table entry.
193 */
194 static int ticket_insert(const Manifest *p, int rid, int tktid){
195 Blob sql1, sql2, sql3;
 
 
196 Stmt q;
197 int i, j;
198 char *aUsed;
199 const char *zMimetype = 0;
200
201 if( tktid==0 ){
202 db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
203 "VALUES(%Q, 0)", p->zTicketUuid);
204 tktid = db_last_insert_rowid();
@@ -211,59 +235,60 @@
211 blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
212 }
213 aUsed = fossil_malloc( nField );
214 memset(aUsed, 0, nField);
215 for(i=0; i<p->nField; i++){
216 const char *zName = p->aField[i].zName;
217 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
218 j = fieldId(zBaseName);
219 if( j<0 ) continue;
220 aUsed[j] = 1;
221 if( aField[j].mUsed & USEDBY_TICKET ){
222 const char *zUsedByName = zName;
223 if( zUsedByName[0]=='+' ){
224 zUsedByName++;
225 blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
226 zUsedByName, zUsedByName, p->aField[i].zValue);
227 }else{
228 blob_append_sql(&sql1,", \"%w\"=%Q", zUsedByName, p->aField[i].zValue);
229 }
230 }
231 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
232 const char *zUsedByName = zName;
233 if( zUsedByName[0]=='+' ){
234 zUsedByName++;
235 }
236 blob_append_sql(&sql2, ",\"%w\"", zUsedByName);
237 blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
238 }
239 if( strcmp(zBaseName,"mimetype")==0 ){
240 zMimetype = p->aField[i].zValue;
241 }
242 }
243 if( rid>0 ){
244 for(i=0; i<p->nField; i++){
245 const char *zName = p->aField[i].zName;
246 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
247 j = fieldId(zBaseName);
248 if( j<0 ) continue;
249 backlink_extract(p->aField[i].zValue, zMimetype, rid, BKLNK_TICKET,
250 p->rDate, i==0);
251 }
252 }
253 blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
 
 
 
254 db_prepare(&q, "%s", blob_sql_text(&sql1));
255 db_bind_double(&q, ":mtime", p->rDate);
256 db_step(&q);
 
 
 
 
 
 
257 db_finalize(&q);
258 blob_reset(&sql1);
259 if( blob_size(&sql2)>0 || haveTicketChngRid ){
260 int fromTkt = 0;
261 if( haveTicketChngRid ){
262 blob_append(&sql2, ",tkt_rid", -1);
263 blob_append_sql(&sql3, ",%d", rid);
264 }
 
 
 
 
265 for(i=0; i<nField; i++){
266 if( aUsed[i]==0
267 && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
268 ){
269 const char *z = aField[i].zName;
@@ -273,25 +298,55 @@
273 blob_append_sql(&sql3, ",\"%w\"", z);
274 }
275 }
276 if( fromTkt ){
277 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
278 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
279 blob_sql_text(&sql2), tktid,
280 blob_sql_text(&sql3), tktid);
 
281 }else{
282 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
283 "VALUES(%d,:mtime%s)",
284 blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
 
285 }
286 db_bind_double(&q, ":mtime", p->rDate);
287 db_step(&q);
 
 
 
 
 
 
 
 
 
 
 
288 db_finalize(&q);
289 }
290 blob_reset(&sql2);
291 blob_reset(&sql3);
292 fossil_free(aUsed);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293 return tktid;
294 }
295
296 /*
297 ** Returns non-zero if moderation is required for ticket changes and ticket
298
--- src/tkt.c
+++ src/tkt.c
@@ -23,11 +23,11 @@
23 #include <assert.h>
24
25 /*
26 ** The list of database user-defined fields in the TICKET table.
27 ** The real table also contains some addition fields for internal
28 ** use. The internal-use fields begin with "tkt_".
29 */
30 static int nField = 0;
31 static struct tktFieldInfo {
32 char *zName; /* Name of the database field */
33 char *zValue; /* Value to store */
@@ -39,10 +39,14 @@
39 #define USEDBY_BOTH 03
40 static u8 haveTicket = 0; /* True if the TICKET table exists */
41 static u8 haveTicketCTime = 0; /* True if TICKET.TKT_CTIME exists */
42 static u8 haveTicketChng = 0; /* True if the TICKETCHNG table exists */
43 static u8 haveTicketChngRid = 0; /* True if TICKETCHNG.TKT_RID exists */
44 static u8 haveTicketChngUser = 0;/* True if TICKETCHNG.TKT_USER exists */
45 static u8 useTicketGenMt = 0; /* use generated TICKET.MIMETYPE */
46 static u8 useTicketChngGenMt = 0;/* use generated TICKETCHNG.MIMETYPE */
47
48
49 /*
50 ** Compare two entries in aField[] for sorting purposes
51 */
52 static int nameCmpr(const void *a, const void *b){
@@ -69,11 +73,11 @@
73 ** The haveTicket and haveTicketChng variables are set to 1 if the TICKET and
74 ** TICKETCHANGE tables exist, respectively.
75 */
76 static void getAllTicketFields(void){
77 Stmt q;
78 int i, noRegularMimetype;
79 static int once = 0;
80 if( once ) return;
81 once = 1;
82 db_prepare(&q, "PRAGMA table_info(ticket)");
83 while( db_step(&q)==SQLITE_ROW ){
@@ -81,10 +85,11 @@
85 haveTicket = 1;
86 if( memcmp(zFieldName,"tkt_",4)==0 ){
87 if( strcmp(zFieldName, "tkt_ctime")==0 ) haveTicketCTime = 1;
88 continue;
89 }
90 if( strchr(zFieldName,' ')!=0 ) continue;
91 if( nField%10==0 ){
92 aField = fossil_realloc(aField, sizeof(aField[0])*(nField+10) );
93 }
94 aField[nField].zName = mprintf("%s", zFieldName);
95 aField[nField].mUsed = USEDBY_TICKET;
@@ -94,13 +99,18 @@
99 db_prepare(&q, "PRAGMA table_info(ticketchng)");
100 while( db_step(&q)==SQLITE_ROW ){
101 const char *zFieldName = db_column_text(&q, 1);
102 haveTicketChng = 1;
103 if( memcmp(zFieldName,"tkt_",4)==0 ){
104 if( strcmp(zFieldName+4,"rid")==0 ){
105 haveTicketChngRid = 1; /* tkt_rid */
106 }else if( strcmp(zFieldName+4,"user")==0 ){
107 haveTicketChngUser = 1; /* tkt_user */
108 }
109 continue;
110 }
111 if( strchr(zFieldName,' ')!=0 ) continue;
112 if( (i = fieldId(zFieldName))>=0 ){
113 aField[i].mUsed |= USEDBY_TICKETCHNG;
114 continue;
115 }
116 if( nField%10==0 ){
@@ -110,13 +120,25 @@
120 aField[nField].mUsed = USEDBY_TICKETCHNG;
121 nField++;
122 }
123 db_finalize(&q);
124 qsort(aField, nField, sizeof(aField[0]), nameCmpr);
125 noRegularMimetype = 1;
126 for(i=0; i<nField; i++){
127 aField[i].zValue = "";
128 aField[i].zAppend = 0;
129 if( strcmp(aField[i].zName,"mimetype")==0 ){
130 noRegularMimetype = 0;
131 }
132 }
133 if( noRegularMimetype ){ /* check for generated "mimetype" columns */
134 useTicketGenMt = db_exists(
135 "SELECT 1 FROM pragma_table_xinfo('ticket') "
136 "WHERE name = 'mimetype'");
137 useTicketChngGenMt = db_exists(
138 "SELECT 1 FROM pragma_table_xinfo('ticketchng') "
139 "WHERE name = 'mimetype'");
140 }
141 }
142
143 /*
144 ** Query the database for all TICKET fields for the specific
@@ -189,16 +211,18 @@
211 **
212 ** Parameter rid is the recordID for the ticket artifact in the BLOB table.
213 **
214 ** Return the new rowid of the TICKET table entry.
215 */
216 static int ticket_insert(const Manifest *p, const int rid, int tktid){
217 Blob sql1; /* update or replace TICKET ... */
218 Blob sql2; /* list of TICKETCHNG's fields that are in the manifest */
219 Blob sql3; /* list of values which correspond to the previous list */
220 Stmt q;
221 int i, j;
222 char *aUsed;
223 int mimetype_tkt = MT_NONE, mimetype_tktchng = MT_NONE;
224
225 if( tktid==0 ){
226 db_multi_exec("INSERT INTO ticket(tkt_uuid, tkt_mtime) "
227 "VALUES(%Q, 0)", p->zTicketUuid);
228 tktid = db_last_insert_rowid();
@@ -211,59 +235,60 @@
235 blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
236 }
237 aUsed = fossil_malloc( nField );
238 memset(aUsed, 0, nField);
239 for(i=0; i<p->nField; i++){
240 const char * const zName = p->aField[i].zName;
241 const char * const zBaseName = zName[0]=='+' ? zName+1 : zName;
242 j = fieldId(zBaseName);
243 if( j<0 ) continue;
244 aUsed[j] = 1;
245 if( aField[j].mUsed & USEDBY_TICKET ){
246 if( zName[0]=='+' ){
 
 
247 blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
248 zBaseName, zBaseName, p->aField[i].zValue);
249 }else{
250 blob_append_sql(&sql1,", \"%w\"=%Q", zBaseName, p->aField[i].zValue);
251 }
252 }
253 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
254 blob_append_sql(&sql2, ",\"%w\"", zBaseName);
 
 
 
 
255 blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
256 }
257 if( strcmp(zBaseName,"mimetype")==0 ){
258 const char *zMimetype = p->aField[i].zValue;
259 /* "mimetype" is a regular column => these two flags must be 0 */
260 assert(!useTicketGenMt);
261 assert(!useTicketChngGenMt);
262 mimetype_tkt = mimetype_tktchng = parse_mimetype( zMimetype );
 
 
 
 
 
 
263 }
264 }
265 blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
266 if( useTicketGenMt ){
267 blob_append_literal(&sql1, " RETURNING mimetype");
268 }
269 db_prepare(&q, "%s", blob_sql_text(&sql1));
270 db_bind_double(&q, ":mtime", p->rDate);
271 db_step(&q);
272 if( useTicketGenMt ){
273 mimetype_tkt = parse_mimetype( db_column_text(&q,0) );
274 if( !useTicketChngGenMt ){
275 mimetype_tktchng = mimetype_tkt;
276 }
277 }
278 db_finalize(&q);
279 blob_reset(&sql1);
280 if( blob_size(&sql2)>0 || haveTicketChngRid || haveTicketChngUser ){
281 int fromTkt = 0;
282 if( haveTicketChngRid ){
283 blob_append_literal(&sql2, ",tkt_rid");
284 blob_append_sql(&sql3, ",%d", rid);
285 }
286 if( haveTicketChngUser && p->zUser ){
287 blob_append_literal(&sql2, ",tkt_user");
288 blob_append_sql(&sql3, ",%Q", p->zUser);
289 }
290 for(i=0; i<nField; i++){
291 if( aUsed[i]==0
292 && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
293 ){
294 const char *z = aField[i].zName;
@@ -273,25 +298,55 @@
298 blob_append_sql(&sql3, ",\"%w\"", z);
299 }
300 }
301 if( fromTkt ){
302 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
303 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d%s",
304 blob_sql_text(&sql2), tktid,
305 blob_sql_text(&sql3), tktid,
306 useTicketChngGenMt ? " RETURNING mimetype" : "");
307 }else{
308 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
309 "VALUES(%d,:mtime%s)%s",
310 blob_sql_text(&sql2), tktid, blob_sql_text(&sql3),
311 useTicketChngGenMt ? " RETURNING mimetype" : "");
312 }
313 db_bind_double(&q, ":mtime", p->rDate);
314 db_step(&q);
315 if( useTicketChngGenMt ){
316 mimetype_tktchng = parse_mimetype( db_column_text(&q, 0) );
317 /* substitute NULL with a value generated within another table */
318 if( !useTicketGenMt ){
319 mimetype_tkt = mimetype_tktchng;
320 }else if( mimetype_tktchng==MT_NONE ){
321 mimetype_tktchng = mimetype_tkt;
322 }else if( mimetype_tkt==MT_NONE ){
323 mimetype_tkt = mimetype_tktchng;
324 }
325 }
326 db_finalize(&q);
327 }
328 blob_reset(&sql2);
329 blob_reset(&sql3);
330 fossil_free(aUsed);
331 if( rid>0 ){ /* extract backlinks */
332 int bReplace = 1, mimetype;
333 for(i=0; i<p->nField; i++){
334 const char *zName = p->aField[i].zName;
335 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
336 j = fieldId(zBaseName);
337 if( j<0 ) continue;
338 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
339 mimetype = mimetype_tktchng;
340 }else{
341 mimetype = mimetype_tkt;
342 }
343 backlink_extract(p->aField[i].zValue, mimetype, rid, BKLNK_TICKET,
344 p->rDate, bReplace);
345 bReplace = 0;
346 }
347 }
348 return tktid;
349 }
350
351 /*
352 ** Returns non-zero if moderation is required for ticket changes and ticket
353
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -86,10 +86,11 @@
8686
@ CREATE TABLE ticketchng(
8787
@ -- Do not change any column that begins with tkt_
8888
@ tkt_id INTEGER REFERENCES ticket,
8989
@ tkt_rid INTEGER REFERENCES blob,
9090
@ tkt_mtime DATE,
91
+@ tkt_user TEXT,
9192
@ -- Add as many fields as required below this line
9293
@ login TEXT,
9394
@ username TEXT,
9495
@ mimetype TEXT,
9596
@ icomment TEXT
9697
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -86,10 +86,11 @@
86 @ CREATE TABLE ticketchng(
87 @ -- Do not change any column that begins with tkt_
88 @ tkt_id INTEGER REFERENCES ticket,
89 @ tkt_rid INTEGER REFERENCES blob,
90 @ tkt_mtime DATE,
 
91 @ -- Add as many fields as required below this line
92 @ login TEXT,
93 @ username TEXT,
94 @ mimetype TEXT,
95 @ icomment TEXT
96
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -86,10 +86,11 @@
86 @ CREATE TABLE ticketchng(
87 @ -- Do not change any column that begins with tkt_
88 @ tkt_id INTEGER REFERENCES ticket,
89 @ tkt_rid INTEGER REFERENCES blob,
90 @ tkt_mtime DATE,
91 @ tkt_user TEXT,
92 @ -- Add as many fields as required below this line
93 @ login TEXT,
94 @ username TEXT,
95 @ mimetype TEXT,
96 @ icomment TEXT
97
+17 -1
--- src/wiki.c
+++ src/wiki.c
@@ -1917,10 +1917,11 @@
19171917
void wcontent_page(void){
19181918
Stmt q;
19191919
double rNow;
19201920
int showAll = P("all")!=0;
19211921
int showRid = P("showid")!=0;
1922
+ int showCkBr = P("showckbr")!=0;
19221923
19231924
login_check_credentials();
19241925
if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
19251926
style_set_current_feature("wiki");
19261927
style_header("Available Wiki Pages");
@@ -1927,10 +1928,11 @@
19271928
if( showAll ){
19281929
style_submenu_element("Active", "%R/wcontent");
19291930
}else{
19301931
style_submenu_element("All", "%R/wcontent?all=1");
19311932
}
1933
+ style_submenu_checkbox("showckbr", "Show associated wikis", 0, 0);
19321934
wiki_standard_submenu(W_ALL_BUT(W_LIST));
19331935
db_prepare(&q, listAllWikiPages/*works-like:""*/);
19341936
@ <div class="brlist">
19351937
@ <table class='sortable' data-column-types='tKN' data-init-sort='1'>
19361938
@ <thead><tr>
@@ -1954,10 +1956,15 @@
19541956
19551957
if( sqlite3_strglob("checkin/*", zWName)==0 ){
19561958
zWDisplayName = mprintf("%.25s...", zWName);
19571959
}else{
19581960
zWDisplayName = mprintf("%s", zWName);
1961
+ }
1962
+ if( !showCkBr &&
1963
+ (sqlite3_strglob("checkin/*", zWName)==0 ||
1964
+ sqlite3_strglob("branch/*", zWName)==0) ){
1965
+ continue;
19591966
}
19601967
if( wrid==0 ){
19611968
if( !showAll ) continue;
19621969
@ <tr><td data-sortkey="%h(zSort)">\
19631970
@ %z(href("%R/whistory?name=%T",zWName))<s>%h(zWDisplayName)</s></a></td>
@@ -2182,19 +2189,22 @@
21822189
**
21832190
** > fossil wiki list ?OPTIONS?
21842191
** > fossil wiki ls ?OPTIONS?
21852192
**
21862193
** Lists all wiki entries, one per line, ordered
2187
-** case-insensitively by name.
2194
+** case-insensitively by name. Wiki pages associated with
2195
+** check-ins and branches are NOT shown, unless -a is given.
21882196
**
21892197
** Options:
21902198
** --all Include "deleted" pages in output.
21912199
** By default deleted pages are elided.
21922200
** -t|--technote Technotes will be listed instead of
21932201
** pages. The technotes will be in order
21942202
** of timestamp with the most recent
21952203
** first.
2204
+** -a|--show-associated Show wiki pages associated with
2205
+** check-ins and branches.
21962206
** -s|--show-technote-ids The id of the tech note will be listed
21972207
** along side the timestamp. The tech note
21982208
** id will be the first word on each line.
21992209
** This option only applies if the
22002210
** --technote option is also specified.
@@ -2424,10 +2434,11 @@
24242434
}else if(( strncmp(g.argv[2],"list",n)==0 )
24252435
|| ( strncmp(g.argv[2],"ls",n)==0 )){
24262436
Stmt q;
24272437
const int fTechnote = find_option("technote","t",0)!=0;
24282438
const int showIds = find_option("show-technote-ids","s",0)!=0;
2439
+ const int showCkBr = find_option("show-associated","a",0)!=0;
24292440
verify_all_options();
24302441
if (fTechnote==0){
24312442
db_prepare(&q, listAllWikiPages/*works-like:""*/);
24322443
}else{
24332444
db_prepare(&q,
@@ -2442,10 +2453,15 @@
24422453
while( db_step(&q)==SQLITE_ROW ){
24432454
const char *zName = db_column_text(&q, 0);
24442455
const int wrid = db_column_int(&q, 2);
24452456
if(!showAll && !wrid){
24462457
continue;
2458
+ }
2459
+ if( !showCkBr &&
2460
+ (sqlite3_strglob("checkin/*", zName)==0 ||
2461
+ sqlite3_strglob("branch/*", zName)==0) ){
2462
+ continue;
24472463
}
24482464
if( showIds ){
24492465
const char *zUuid = db_column_text(&q, 1);
24502466
fossil_print("%s ",zUuid);
24512467
}
24522468
--- src/wiki.c
+++ src/wiki.c
@@ -1917,10 +1917,11 @@
1917 void wcontent_page(void){
1918 Stmt q;
1919 double rNow;
1920 int showAll = P("all")!=0;
1921 int showRid = P("showid")!=0;
 
1922
1923 login_check_credentials();
1924 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
1925 style_set_current_feature("wiki");
1926 style_header("Available Wiki Pages");
@@ -1927,10 +1928,11 @@
1927 if( showAll ){
1928 style_submenu_element("Active", "%R/wcontent");
1929 }else{
1930 style_submenu_element("All", "%R/wcontent?all=1");
1931 }
 
1932 wiki_standard_submenu(W_ALL_BUT(W_LIST));
1933 db_prepare(&q, listAllWikiPages/*works-like:""*/);
1934 @ <div class="brlist">
1935 @ <table class='sortable' data-column-types='tKN' data-init-sort='1'>
1936 @ <thead><tr>
@@ -1954,10 +1956,15 @@
1954
1955 if( sqlite3_strglob("checkin/*", zWName)==0 ){
1956 zWDisplayName = mprintf("%.25s...", zWName);
1957 }else{
1958 zWDisplayName = mprintf("%s", zWName);
 
 
 
 
 
1959 }
1960 if( wrid==0 ){
1961 if( !showAll ) continue;
1962 @ <tr><td data-sortkey="%h(zSort)">\
1963 @ %z(href("%R/whistory?name=%T",zWName))<s>%h(zWDisplayName)</s></a></td>
@@ -2182,19 +2189,22 @@
2182 **
2183 ** > fossil wiki list ?OPTIONS?
2184 ** > fossil wiki ls ?OPTIONS?
2185 **
2186 ** Lists all wiki entries, one per line, ordered
2187 ** case-insensitively by name.
 
2188 **
2189 ** Options:
2190 ** --all Include "deleted" pages in output.
2191 ** By default deleted pages are elided.
2192 ** -t|--technote Technotes will be listed instead of
2193 ** pages. The technotes will be in order
2194 ** of timestamp with the most recent
2195 ** first.
 
 
2196 ** -s|--show-technote-ids The id of the tech note will be listed
2197 ** along side the timestamp. The tech note
2198 ** id will be the first word on each line.
2199 ** This option only applies if the
2200 ** --technote option is also specified.
@@ -2424,10 +2434,11 @@
2424 }else if(( strncmp(g.argv[2],"list",n)==0 )
2425 || ( strncmp(g.argv[2],"ls",n)==0 )){
2426 Stmt q;
2427 const int fTechnote = find_option("technote","t",0)!=0;
2428 const int showIds = find_option("show-technote-ids","s",0)!=0;
 
2429 verify_all_options();
2430 if (fTechnote==0){
2431 db_prepare(&q, listAllWikiPages/*works-like:""*/);
2432 }else{
2433 db_prepare(&q,
@@ -2442,10 +2453,15 @@
2442 while( db_step(&q)==SQLITE_ROW ){
2443 const char *zName = db_column_text(&q, 0);
2444 const int wrid = db_column_int(&q, 2);
2445 if(!showAll && !wrid){
2446 continue;
 
 
 
 
 
2447 }
2448 if( showIds ){
2449 const char *zUuid = db_column_text(&q, 1);
2450 fossil_print("%s ",zUuid);
2451 }
2452
--- src/wiki.c
+++ src/wiki.c
@@ -1917,10 +1917,11 @@
1917 void wcontent_page(void){
1918 Stmt q;
1919 double rNow;
1920 int showAll = P("all")!=0;
1921 int showRid = P("showid")!=0;
1922 int showCkBr = P("showckbr")!=0;
1923
1924 login_check_credentials();
1925 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
1926 style_set_current_feature("wiki");
1927 style_header("Available Wiki Pages");
@@ -1927,10 +1928,11 @@
1928 if( showAll ){
1929 style_submenu_element("Active", "%R/wcontent");
1930 }else{
1931 style_submenu_element("All", "%R/wcontent?all=1");
1932 }
1933 style_submenu_checkbox("showckbr", "Show associated wikis", 0, 0);
1934 wiki_standard_submenu(W_ALL_BUT(W_LIST));
1935 db_prepare(&q, listAllWikiPages/*works-like:""*/);
1936 @ <div class="brlist">
1937 @ <table class='sortable' data-column-types='tKN' data-init-sort='1'>
1938 @ <thead><tr>
@@ -1954,10 +1956,15 @@
1956
1957 if( sqlite3_strglob("checkin/*", zWName)==0 ){
1958 zWDisplayName = mprintf("%.25s...", zWName);
1959 }else{
1960 zWDisplayName = mprintf("%s", zWName);
1961 }
1962 if( !showCkBr &&
1963 (sqlite3_strglob("checkin/*", zWName)==0 ||
1964 sqlite3_strglob("branch/*", zWName)==0) ){
1965 continue;
1966 }
1967 if( wrid==0 ){
1968 if( !showAll ) continue;
1969 @ <tr><td data-sortkey="%h(zSort)">\
1970 @ %z(href("%R/whistory?name=%T",zWName))<s>%h(zWDisplayName)</s></a></td>
@@ -2182,19 +2189,22 @@
2189 **
2190 ** > fossil wiki list ?OPTIONS?
2191 ** > fossil wiki ls ?OPTIONS?
2192 **
2193 ** Lists all wiki entries, one per line, ordered
2194 ** case-insensitively by name. Wiki pages associated with
2195 ** check-ins and branches are NOT shown, unless -a is given.
2196 **
2197 ** Options:
2198 ** --all Include "deleted" pages in output.
2199 ** By default deleted pages are elided.
2200 ** -t|--technote Technotes will be listed instead of
2201 ** pages. The technotes will be in order
2202 ** of timestamp with the most recent
2203 ** first.
2204 ** -a|--show-associated Show wiki pages associated with
2205 ** check-ins and branches.
2206 ** -s|--show-technote-ids The id of the tech note will be listed
2207 ** along side the timestamp. The tech note
2208 ** id will be the first word on each line.
2209 ** This option only applies if the
2210 ** --technote option is also specified.
@@ -2424,10 +2434,11 @@
2434 }else if(( strncmp(g.argv[2],"list",n)==0 )
2435 || ( strncmp(g.argv[2],"ls",n)==0 )){
2436 Stmt q;
2437 const int fTechnote = find_option("technote","t",0)!=0;
2438 const int showIds = find_option("show-technote-ids","s",0)!=0;
2439 const int showCkBr = find_option("show-associated","a",0)!=0;
2440 verify_all_options();
2441 if (fTechnote==0){
2442 db_prepare(&q, listAllWikiPages/*works-like:""*/);
2443 }else{
2444 db_prepare(&q,
@@ -2442,10 +2453,15 @@
2453 while( db_step(&q)==SQLITE_ROW ){
2454 const char *zName = db_column_text(&q, 0);
2455 const int wrid = db_column_int(&q, 2);
2456 if(!showAll && !wrid){
2457 continue;
2458 }
2459 if( !showCkBr &&
2460 (sqlite3_strglob("checkin/*", zName)==0 ||
2461 sqlite3_strglob("branch/*", zName)==0) ){
2462 continue;
2463 }
2464 if( showIds ){
2465 const char *zUuid = db_column_text(&q, 1);
2466 fossil_print("%s ",zUuid);
2467 }
2468
+71 -66
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -175,76 +175,79 @@
175175
** Allowed markup.
176176
**
177177
** Except for MARKUP_INVALID, this must all be in alphabetical order
178178
** and in numerical sequence. The first markup type must be zero.
179179
** The value for MARKUP_XYZ must correspond to the <xyz> entry
180
-** in aAllowedMarkup[].
181
-*/
182
-#define MARKUP_INVALID 0
183
-#define MARKUP_A 1
184
-#define MARKUP_ADDRESS 2
185
-#define MARKUP_HTML5_ARTICLE 3
186
-#define MARKUP_HTML5_ASIDE 4
187
-#define MARKUP_B 5
188
-#define MARKUP_BIG 6
189
-#define MARKUP_BLOCKQUOTE 7
190
-#define MARKUP_BR 8
191
-#define MARKUP_CENTER 9
192
-#define MARKUP_CITE 10
193
-#define MARKUP_CODE 11
194
-#define MARKUP_COL 12
195
-#define MARKUP_COLGROUP 13
196
-#define MARKUP_DD 14
197
-#define MARKUP_DEL 15
198
-#define MARKUP_DFN 16
199
-#define MARKUP_DIV 17
200
-#define MARKUP_DL 18
201
-#define MARKUP_DT 19
202
-#define MARKUP_EM 20
203
-#define MARKUP_FONT 21
204
-#define MARKUP_HTML5_FOOTER 22
205
-#define MARKUP_H1 23
206
-#define MARKUP_H2 24
207
-#define MARKUP_H3 25
208
-#define MARKUP_H4 26
209
-#define MARKUP_H5 27
210
-#define MARKUP_H6 28
211
-#define MARKUP_HTML5_HEADER 29
212
-#define MARKUP_HR 30
213
-#define MARKUP_I 31
214
-#define MARKUP_IMG 32
215
-#define MARKUP_INS 33
216
-#define MARKUP_KBD 34
217
-#define MARKUP_LI 35
218
-#define MARKUP_HTML5_NAV 36
219
-#define MARKUP_NOBR 37
220
-#define MARKUP_NOWIKI 38
221
-#define MARKUP_OL 39
222
-#define MARKUP_P 40
223
-#define MARKUP_PRE 41
224
-#define MARKUP_S 42
225
-#define MARKUP_SAMP 43
226
-#define MARKUP_HTML5_SECTION 44
227
-#define MARKUP_SMALL 45
228
-#define MARKUP_SPAN 46
229
-#define MARKUP_STRIKE 47
230
-#define MARKUP_STRONG 48
231
-#define MARKUP_SUB 49
232
-#define MARKUP_SUP 50
233
-#define MARKUP_TABLE 51
234
-#define MARKUP_TBODY 52
235
-#define MARKUP_TD 53
236
-#define MARKUP_TFOOT 54
237
-#define MARKUP_TH 55
238
-#define MARKUP_THEAD 56
239
-#define MARKUP_TITLE 57
240
-#define MARKUP_TR 58
241
-#define MARKUP_TT 59
242
-#define MARKUP_U 60
243
-#define MARKUP_UL 61
244
-#define MARKUP_VAR 62
245
-#define MARKUP_VERBATIM 63
180
+** in aMarkup[].
181
+*/
182
+enum markup_t {
183
+ MARKUP_INVALID = 0,
184
+ MARKUP_A,
185
+ MARKUP_ABBR,
186
+ MARKUP_ADDRESS,
187
+ MARKUP_HTML5_ARTICLE,
188
+ MARKUP_HTML5_ASIDE,
189
+ MARKUP_B,
190
+ MARKUP_BIG,
191
+ MARKUP_BLOCKQUOTE,
192
+ MARKUP_BR,
193
+ MARKUP_CENTER,
194
+ MARKUP_CITE,
195
+ MARKUP_CODE,
196
+ MARKUP_COL,
197
+ MARKUP_COLGROUP,
198
+ MARKUP_DD,
199
+ MARKUP_DEL,
200
+ MARKUP_DFN,
201
+ MARKUP_DIV,
202
+ MARKUP_DL,
203
+ MARKUP_DT,
204
+ MARKUP_EM,
205
+ MARKUP_FONT,
206
+ MARKUP_HTML5_FOOTER,
207
+ MARKUP_H1,
208
+ MARKUP_H2,
209
+ MARKUP_H3,
210
+ MARKUP_H4,
211
+ MARKUP_H5,
212
+ MARKUP_H6,
213
+ MARKUP_HTML5_HEADER,
214
+ MARKUP_HR,
215
+ MARKUP_I,
216
+ MARKUP_IMG,
217
+ MARKUP_INS,
218
+ MARKUP_KBD,
219
+ MARKUP_LI,
220
+ MARKUP_HTML5_NAV,
221
+ MARKUP_NOBR,
222
+ MARKUP_NOWIKI,
223
+ MARKUP_OL,
224
+ MARKUP_P,
225
+ MARKUP_PRE,
226
+ MARKUP_S,
227
+ MARKUP_SAMP,
228
+ MARKUP_HTML5_SECTION,
229
+ MARKUP_SMALL,
230
+ MARKUP_SPAN,
231
+ MARKUP_STRIKE,
232
+ MARKUP_STRONG,
233
+ MARKUP_SUB,
234
+ MARKUP_SUP,
235
+ MARKUP_TABLE,
236
+ MARKUP_TBODY,
237
+ MARKUP_TD,
238
+ MARKUP_TFOOT,
239
+ MARKUP_TH,
240
+ MARKUP_THEAD,
241
+ MARKUP_TITLE,
242
+ MARKUP_TR,
243
+ MARKUP_TT,
244
+ MARKUP_U,
245
+ MARKUP_UL,
246
+ MARKUP_VAR,
247
+ MARKUP_VERBATIM
248
+};
246249
247250
/*
248251
** The various markup is divided into the following types:
249252
*/
250253
#define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
@@ -279,10 +282,12 @@
279282
} aMarkup[] = {
280283
{ 0, MARKUP_INVALID, 0, 0 },
281284
{ "a", MARKUP_A, MUTYPE_HYPERLINK,
282285
AMSK_HREF|AMSK_NAME|AMSK_CLASS|AMSK_TARGET|AMSK_STYLE|
283286
AMSK_TITLE},
287
+ { "abbr", MARKUP_ABBR, MUTYPE_FONT,
288
+ AMSK_ID|AMSK_CLASS|AMSK_STYLE|AMSK_TITLE },
284289
{ "address", MARKUP_ADDRESS, MUTYPE_BLOCK, AMSK_STYLE },
285290
{ "article", MARKUP_HTML5_ARTICLE, MUTYPE_BLOCK,
286291
AMSK_ID|AMSK_CLASS|AMSK_STYLE },
287292
{ "aside", MARKUP_HTML5_ASIDE, MUTYPE_BLOCK,
288293
AMSK_ID|AMSK_CLASS|AMSK_STYLE },
289294
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -175,76 +175,79 @@
175 ** Allowed markup.
176 **
177 ** Except for MARKUP_INVALID, this must all be in alphabetical order
178 ** and in numerical sequence. The first markup type must be zero.
179 ** The value for MARKUP_XYZ must correspond to the <xyz> entry
180 ** in aAllowedMarkup[].
181 */
182 #define MARKUP_INVALID 0
183 #define MARKUP_A 1
184 #define MARKUP_ADDRESS 2
185 #define MARKUP_HTML5_ARTICLE 3
186 #define MARKUP_HTML5_ASIDE 4
187 #define MARKUP_B 5
188 #define MARKUP_BIG 6
189 #define MARKUP_BLOCKQUOTE 7
190 #define MARKUP_BR 8
191 #define MARKUP_CENTER 9
192 #define MARKUP_CITE 10
193 #define MARKUP_CODE 11
194 #define MARKUP_COL 12
195 #define MARKUP_COLGROUP 13
196 #define MARKUP_DD 14
197 #define MARKUP_DEL 15
198 #define MARKUP_DFN 16
199 #define MARKUP_DIV 17
200 #define MARKUP_DL 18
201 #define MARKUP_DT 19
202 #define MARKUP_EM 20
203 #define MARKUP_FONT 21
204 #define MARKUP_HTML5_FOOTER 22
205 #define MARKUP_H1 23
206 #define MARKUP_H2 24
207 #define MARKUP_H3 25
208 #define MARKUP_H4 26
209 #define MARKUP_H5 27
210 #define MARKUP_H6 28
211 #define MARKUP_HTML5_HEADER 29
212 #define MARKUP_HR 30
213 #define MARKUP_I 31
214 #define MARKUP_IMG 32
215 #define MARKUP_INS 33
216 #define MARKUP_KBD 34
217 #define MARKUP_LI 35
218 #define MARKUP_HTML5_NAV 36
219 #define MARKUP_NOBR 37
220 #define MARKUP_NOWIKI 38
221 #define MARKUP_OL 39
222 #define MARKUP_P 40
223 #define MARKUP_PRE 41
224 #define MARKUP_S 42
225 #define MARKUP_SAMP 43
226 #define MARKUP_HTML5_SECTION 44
227 #define MARKUP_SMALL 45
228 #define MARKUP_SPAN 46
229 #define MARKUP_STRIKE 47
230 #define MARKUP_STRONG 48
231 #define MARKUP_SUB 49
232 #define MARKUP_SUP 50
233 #define MARKUP_TABLE 51
234 #define MARKUP_TBODY 52
235 #define MARKUP_TD 53
236 #define MARKUP_TFOOT 54
237 #define MARKUP_TH 55
238 #define MARKUP_THEAD 56
239 #define MARKUP_TITLE 57
240 #define MARKUP_TR 58
241 #define MARKUP_TT 59
242 #define MARKUP_U 60
243 #define MARKUP_UL 61
244 #define MARKUP_VAR 62
245 #define MARKUP_VERBATIM 63
 
 
 
246
247 /*
248 ** The various markup is divided into the following types:
249 */
250 #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
@@ -279,10 +282,12 @@
279 } aMarkup[] = {
280 { 0, MARKUP_INVALID, 0, 0 },
281 { "a", MARKUP_A, MUTYPE_HYPERLINK,
282 AMSK_HREF|AMSK_NAME|AMSK_CLASS|AMSK_TARGET|AMSK_STYLE|
283 AMSK_TITLE},
 
 
284 { "address", MARKUP_ADDRESS, MUTYPE_BLOCK, AMSK_STYLE },
285 { "article", MARKUP_HTML5_ARTICLE, MUTYPE_BLOCK,
286 AMSK_ID|AMSK_CLASS|AMSK_STYLE },
287 { "aside", MARKUP_HTML5_ASIDE, MUTYPE_BLOCK,
288 AMSK_ID|AMSK_CLASS|AMSK_STYLE },
289
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -175,76 +175,79 @@
175 ** Allowed markup.
176 **
177 ** Except for MARKUP_INVALID, this must all be in alphabetical order
178 ** and in numerical sequence. The first markup type must be zero.
179 ** The value for MARKUP_XYZ must correspond to the <xyz> entry
180 ** in aMarkup[].
181 */
182 enum markup_t {
183 MARKUP_INVALID = 0,
184 MARKUP_A,
185 MARKUP_ABBR,
186 MARKUP_ADDRESS,
187 MARKUP_HTML5_ARTICLE,
188 MARKUP_HTML5_ASIDE,
189 MARKUP_B,
190 MARKUP_BIG,
191 MARKUP_BLOCKQUOTE,
192 MARKUP_BR,
193 MARKUP_CENTER,
194 MARKUP_CITE,
195 MARKUP_CODE,
196 MARKUP_COL,
197 MARKUP_COLGROUP,
198 MARKUP_DD,
199 MARKUP_DEL,
200 MARKUP_DFN,
201 MARKUP_DIV,
202 MARKUP_DL,
203 MARKUP_DT,
204 MARKUP_EM,
205 MARKUP_FONT,
206 MARKUP_HTML5_FOOTER,
207 MARKUP_H1,
208 MARKUP_H2,
209 MARKUP_H3,
210 MARKUP_H4,
211 MARKUP_H5,
212 MARKUP_H6,
213 MARKUP_HTML5_HEADER,
214 MARKUP_HR,
215 MARKUP_I,
216 MARKUP_IMG,
217 MARKUP_INS,
218 MARKUP_KBD,
219 MARKUP_LI,
220 MARKUP_HTML5_NAV,
221 MARKUP_NOBR,
222 MARKUP_NOWIKI,
223 MARKUP_OL,
224 MARKUP_P,
225 MARKUP_PRE,
226 MARKUP_S,
227 MARKUP_SAMP,
228 MARKUP_HTML5_SECTION,
229 MARKUP_SMALL,
230 MARKUP_SPAN,
231 MARKUP_STRIKE,
232 MARKUP_STRONG,
233 MARKUP_SUB,
234 MARKUP_SUP,
235 MARKUP_TABLE,
236 MARKUP_TBODY,
237 MARKUP_TD,
238 MARKUP_TFOOT,
239 MARKUP_TH,
240 MARKUP_THEAD,
241 MARKUP_TITLE,
242 MARKUP_TR,
243 MARKUP_TT,
244 MARKUP_U,
245 MARKUP_UL,
246 MARKUP_VAR,
247 MARKUP_VERBATIM
248 };
249
250 /*
251 ** The various markup is divided into the following types:
252 */
253 #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
@@ -279,10 +282,12 @@
282 } aMarkup[] = {
283 { 0, MARKUP_INVALID, 0, 0 },
284 { "a", MARKUP_A, MUTYPE_HYPERLINK,
285 AMSK_HREF|AMSK_NAME|AMSK_CLASS|AMSK_TARGET|AMSK_STYLE|
286 AMSK_TITLE},
287 { "abbr", MARKUP_ABBR, MUTYPE_FONT,
288 AMSK_ID|AMSK_CLASS|AMSK_STYLE|AMSK_TITLE },
289 { "address", MARKUP_ADDRESS, MUTYPE_BLOCK, AMSK_STYLE },
290 { "article", MARKUP_HTML5_ARTICLE, MUTYPE_BLOCK,
291 AMSK_ID|AMSK_CLASS|AMSK_STYLE },
292 { "aside", MARKUP_HTML5_ASIDE, MUTYPE_BLOCK,
293 AMSK_ID|AMSK_CLASS|AMSK_STYLE },
294
--- src/winhttp.c
+++ src/winhttp.c
@@ -616,10 +616,14 @@
616616
}
617617
if( g.zMainMenuFile ){
618618
blob_appendf(&options, " --mainmenu ");
619619
blob_append_escaped_arg(&options, g.zMainMenuFile, 1);
620620
}
621
+ if( builtin_get_js_delivery_mode()!=0 /* JS_INLINE==0 may change? */ ){
622
+ blob_appendf(&options, " --jsmode ");
623
+ blob_append_escaped_arg(&options, builtin_get_js_delivery_mode_name(), 0);
624
+ }
621625
#if USE_SEE
622626
zSavedKey = db_get_saved_encryption_key();
623627
savedKeySize = db_get_saved_encryption_key_size();
624628
if( zSavedKey!=0 && savedKeySize>0 ){
625629
blob_appendf(&options, " --usepidkey %lu:%p:%u", GetCurrentProcessId(),
626630
627631
ADDED tools/emcc.sh.in
--- src/winhttp.c
+++ src/winhttp.c
@@ -616,10 +616,14 @@
616 }
617 if( g.zMainMenuFile ){
618 blob_appendf(&options, " --mainmenu ");
619 blob_append_escaped_arg(&options, g.zMainMenuFile, 1);
620 }
 
 
 
 
621 #if USE_SEE
622 zSavedKey = db_get_saved_encryption_key();
623 savedKeySize = db_get_saved_encryption_key_size();
624 if( zSavedKey!=0 && savedKeySize>0 ){
625 blob_appendf(&options, " --usepidkey %lu:%p:%u", GetCurrentProcessId(),
626
627 DDED tools/emcc.sh.in
--- src/winhttp.c
+++ src/winhttp.c
@@ -616,10 +616,14 @@
616 }
617 if( g.zMainMenuFile ){
618 blob_appendf(&options, " --mainmenu ");
619 blob_append_escaped_arg(&options, g.zMainMenuFile, 1);
620 }
621 if( builtin_get_js_delivery_mode()!=0 /* JS_INLINE==0 may change? */ ){
622 blob_appendf(&options, " --jsmode ");
623 blob_append_escaped_arg(&options, builtin_get_js_delivery_mode_name(), 0);
624 }
625 #if USE_SEE
626 zSavedKey = db_get_saved_encryption_key();
627 savedKeySize = db_get_saved_encryption_key_size();
628 if( zSavedKey!=0 && savedKeySize>0 ){
629 blob_appendf(&options, " --usepidkey %lu:%p:%u", GetCurrentProcessId(),
630
631 DDED tools/emcc.sh.in
--- a/tools/emcc.sh.in
+++ b/tools/emcc.sh.in
@@ -0,0 +1,65 @@
1
+#!/usr/bin/bash
2
+#############################################
3
+# WARNING: emcc.sh is generated from emcc.sh.in by the configure
4
+# process. Do not edit emcc.sh directly, as it may be deleted or
5
+# overwritten by the configure script.
6
+#
7
+# A wrapper around the emcc compiler which uses configure-time state
8
+# to locate the Emscripten SDK and import the SDK's environment
9
+# script, if needed.
10
+########################################################################
11
+# EMSDK_HOME comes from the configure --with-emsdk=/dir flag.
12
+# EMSDK_ENVk=/dir flag.
13
+# EMSDK_ENV_SH is ${thatDir}/emsdk_env.sh and is also set by the
14
+# ="@EMSDK_ENV@"
15
+
16
+emc`which emcc 2>/dev/null`
17
+fi
18
+
19
+if [ x = "x${emcc}" ]; then
20
+ # If emcc is not found in the path, try to find it via an emsdk
21
+ # installation. The SDK variant i
22
+ # style^^^^ Please try to keep this #!/bin/sh
23
+ emcc is also available
24
+ # via package managers on some OSes.
25
+ if [ x = "x${EMSDK_HOME}" ]; then
26
+ echo "EMSDK_HOME is not set. Pass --with-emsdk=/path/to/emsdk" \
27
+ "to the configure script." 1>&2
28
+ exit 1
29
+ fi
30
+
31
+ if [ x = "x${EMSDK_ENV_SH}" ]; then
32
+ if [ -f "${EMSDK_HOME}/emsdk_env.sh" ]; then
33
+ EMSDK_ENV_SH="${EMSDK_HOME}/emsdk_env.sh"
34
+ else
35
+ echo "EMSDK_ENV_SH is not set. Expecting configure script to set it." 1>&2
36
+ exit 2
37
+ fi
38
+ fi
39
+
40
+ if [ ! -f "${EMSDK_ENV_SH}" ]; then
41
+ echo "emsdk_env script not found: $EMSDK_ENV_SH" 1>&2
42
+ exit 3
43
+ fi
44
+
45
+ # $EMSDK is part of the state set by emsdk_env.sh.
46
+ if [ x = "x${EMSDK}" ]; then
47
+ EMSDK_QUIET=1
48
+ export EMSDK_QUIET
49
+ # ^^^ Squelches informational output from ${EMSDK_ENV_SH}.
50
+ source "${EMSDK_ENV_SH}" || {
51
+ rc=$?
52
+ echo "Error sourcing ${EMSDK_ENV_SH}"
53
+ exit $rc
54
+ }
55
+ fi
56
+ emcc=`which emcc 2>/dev/null`
57
+ if [ x = "x${emcc}" ]; then
58
+ echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV_SH}." 1>&2
59
+ exit 4
60
+ fi
61
+fi
62
+
63
+exec $emcc "$@"
64
+}" ]; then
65
+ emcc "$@"
--- a/tools/emcc.sh.in
+++ b/tools/emcc.sh.in
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/tools/emcc.sh.in
+++ b/tools/emcc.sh.in
@@ -0,0 +1,65 @@
1 #!/usr/bin/bash
2 #############################################
3 # WARNING: emcc.sh is generated from emcc.sh.in by the configure
4 # process. Do not edit emcc.sh directly, as it may be deleted or
5 # overwritten by the configure script.
6 #
7 # A wrapper around the emcc compiler which uses configure-time state
8 # to locate the Emscripten SDK and import the SDK's environment
9 # script, if needed.
10 ########################################################################
11 # EMSDK_HOME comes from the configure --with-emsdk=/dir flag.
12 # EMSDK_ENVk=/dir flag.
13 # EMSDK_ENV_SH is ${thatDir}/emsdk_env.sh and is also set by the
14 # ="@EMSDK_ENV@"
15
16 emc`which emcc 2>/dev/null`
17 fi
18
19 if [ x = "x${emcc}" ]; then
20 # If emcc is not found in the path, try to find it via an emsdk
21 # installation. The SDK variant i
22 # style^^^^ Please try to keep this #!/bin/sh
23 emcc is also available
24 # via package managers on some OSes.
25 if [ x = "x${EMSDK_HOME}" ]; then
26 echo "EMSDK_HOME is not set. Pass --with-emsdk=/path/to/emsdk" \
27 "to the configure script." 1>&2
28 exit 1
29 fi
30
31 if [ x = "x${EMSDK_ENV_SH}" ]; then
32 if [ -f "${EMSDK_HOME}/emsdk_env.sh" ]; then
33 EMSDK_ENV_SH="${EMSDK_HOME}/emsdk_env.sh"
34 else
35 echo "EMSDK_ENV_SH is not set. Expecting configure script to set it." 1>&2
36 exit 2
37 fi
38 fi
39
40 if [ ! -f "${EMSDK_ENV_SH}" ]; then
41 echo "emsdk_env script not found: $EMSDK_ENV_SH" 1>&2
42 exit 3
43 fi
44
45 # $EMSDK is part of the state set by emsdk_env.sh.
46 if [ x = "x${EMSDK}" ]; then
47 EMSDK_QUIET=1
48 export EMSDK_QUIET
49 # ^^^ Squelches informational output from ${EMSDK_ENV_SH}.
50 source "${EMSDK_ENV_SH}" || {
51 rc=$?
52 echo "Error sourcing ${EMSDK_ENV_SH}"
53 exit $rc
54 }
55 fi
56 emcc=`which emcc 2>/dev/null`
57 if [ x = "x${emcc}" ]; then
58 echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV_SH}." 1>&2
59 exit 4
60 fi
61 fi
62
63 exec $emcc "$@"
64 }" ]; then
65 emcc "$@"
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -217,10 +217,12 @@
217217
default.css
218218
style.*.css
219219
../skins/*/*.txt
220220
sounds/*.wav
221221
alerts/*.wav
222
+ ../extsrc/pikchr.wasm
223
+ ../extsrc/pikchr*.js
222224
}
223225
224226
# Options used to compile the included SQLite library.
225227
#
226228
set SQLITE_OPTIONS {
@@ -559,10 +561,21 @@
559561
$(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
560562
561563
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
562564
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
563565
566
+$(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
567
+ $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
568
+ -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore \
569
+ -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
570
+ -sENVIRONMENT=web \
571
+ -sMODULARIZE \
572
+ -sEXPORT_NAME=initPikchrModule \
573
+ --minify 0
574
+ @chmod -x $(SRCDIR_extsrc)/pikchr.wasm
575
+wasm: $(SRCDIR_extsrc)/pikchr.js
576
+
564577
#
565578
# The list of all the targets that do not correspond to real files. This stops
566579
# 'make' from getting confused when someone makes an error in a rule.
567580
#
568581
@@ -637,11 +650,11 @@
637650
638651
#### Enable compiling with debug symbols (much larger binary)
639652
#
640653
# FOSSIL_ENABLE_SYMBOLS = 1
641654
642
-#### Enable JSON (http://www.json.org) support using "cson"
655
+#### Enable JSON (https://www.json.org) support using "cson"
643656
#
644657
# FOSSIL_ENABLE_JSON = 1
645658
646659
#### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
647660
#
648661
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -217,10 +217,12 @@
217 default.css
218 style.*.css
219 ../skins/*/*.txt
220 sounds/*.wav
221 alerts/*.wav
 
 
222 }
223
224 # Options used to compile the included SQLite library.
225 #
226 set SQLITE_OPTIONS {
@@ -559,10 +561,21 @@
559 $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
560
561 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
562 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
563
 
 
 
 
 
 
 
 
 
 
 
564 #
565 # The list of all the targets that do not correspond to real files. This stops
566 # 'make' from getting confused when someone makes an error in a rule.
567 #
568
@@ -637,11 +650,11 @@
637
638 #### Enable compiling with debug symbols (much larger binary)
639 #
640 # FOSSIL_ENABLE_SYMBOLS = 1
641
642 #### Enable JSON (http://www.json.org) support using "cson"
643 #
644 # FOSSIL_ENABLE_JSON = 1
645
646 #### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
647 #
648
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -217,10 +217,12 @@
217 default.css
218 style.*.css
219 ../skins/*/*.txt
220 sounds/*.wav
221 alerts/*.wav
222 ../extsrc/pikchr.wasm
223 ../extsrc/pikchr*.js
224 }
225
226 # Options used to compile the included SQLite library.
227 #
228 set SQLITE_OPTIONS {
@@ -559,10 +561,21 @@
561 $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
562
563 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
564 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
565
566 $(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
567 $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
568 -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore \
569 -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
570 -sENVIRONMENT=web \
571 -sMODULARIZE \
572 -sEXPORT_NAME=initPikchrModule \
573 --minify 0
574 @chmod -x $(SRCDIR_extsrc)/pikchr.wasm
575 wasm: $(SRCDIR_extsrc)/pikchr.js
576
577 #
578 # The list of all the targets that do not correspond to real files. This stops
579 # 'make' from getting confused when someone makes an error in a rule.
580 #
581
@@ -637,11 +650,11 @@
650
651 #### Enable compiling with debug symbols (much larger binary)
652 #
653 # FOSSIL_ENABLE_SYMBOLS = 1
654
655 #### Enable JSON (https://www.json.org) support using "cson"
656 #
657 # FOSSIL_ENABLE_JSON = 1
658
659 #### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
660 #
661
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -54,11 +54,11 @@
5454
5555
#### Enable compiling with debug symbols (much larger binary)
5656
#
5757
# FOSSIL_ENABLE_SYMBOLS = 1
5858
59
-#### Enable JSON (http://www.json.org) support using "cson"
59
+#### Enable JSON (https://www.json.org) support using "cson"
6060
#
6161
# FOSSIL_ENABLE_JSON = 1
6262
6363
#### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
6464
#
@@ -549,10 +549,13 @@
549549
$(SRCDIR)/xfer.c \
550550
$(SRCDIR)/xfersetup.c \
551551
$(SRCDIR)/zip.c
552552
553553
EXTRA_FILES = \
554
+ $(SRCDIR)/../extsrc/pikchr-worker.js \
555
+ $(SRCDIR)/../extsrc/pikchr.js \
556
+ $(SRCDIR)/../extsrc/pikchr.wasm \
554557
$(SRCDIR)/../skins/ardoise/css.txt \
555558
$(SRCDIR)/../skins/ardoise/details.txt \
556559
$(SRCDIR)/../skins/ardoise/footer.txt \
557560
$(SRCDIR)/../skins/ardoise/header.txt \
558561
$(SRCDIR)/../skins/black_and_white/css.txt \
@@ -617,10 +620,11 @@
617620
$(SRCDIR)/fossil.page.brlist.js \
618621
$(SRCDIR)/fossil.page.chat.js \
619622
$(SRCDIR)/fossil.page.fileedit.js \
620623
$(SRCDIR)/fossil.page.forumpost.js \
621624
$(SRCDIR)/fossil.page.pikchrshow.js \
625
+ $(SRCDIR)/fossil.page.pikchrshowasm.js \
622626
$(SRCDIR)/fossil.page.whistory.js \
623627
$(SRCDIR)/fossil.page.wikiedit.js \
624628
$(SRCDIR)/fossil.pikchr.js \
625629
$(SRCDIR)/fossil.popupwidget.js \
626630
$(SRCDIR)/fossil.storage.js \
@@ -652,10 +656,11 @@
652656
$(SRCDIR)/sounds/e.wav \
653657
$(SRCDIR)/sounds/f.wav \
654658
$(SRCDIR)/style.admin_log.css \
655659
$(SRCDIR)/style.chat.css \
656660
$(SRCDIR)/style.fileedit.css \
661
+ $(SRCDIR)/style.pikchrshow.css \
657662
$(SRCDIR)/style.wikiedit.css \
658663
$(SRCDIR)/tree.js \
659664
$(SRCDIR)/useredit.js \
660665
$(SRCDIR)/wiki.wiki
661666
662667
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -54,11 +54,11 @@
54
55 #### Enable compiling with debug symbols (much larger binary)
56 #
57 # FOSSIL_ENABLE_SYMBOLS = 1
58
59 #### Enable JSON (http://www.json.org) support using "cson"
60 #
61 # FOSSIL_ENABLE_JSON = 1
62
63 #### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
64 #
@@ -549,10 +549,13 @@
549 $(SRCDIR)/xfer.c \
550 $(SRCDIR)/xfersetup.c \
551 $(SRCDIR)/zip.c
552
553 EXTRA_FILES = \
 
 
 
554 $(SRCDIR)/../skins/ardoise/css.txt \
555 $(SRCDIR)/../skins/ardoise/details.txt \
556 $(SRCDIR)/../skins/ardoise/footer.txt \
557 $(SRCDIR)/../skins/ardoise/header.txt \
558 $(SRCDIR)/../skins/black_and_white/css.txt \
@@ -617,10 +620,11 @@
617 $(SRCDIR)/fossil.page.brlist.js \
618 $(SRCDIR)/fossil.page.chat.js \
619 $(SRCDIR)/fossil.page.fileedit.js \
620 $(SRCDIR)/fossil.page.forumpost.js \
621 $(SRCDIR)/fossil.page.pikchrshow.js \
 
622 $(SRCDIR)/fossil.page.whistory.js \
623 $(SRCDIR)/fossil.page.wikiedit.js \
624 $(SRCDIR)/fossil.pikchr.js \
625 $(SRCDIR)/fossil.popupwidget.js \
626 $(SRCDIR)/fossil.storage.js \
@@ -652,10 +656,11 @@
652 $(SRCDIR)/sounds/e.wav \
653 $(SRCDIR)/sounds/f.wav \
654 $(SRCDIR)/style.admin_log.css \
655 $(SRCDIR)/style.chat.css \
656 $(SRCDIR)/style.fileedit.css \
 
657 $(SRCDIR)/style.wikiedit.css \
658 $(SRCDIR)/tree.js \
659 $(SRCDIR)/useredit.js \
660 $(SRCDIR)/wiki.wiki
661
662
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -54,11 +54,11 @@
54
55 #### Enable compiling with debug symbols (much larger binary)
56 #
57 # FOSSIL_ENABLE_SYMBOLS = 1
58
59 #### Enable JSON (https://www.json.org) support using "cson"
60 #
61 # FOSSIL_ENABLE_JSON = 1
62
63 #### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
64 #
@@ -549,10 +549,13 @@
549 $(SRCDIR)/xfer.c \
550 $(SRCDIR)/xfersetup.c \
551 $(SRCDIR)/zip.c
552
553 EXTRA_FILES = \
554 $(SRCDIR)/../extsrc/pikchr-worker.js \
555 $(SRCDIR)/../extsrc/pikchr.js \
556 $(SRCDIR)/../extsrc/pikchr.wasm \
557 $(SRCDIR)/../skins/ardoise/css.txt \
558 $(SRCDIR)/../skins/ardoise/details.txt \
559 $(SRCDIR)/../skins/ardoise/footer.txt \
560 $(SRCDIR)/../skins/ardoise/header.txt \
561 $(SRCDIR)/../skins/black_and_white/css.txt \
@@ -617,10 +620,11 @@
620 $(SRCDIR)/fossil.page.brlist.js \
621 $(SRCDIR)/fossil.page.chat.js \
622 $(SRCDIR)/fossil.page.fileedit.js \
623 $(SRCDIR)/fossil.page.forumpost.js \
624 $(SRCDIR)/fossil.page.pikchrshow.js \
625 $(SRCDIR)/fossil.page.pikchrshowasm.js \
626 $(SRCDIR)/fossil.page.whistory.js \
627 $(SRCDIR)/fossil.page.wikiedit.js \
628 $(SRCDIR)/fossil.pikchr.js \
629 $(SRCDIR)/fossil.popupwidget.js \
630 $(SRCDIR)/fossil.storage.js \
@@ -652,10 +656,11 @@
656 $(SRCDIR)/sounds/e.wav \
657 $(SRCDIR)/sounds/f.wav \
658 $(SRCDIR)/style.admin_log.css \
659 $(SRCDIR)/style.chat.css \
660 $(SRCDIR)/style.fileedit.css \
661 $(SRCDIR)/style.pikchrshow.css \
662 $(SRCDIR)/style.wikiedit.css \
663 $(SRCDIR)/tree.js \
664 $(SRCDIR)/useredit.js \
665 $(SRCDIR)/wiki.wiki
666
667
+12 -2
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -505,11 +505,14 @@
505505
"$(OX)\xfer_.c" \
506506
"$(OX)\xfersetup_.c" \
507507
"$(OX)\zip_.c" \
508508
"$(SRCDIR_extsrc)\pikchr.c"
509509
510
-EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
510
+EXTRA_FILES = "$(SRCDIR)\..\extsrc\pikchr-worker.js" \
511
+ "$(SRCDIR)\..\extsrc\pikchr.js" \
512
+ "$(SRCDIR)\..\extsrc\pikchr.wasm" \
513
+ "$(SRCDIR)\..\skins\ardoise\css.txt" \
511514
"$(SRCDIR)\..\skins\ardoise\details.txt" \
512515
"$(SRCDIR)\..\skins\ardoise\footer.txt" \
513516
"$(SRCDIR)\..\skins\ardoise\header.txt" \
514517
"$(SRCDIR)\..\skins\black_and_white\css.txt" \
515518
"$(SRCDIR)\..\skins\black_and_white\details.txt" \
@@ -573,10 +576,11 @@
573576
"$(SRCDIR)\fossil.page.brlist.js" \
574577
"$(SRCDIR)\fossil.page.chat.js" \
575578
"$(SRCDIR)\fossil.page.fileedit.js" \
576579
"$(SRCDIR)\fossil.page.forumpost.js" \
577580
"$(SRCDIR)\fossil.page.pikchrshow.js" \
581
+ "$(SRCDIR)\fossil.page.pikchrshowasm.js" \
578582
"$(SRCDIR)\fossil.page.whistory.js" \
579583
"$(SRCDIR)\fossil.page.wikiedit.js" \
580584
"$(SRCDIR)\fossil.pikchr.js" \
581585
"$(SRCDIR)\fossil.popupwidget.js" \
582586
"$(SRCDIR)\fossil.storage.js" \
@@ -608,10 +612,11 @@
608612
"$(SRCDIR)\sounds\e.wav" \
609613
"$(SRCDIR)\sounds\f.wav" \
610614
"$(SRCDIR)\style.admin_log.css" \
611615
"$(SRCDIR)\style.chat.css" \
612616
"$(SRCDIR)\style.fileedit.css" \
617
+ "$(SRCDIR)\style.pikchrshow.css" \
613618
"$(SRCDIR)\style.wikiedit.css" \
614619
"$(SRCDIR)\tree.js" \
615620
"$(SRCDIR)\useredit.js" \
616621
"$(SRCDIR)\wiki.wiki"
617622
@@ -1129,11 +1134,14 @@
11291134
"$(OBJDIR)\json_timeline$O" : "$(SRCDIR)\json_detail.h"
11301135
"$(OBJDIR)\json_user$O" : "$(SRCDIR)\json_detail.h"
11311136
"$(OBJDIR)\json_wiki$O" : "$(SRCDIR)\json_detail.h"
11321137
11331138
"$(OX)\builtin_data.reslist": $(EXTRA_FILES) "$(B)\win\Makefile.msc"
1134
- echo "$(SRCDIR)\../skins/ardoise/css.txt" > $@
1139
+ echo "$(SRCDIR)\../extsrc/pikchr-worker.js" > $@
1140
+ echo "$(SRCDIR)\../extsrc/pikchr.js" >> $@
1141
+ echo "$(SRCDIR)\../extsrc/pikchr.wasm" >> $@
1142
+ echo "$(SRCDIR)\../skins/ardoise/css.txt" >> $@
11351143
echo "$(SRCDIR)\../skins/ardoise/details.txt" >> $@
11361144
echo "$(SRCDIR)\../skins/ardoise/footer.txt" >> $@
11371145
echo "$(SRCDIR)\../skins/ardoise/header.txt" >> $@
11381146
echo "$(SRCDIR)\../skins/black_and_white/css.txt" >> $@
11391147
echo "$(SRCDIR)\../skins/black_and_white/details.txt" >> $@
@@ -1197,10 +1205,11 @@
11971205
echo "$(SRCDIR)\fossil.page.brlist.js" >> $@
11981206
echo "$(SRCDIR)\fossil.page.chat.js" >> $@
11991207
echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@
12001208
echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@
12011209
echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@
1210
+ echo "$(SRCDIR)\fossil.page.pikchrshowasm.js" >> $@
12021211
echo "$(SRCDIR)\fossil.page.whistory.js" >> $@
12031212
echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@
12041213
echo "$(SRCDIR)\fossil.pikchr.js" >> $@
12051214
echo "$(SRCDIR)\fossil.popupwidget.js" >> $@
12061215
echo "$(SRCDIR)\fossil.storage.js" >> $@
@@ -1232,10 +1241,11 @@
12321241
echo "$(SRCDIR)\sounds/e.wav" >> $@
12331242
echo "$(SRCDIR)\sounds/f.wav" >> $@
12341243
echo "$(SRCDIR)\style.admin_log.css" >> $@
12351244
echo "$(SRCDIR)\style.chat.css" >> $@
12361245
echo "$(SRCDIR)\style.fileedit.css" >> $@
1246
+ echo "$(SRCDIR)\style.pikchrshow.css" >> $@
12371247
echo "$(SRCDIR)\style.wikiedit.css" >> $@
12381248
echo "$(SRCDIR)\tree.js" >> $@
12391249
echo "$(SRCDIR)\useredit.js" >> $@
12401250
echo "$(SRCDIR)\wiki.wiki" >> $@
12411251
12421252
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -505,11 +505,14 @@
505 "$(OX)\xfer_.c" \
506 "$(OX)\xfersetup_.c" \
507 "$(OX)\zip_.c" \
508 "$(SRCDIR_extsrc)\pikchr.c"
509
510 EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
 
 
 
511 "$(SRCDIR)\..\skins\ardoise\details.txt" \
512 "$(SRCDIR)\..\skins\ardoise\footer.txt" \
513 "$(SRCDIR)\..\skins\ardoise\header.txt" \
514 "$(SRCDIR)\..\skins\black_and_white\css.txt" \
515 "$(SRCDIR)\..\skins\black_and_white\details.txt" \
@@ -573,10 +576,11 @@
573 "$(SRCDIR)\fossil.page.brlist.js" \
574 "$(SRCDIR)\fossil.page.chat.js" \
575 "$(SRCDIR)\fossil.page.fileedit.js" \
576 "$(SRCDIR)\fossil.page.forumpost.js" \
577 "$(SRCDIR)\fossil.page.pikchrshow.js" \
 
578 "$(SRCDIR)\fossil.page.whistory.js" \
579 "$(SRCDIR)\fossil.page.wikiedit.js" \
580 "$(SRCDIR)\fossil.pikchr.js" \
581 "$(SRCDIR)\fossil.popupwidget.js" \
582 "$(SRCDIR)\fossil.storage.js" \
@@ -608,10 +612,11 @@
608 "$(SRCDIR)\sounds\e.wav" \
609 "$(SRCDIR)\sounds\f.wav" \
610 "$(SRCDIR)\style.admin_log.css" \
611 "$(SRCDIR)\style.chat.css" \
612 "$(SRCDIR)\style.fileedit.css" \
 
613 "$(SRCDIR)\style.wikiedit.css" \
614 "$(SRCDIR)\tree.js" \
615 "$(SRCDIR)\useredit.js" \
616 "$(SRCDIR)\wiki.wiki"
617
@@ -1129,11 +1134,14 @@
1129 "$(OBJDIR)\json_timeline$O" : "$(SRCDIR)\json_detail.h"
1130 "$(OBJDIR)\json_user$O" : "$(SRCDIR)\json_detail.h"
1131 "$(OBJDIR)\json_wiki$O" : "$(SRCDIR)\json_detail.h"
1132
1133 "$(OX)\builtin_data.reslist": $(EXTRA_FILES) "$(B)\win\Makefile.msc"
1134 echo "$(SRCDIR)\../skins/ardoise/css.txt" > $@
 
 
 
1135 echo "$(SRCDIR)\../skins/ardoise/details.txt" >> $@
1136 echo "$(SRCDIR)\../skins/ardoise/footer.txt" >> $@
1137 echo "$(SRCDIR)\../skins/ardoise/header.txt" >> $@
1138 echo "$(SRCDIR)\../skins/black_and_white/css.txt" >> $@
1139 echo "$(SRCDIR)\../skins/black_and_white/details.txt" >> $@
@@ -1197,10 +1205,11 @@
1197 echo "$(SRCDIR)\fossil.page.brlist.js" >> $@
1198 echo "$(SRCDIR)\fossil.page.chat.js" >> $@
1199 echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@
1200 echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@
1201 echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@
 
1202 echo "$(SRCDIR)\fossil.page.whistory.js" >> $@
1203 echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@
1204 echo "$(SRCDIR)\fossil.pikchr.js" >> $@
1205 echo "$(SRCDIR)\fossil.popupwidget.js" >> $@
1206 echo "$(SRCDIR)\fossil.storage.js" >> $@
@@ -1232,10 +1241,11 @@
1232 echo "$(SRCDIR)\sounds/e.wav" >> $@
1233 echo "$(SRCDIR)\sounds/f.wav" >> $@
1234 echo "$(SRCDIR)\style.admin_log.css" >> $@
1235 echo "$(SRCDIR)\style.chat.css" >> $@
1236 echo "$(SRCDIR)\style.fileedit.css" >> $@
 
1237 echo "$(SRCDIR)\style.wikiedit.css" >> $@
1238 echo "$(SRCDIR)\tree.js" >> $@
1239 echo "$(SRCDIR)\useredit.js" >> $@
1240 echo "$(SRCDIR)\wiki.wiki" >> $@
1241
1242
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -505,11 +505,14 @@
505 "$(OX)\xfer_.c" \
506 "$(OX)\xfersetup_.c" \
507 "$(OX)\zip_.c" \
508 "$(SRCDIR_extsrc)\pikchr.c"
509
510 EXTRA_FILES = "$(SRCDIR)\..\extsrc\pikchr-worker.js" \
511 "$(SRCDIR)\..\extsrc\pikchr.js" \
512 "$(SRCDIR)\..\extsrc\pikchr.wasm" \
513 "$(SRCDIR)\..\skins\ardoise\css.txt" \
514 "$(SRCDIR)\..\skins\ardoise\details.txt" \
515 "$(SRCDIR)\..\skins\ardoise\footer.txt" \
516 "$(SRCDIR)\..\skins\ardoise\header.txt" \
517 "$(SRCDIR)\..\skins\black_and_white\css.txt" \
518 "$(SRCDIR)\..\skins\black_and_white\details.txt" \
@@ -573,10 +576,11 @@
576 "$(SRCDIR)\fossil.page.brlist.js" \
577 "$(SRCDIR)\fossil.page.chat.js" \
578 "$(SRCDIR)\fossil.page.fileedit.js" \
579 "$(SRCDIR)\fossil.page.forumpost.js" \
580 "$(SRCDIR)\fossil.page.pikchrshow.js" \
581 "$(SRCDIR)\fossil.page.pikchrshowasm.js" \
582 "$(SRCDIR)\fossil.page.whistory.js" \
583 "$(SRCDIR)\fossil.page.wikiedit.js" \
584 "$(SRCDIR)\fossil.pikchr.js" \
585 "$(SRCDIR)\fossil.popupwidget.js" \
586 "$(SRCDIR)\fossil.storage.js" \
@@ -608,10 +612,11 @@
612 "$(SRCDIR)\sounds\e.wav" \
613 "$(SRCDIR)\sounds\f.wav" \
614 "$(SRCDIR)\style.admin_log.css" \
615 "$(SRCDIR)\style.chat.css" \
616 "$(SRCDIR)\style.fileedit.css" \
617 "$(SRCDIR)\style.pikchrshow.css" \
618 "$(SRCDIR)\style.wikiedit.css" \
619 "$(SRCDIR)\tree.js" \
620 "$(SRCDIR)\useredit.js" \
621 "$(SRCDIR)\wiki.wiki"
622
@@ -1129,11 +1134,14 @@
1134 "$(OBJDIR)\json_timeline$O" : "$(SRCDIR)\json_detail.h"
1135 "$(OBJDIR)\json_user$O" : "$(SRCDIR)\json_detail.h"
1136 "$(OBJDIR)\json_wiki$O" : "$(SRCDIR)\json_detail.h"
1137
1138 "$(OX)\builtin_data.reslist": $(EXTRA_FILES) "$(B)\win\Makefile.msc"
1139 echo "$(SRCDIR)\../extsrc/pikchr-worker.js" > $@
1140 echo "$(SRCDIR)\../extsrc/pikchr.js" >> $@
1141 echo "$(SRCDIR)\../extsrc/pikchr.wasm" >> $@
1142 echo "$(SRCDIR)\../skins/ardoise/css.txt" >> $@
1143 echo "$(SRCDIR)\../skins/ardoise/details.txt" >> $@
1144 echo "$(SRCDIR)\../skins/ardoise/footer.txt" >> $@
1145 echo "$(SRCDIR)\../skins/ardoise/header.txt" >> $@
1146 echo "$(SRCDIR)\../skins/black_and_white/css.txt" >> $@
1147 echo "$(SRCDIR)\../skins/black_and_white/details.txt" >> $@
@@ -1197,10 +1205,11 @@
1205 echo "$(SRCDIR)\fossil.page.brlist.js" >> $@
1206 echo "$(SRCDIR)\fossil.page.chat.js" >> $@
1207 echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@
1208 echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@
1209 echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@
1210 echo "$(SRCDIR)\fossil.page.pikchrshowasm.js" >> $@
1211 echo "$(SRCDIR)\fossil.page.whistory.js" >> $@
1212 echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@
1213 echo "$(SRCDIR)\fossil.pikchr.js" >> $@
1214 echo "$(SRCDIR)\fossil.popupwidget.js" >> $@
1215 echo "$(SRCDIR)\fossil.storage.js" >> $@
@@ -1232,10 +1241,11 @@
1241 echo "$(SRCDIR)\sounds/e.wav" >> $@
1242 echo "$(SRCDIR)\sounds/f.wav" >> $@
1243 echo "$(SRCDIR)\style.admin_log.css" >> $@
1244 echo "$(SRCDIR)\style.chat.css" >> $@
1245 echo "$(SRCDIR)\style.fileedit.css" >> $@
1246 echo "$(SRCDIR)\style.pikchrshow.css" >> $@
1247 echo "$(SRCDIR)\style.wikiedit.css" >> $@
1248 echo "$(SRCDIR)\tree.js" >> $@
1249 echo "$(SRCDIR)\useredit.js" >> $@
1250 echo "$(SRCDIR)\wiki.wiki" >> $@
1251
1252
+149 -7
--- www/build.wiki
+++ www/build.wiki
@@ -265,14 +265,11 @@
265265
are a member of the <tt>docker</tt> group).
266266
267267
First, create a file named <tt>Dockerfile</tt> with the following contents:
268268
269269
<pre><code>
270
-# Alpine >3.13 breaks stuff on many host OSes! For details see:
271
-# https://wiki.alpinelinux.org/wiki/Draft_Release_Notes_for_Alpine_3.14.0#faccessat2
272
-# FROM alpine:edge
273
-FROM alpine:3.13
270
+FROM alpine:edge
274271
RUN apk update \
275272
&& apk upgrade \
276273
&& apk add --no-cache \
277274
curl gcc make tcl \
278275
musl-dev \
@@ -332,11 +329,11 @@
332329
333330
<h2>6.0 Building on/for Android</h2>
334331
335332
<h3>6.1 Cross-compiling from Linux</h3>
336333
337
-The following instructions for building Fossil for Android,
334
+The following instructions for building Fossil for Android via Linux,
338335
without requiring a rooted OS, are adapted from
339336
[https://fossil-scm.org/forum/forumpost/e0e9de4a7e | forumpost/e0e9de4a7e].
340337
341338
On the development machine, from the fossil source tree:
342339
@@ -381,13 +378,12 @@
381378
Some information about these (reportedly harmless) warnings can
382379
be found
383380
[https://stackoverflow.com/a/41900551 | on this StackOverflow post].
384381
385382
386
-
387383
<a id='fuzzer'></a>
388
-<h2>Building for Fuzz Testing</h2>
384
+<h2>7.0 Building for Fuzz Testing</h2>
389385
390386
This feature is primarily intended for fossil's developers and may
391387
change at any time. It is only known to work on Linux systems and has
392388
been seen to work on x86/64 and ARM.
393389
@@ -460,5 +456,151 @@
460456
e.g. <tt>-jobs=4</tt> to start four fuzzer jobs in parallel, but doing
461457
so may cause the fuzzer to <em>strip the --fuzztype flag</em>, leading
462458
to it testing the wrong thing. When passing on fuzzer-specific flags
463459
along with <tt>--fuzztype</tt>, be sure to check your system's process
464460
list to ensure that your <tt>--fuzztype</tt> flag is there.
461
+
462
+
463
+<a id='wasm'></a>
464
+<h2>8.0 Building WebAssembly Components</h2>
465
+
466
+As of version 2.19, fossil uses one component built as
467
+[https://developer.mozilla.org/en-US/docs/WebAssembly | WebAssembly]
468
+a.k.a. WASM. Because compiling WASM code requires non-trivial
469
+client-side tooling, the repository includes compiled copies of these
470
+pieces. Most Fossil hackers should never need to concern themselves
471
+with the WASM parts, but this section describes how to for those who
472
+want or need to do so.
473
+
474
+<strong>The bits described in this section are necessary when updating
475
+<tt>extsrc/pikchr.c</tt></strong> from the upstream source, or the
476
+fossil binary will use a different version of pikchr than
477
+[/pikchrshow] does (as the latter runs the WASM build of pikchr).
478
+
479
+These instructions have only ever been tested on Linux systems. They
480
+"should" work on any Unix-like system supported by Emscripten. The
481
+fossil makefiles for Windows builds <em>do not</em> include any of the
482
+WASM-related components (patches to add that would be welcomed, of
483
+course).
484
+
485
+The first step is to configure the tree with support for
486
+[https://emscripten.org/|Emscripten]. This requires that the system
487
+has the Emscripten SDK (a.k.a. emsdk) installed, as documented at:
488
+
489
+[https://emscripten.org/docs/getting_started/downloads.html]
490
+
491
+For instructions on keeping the SDK up to date, see:
492
+
493
+[https://emscripten.org/docs/tools_reference/emsdk.html]
494
+
495
+ Sidebar: getting Emscripten up and running is trivial and
496
+ painless, at least on Linux systems, but the installer downloads
497
+ many hundreds of megabytes of tools and dependencies, all of which
498
+ will be installed under the single SDK directory (as opposed to
499
+ being installed at the system level). It does, however, require
500
+ that python3 be installed at the system level and it can
501
+ optionally make use of a system-level cmake for certain tasks
502
+ unrelated to how fossil uses the SDK.
503
+
504
+After installing the SDK, configure the fossil tree with emsdk
505
+support:
506
+
507
+<pre><code>$ ./configure --with-emsdk=/path/to/emsdk ...other options...
508
+</code></pre>
509
+
510
+If the <tt>--with-emsdk</tt> flag is not provided, the configure
511
+script will check for the environment variable <tt>EMSDK</tt>, which
512
+is one of the standard variables the SDK environment uses. If that
513
+variable is found, its value will implicitly be used in place of the
514
+missing <tt>--with-emsdk</tt> flag. Thus, if the <tt>emsdk_env.sh</tt>
515
+script is sourced into the shell before running the configure script,
516
+the SDK will be detected even without the config flag.
517
+
518
+The configure script installs some makefile variables which tell the
519
+build where to find the SDK and it generates a script named
520
+<tt>tools/emcc.sh</tt> (from the template file
521
+<tt>[/file/tools/emcc.sh.in|/tools/emcc.sh.in]</tt>), which is a
522
+wrapper around the Emscripten C compiler (<tt>emcc</tt>). The wrapper
523
+script uses the configure-time state to attempt to set up the various
524
+environment variables which are required by <tt>emcc</tt> and will
525
+fail if it cannot do so. Once it's set up the environment, it passes
526
+on all of its arguments to <tt>emcc</tt>.
527
+
528
+The WASM-related build parts are set up such that none of them should
529
+ever trigger implicity (e.g. via dependencies resolution) in a normal
530
+build cycle. They are instead explicitly built as described below.
531
+
532
+From the top of the source tree, all WASM-related components can be
533
+built with:
534
+
535
+<pre><code>$ make wasm</code></pre>
536
+
537
+As of this writing, those parts include:
538
+
539
+ * <tt>extsrc/pikchr.wasm</tt> is a WASM-compiled form of
540
+ <tt>extsrc/pikchr.c</tt>.
541
+ * <tt>extsrc/pikchr.js</tt> is JS/WASM glue code generated by Emscripten
542
+ to give JS code access to the API exported by the WASM file.
543
+
544
+ Sidebar: The file
545
+ <tt>[/file/extsrc/pikcher-worker.js|extsrc/pikcher-worker.js]</tt>
546
+ is hand-coded and intended to be loaded as a "Worker" in
547
+ JavaScript. That file loads the main module and provides an
548
+ interface via which a main JavaScript thread can communicate with
549
+ pikchr running in a Worker thread. The file
550
+ <tt>[/file/src/fossil.page.pikchrshowasm.js|src/fossil.page.pikchrshowasm.js]</tt>
551
+ implements the [/pikchrshow] app and demonstrates how
552
+ <tt>pikchr-worker.js</tt> is used.
553
+
554
+When a new version of <tt>extsrc/pikchr.c</tt> is installed, the
555
+files <tt>pikchr.{js,wasm}</tt> will need to be recompiled to account
556
+for that. Running <tt>make wasm</tt> will, if the build is set up for
557
+the emsdk, recompile those:
558
+
559
+<pre><code>$ make wasm
560
+./tools/emcc.sh -o extsrc/pikchr.js ...
561
+$ ls -la extsrc/pikchr.{js,wasm}
562
+-rw-rw-r-- 1 stephan stephan 17263 Jun 8 03:59 extsrc/pikchr.js
563
+-rw-rw-r-- 1 stephan stephan 97578 Jun 8 03:59 extsrc/pikchr.wasm
564
+</code></pre>
565
+
566
+<blockquote>Sidebar: if that fails with a message along the lines of:
567
+
568
+<pre><code>setting `EXPORTED_RUNTIME_METHODS` expects `<class 'list'>` but got `<class 'str'>`</code></pre>
569
+
570
+then the emcc being invoked is too old: emcc changed the format of
571
+list-type arguments at some point. The required minimum version is
572
+unknown, but any SDK version from May 2022 or later "should" (as of
573
+this writing) suffice. Any older version may or may not work.
574
+</blockquote>
575
+
576
+After that succeeds, we need to run the normal build so that those
577
+generated files can be compiled in to the fossil binary, accessible
578
+via the [/help?cmd=/builtin|/builtin page]:
579
+
580
+<pre><code>$ make</code></pre>
581
+
582
+Before checking in those newly-built files, they need to be tested by
583
+running the [/pikchrshow] page. If that page loads, the compilation
584
+process fundamentally worked (a load failure will be made obvious to
585
+the viewer). If it fails to load then the browser's dev tools console
586
+likely provides at least a small hint (and <em>sometimes</em> a useful
587
+hint) about the nature of the problem. Don't check those files in
588
+until [/pikchrshow] runs, though!
589
+
590
+Should pikchr's C interface ever change, <tt>pikchr-worker.js</tt>
591
+will need to be updated to accommodate it, but such modification is
592
+typically trivial.
593
+
594
+<h3>8.1 Solutions other than Emscripten?</h3>
595
+
596
+Emscripten is not the only option for building C as WASM, but it
597
+provides a complete toolchain which eliminates many other steps which
598
+must otherwise be accounted for on a per-project basis. Despite its
599
+convenience, it behooves us to explore other build options for the
600
+sake of portability and avoiding what amounts to vendor lock-in.
601
+
602
+For later refererence, here are articles specifically covering
603
+building WASM projects without using Emscripten:
604
+
605
+ * [https://surma.dev/things/c-to-webassembly/]
606
+ * [https://schellcode.github.io/webassembly-without-emscripten]
465607
--- www/build.wiki
+++ www/build.wiki
@@ -265,14 +265,11 @@
265 are a member of the <tt>docker</tt> group).
266
267 First, create a file named <tt>Dockerfile</tt> with the following contents:
268
269 <pre><code>
270 # Alpine >3.13 breaks stuff on many host OSes! For details see:
271 # https://wiki.alpinelinux.org/wiki/Draft_Release_Notes_for_Alpine_3.14.0#faccessat2
272 # FROM alpine:edge
273 FROM alpine:3.13
274 RUN apk update \
275 && apk upgrade \
276 && apk add --no-cache \
277 curl gcc make tcl \
278 musl-dev \
@@ -332,11 +329,11 @@
332
333 <h2>6.0 Building on/for Android</h2>
334
335 <h3>6.1 Cross-compiling from Linux</h3>
336
337 The following instructions for building Fossil for Android,
338 without requiring a rooted OS, are adapted from
339 [https://fossil-scm.org/forum/forumpost/e0e9de4a7e | forumpost/e0e9de4a7e].
340
341 On the development machine, from the fossil source tree:
342
@@ -381,13 +378,12 @@
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
@@ -460,5 +456,151 @@
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/build.wiki
+++ www/build.wiki
@@ -265,14 +265,11 @@
265 are a member of the <tt>docker</tt> group).
266
267 First, create a file named <tt>Dockerfile</tt> with the following contents:
268
269 <pre><code>
270 FROM alpine:edge
 
 
 
271 RUN apk update \
272 && apk upgrade \
273 && apk add --no-cache \
274 curl gcc make tcl \
275 musl-dev \
@@ -332,11 +329,11 @@
329
330 <h2>6.0 Building on/for Android</h2>
331
332 <h3>6.1 Cross-compiling from Linux</h3>
333
334 The following instructions for building Fossil for Android via Linux,
335 without requiring a rooted OS, are adapted from
336 [https://fossil-scm.org/forum/forumpost/e0e9de4a7e | forumpost/e0e9de4a7e].
337
338 On the development machine, from the fossil source tree:
339
@@ -381,13 +378,12 @@
378 Some information about these (reportedly harmless) warnings can
379 be found
380 [https://stackoverflow.com/a/41900551 | on this StackOverflow post].
381
382
 
383 <a id='fuzzer'></a>
384 <h2>7.0 Building for Fuzz Testing</h2>
385
386 This feature is primarily intended for fossil's developers and may
387 change at any time. It is only known to work on Linux systems and has
388 been seen to work on x86/64 and ARM.
389
@@ -460,5 +456,151 @@
456 e.g. <tt>-jobs=4</tt> to start four fuzzer jobs in parallel, but doing
457 so may cause the fuzzer to <em>strip the --fuzztype flag</em>, leading
458 to it testing the wrong thing. When passing on fuzzer-specific flags
459 along with <tt>--fuzztype</tt>, be sure to check your system's process
460 list to ensure that your <tt>--fuzztype</tt> flag is there.
461
462
463 <a id='wasm'></a>
464 <h2>8.0 Building WebAssembly Components</h2>
465
466 As of version 2.19, fossil uses one component built as
467 [https://developer.mozilla.org/en-US/docs/WebAssembly | WebAssembly]
468 a.k.a. WASM. Because compiling WASM code requires non-trivial
469 client-side tooling, the repository includes compiled copies of these
470 pieces. Most Fossil hackers should never need to concern themselves
471 with the WASM parts, but this section describes how to for those who
472 want or need to do so.
473
474 <strong>The bits described in this section are necessary when updating
475 <tt>extsrc/pikchr.c</tt></strong> from the upstream source, or the
476 fossil binary will use a different version of pikchr than
477 [/pikchrshow] does (as the latter runs the WASM build of pikchr).
478
479 These instructions have only ever been tested on Linux systems. They
480 "should" work on any Unix-like system supported by Emscripten. The
481 fossil makefiles for Windows builds <em>do not</em> include any of the
482 WASM-related components (patches to add that would be welcomed, of
483 course).
484
485 The first step is to configure the tree with support for
486 [https://emscripten.org/|Emscripten]. This requires that the system
487 has the Emscripten SDK (a.k.a. emsdk) installed, as documented at:
488
489 [https://emscripten.org/docs/getting_started/downloads.html]
490
491 For instructions on keeping the SDK up to date, see:
492
493 [https://emscripten.org/docs/tools_reference/emsdk.html]
494
495 Sidebar: getting Emscripten up and running is trivial and
496 painless, at least on Linux systems, but the installer downloads
497 many hundreds of megabytes of tools and dependencies, all of which
498 will be installed under the single SDK directory (as opposed to
499 being installed at the system level). It does, however, require
500 that python3 be installed at the system level and it can
501 optionally make use of a system-level cmake for certain tasks
502 unrelated to how fossil uses the SDK.
503
504 After installing the SDK, configure the fossil tree with emsdk
505 support:
506
507 <pre><code>$ ./configure --with-emsdk=/path/to/emsdk ...other options...
508 </code></pre>
509
510 If the <tt>--with-emsdk</tt> flag is not provided, the configure
511 script will check for the environment variable <tt>EMSDK</tt>, which
512 is one of the standard variables the SDK environment uses. If that
513 variable is found, its value will implicitly be used in place of the
514 missing <tt>--with-emsdk</tt> flag. Thus, if the <tt>emsdk_env.sh</tt>
515 script is sourced into the shell before running the configure script,
516 the SDK will be detected even without the config flag.
517
518 The configure script installs some makefile variables which tell the
519 build where to find the SDK and it generates a script named
520 <tt>tools/emcc.sh</tt> (from the template file
521 <tt>[/file/tools/emcc.sh.in|/tools/emcc.sh.in]</tt>), which is a
522 wrapper around the Emscripten C compiler (<tt>emcc</tt>). The wrapper
523 script uses the configure-time state to attempt to set up the various
524 environment variables which are required by <tt>emcc</tt> and will
525 fail if it cannot do so. Once it's set up the environment, it passes
526 on all of its arguments to <tt>emcc</tt>.
527
528 The WASM-related build parts are set up such that none of them should
529 ever trigger implicity (e.g. via dependencies resolution) in a normal
530 build cycle. They are instead explicitly built as described below.
531
532 From the top of the source tree, all WASM-related components can be
533 built with:
534
535 <pre><code>$ make wasm</code></pre>
536
537 As of this writing, those parts include:
538
539 * <tt>extsrc/pikchr.wasm</tt> is a WASM-compiled form of
540 <tt>extsrc/pikchr.c</tt>.
541 * <tt>extsrc/pikchr.js</tt> is JS/WASM glue code generated by Emscripten
542 to give JS code access to the API exported by the WASM file.
543
544 Sidebar: The file
545 <tt>[/file/extsrc/pikcher-worker.js|extsrc/pikcher-worker.js]</tt>
546 is hand-coded and intended to be loaded as a "Worker" in
547 JavaScript. That file loads the main module and provides an
548 interface via which a main JavaScript thread can communicate with
549 pikchr running in a Worker thread. The file
550 <tt>[/file/src/fossil.page.pikchrshowasm.js|src/fossil.page.pikchrshowasm.js]</tt>
551 implements the [/pikchrshow] app and demonstrates how
552 <tt>pikchr-worker.js</tt> is used.
553
554 When a new version of <tt>extsrc/pikchr.c</tt> is installed, the
555 files <tt>pikchr.{js,wasm}</tt> will need to be recompiled to account
556 for that. Running <tt>make wasm</tt> will, if the build is set up for
557 the emsdk, recompile those:
558
559 <pre><code>$ make wasm
560 ./tools/emcc.sh -o extsrc/pikchr.js ...
561 $ ls -la extsrc/pikchr.{js,wasm}
562 -rw-rw-r-- 1 stephan stephan 17263 Jun 8 03:59 extsrc/pikchr.js
563 -rw-rw-r-- 1 stephan stephan 97578 Jun 8 03:59 extsrc/pikchr.wasm
564 </code></pre>
565
566 <blockquote>Sidebar: if that fails with a message along the lines of:
567
568 <pre><code>setting `EXPORTED_RUNTIME_METHODS` expects `<class 'list'>` but got `<class 'str'>`</code></pre>
569
570 then the emcc being invoked is too old: emcc changed the format of
571 list-type arguments at some point. The required minimum version is
572 unknown, but any SDK version from May 2022 or later "should" (as of
573 this writing) suffice. Any older version may or may not work.
574 </blockquote>
575
576 After that succeeds, we need to run the normal build so that those
577 generated files can be compiled in to the fossil binary, accessible
578 via the [/help?cmd=/builtin|/builtin page]:
579
580 <pre><code>$ make</code></pre>
581
582 Before checking in those newly-built files, they need to be tested by
583 running the [/pikchrshow] page. If that page loads, the compilation
584 process fundamentally worked (a load failure will be made obvious to
585 the viewer). If it fails to load then the browser's dev tools console
586 likely provides at least a small hint (and <em>sometimes</em> a useful
587 hint) about the nature of the problem. Don't check those files in
588 until [/pikchrshow] runs, though!
589
590 Should pikchr's C interface ever change, <tt>pikchr-worker.js</tt>
591 will need to be updated to accommodate it, but such modification is
592 typically trivial.
593
594 <h3>8.1 Solutions other than Emscripten?</h3>
595
596 Emscripten is not the only option for building C as WASM, but it
597 provides a complete toolchain which eliminates many other steps which
598 must otherwise be accounted for on a per-project basis. Despite its
599 convenience, it behooves us to explore other build options for the
600 sake of portability and avoiding what amounts to vendor lock-in.
601
602 For later refererence, here are articles specifically covering
603 building WASM projects without using Emscripten:
604
605 * [https://surma.dev/things/c-to-webassembly/]
606 * [https://schellcode.github.io/webassembly-without-emscripten]
607
--- www/caps/index.md
+++ www/caps/index.md
@@ -193,16 +193,16 @@
193193
The repo clone is completely under your user’s power at that point,
194194
affected only by OS file permissions and such. If you need to prevent
195195
that, you want to deny **Clone** capability instead.
196196
197197
Withholding the **Read** capability has a different effect: it
198
-prevents a web client from viewing [embedded
199
-documentation][edoc], using [the file
200
-browser](/help?name=/dir), and pulling file content via the
201
-[`/artifact`](/help?name=/artifact), [`/file`](/help?name=/file), and
202
-[`/raw`](/help?name=/raw) URLs.
203
-It is is common to withhold **Read** capability from low-status visitors
198
+prevents a web client from viewing [embedded documentation][edoc],
199
+using [the file browser](/help?name=/dir),
200
+exploring the [history](/help?name=/timeline) of check-ins,
201
+and pulling file content via the [`/artifact`](/help?name=/artifact),
202
+[`/file`](/help?name=/file), and [`/raw`](/help?name=/raw) URLs.
203
+It is common to withhold **Read** capability from low-status visitors
204204
on private or semi-private repos to prevent them from pulling individual
205205
elements of the repo over the web one at a time, as someone may do when
206206
denied the bulk **Clone** capability.
207207
208208
[edoc]: ../embeddeddoc.wiki
209209
--- www/caps/index.md
+++ www/caps/index.md
@@ -193,16 +193,16 @@
193 The repo clone is completely under your user’s power at that point,
194 affected only by OS file permissions and such. If you need to prevent
195 that, you want to deny **Clone** capability instead.
196
197 Withholding the **Read** capability has a different effect: it
198 prevents a web client from viewing [embedded
199 documentation][edoc], using [the file
200 browser](/help?name=/dir), and pulling file content via the
201 [`/artifact`](/help?name=/artifact), [`/file`](/help?name=/file), and
202 [`/raw`](/help?name=/raw) URLs.
203 It is is common to withhold **Read** capability from low-status visitors
204 on private or semi-private repos to prevent them from pulling individual
205 elements of the repo over the web one at a time, as someone may do when
206 denied the bulk **Clone** capability.
207
208 [edoc]: ../embeddeddoc.wiki
209
--- www/caps/index.md
+++ www/caps/index.md
@@ -193,16 +193,16 @@
193 The repo clone is completely under your user’s power at that point,
194 affected only by OS file permissions and such. If you need to prevent
195 that, you want to deny **Clone** capability instead.
196
197 Withholding the **Read** capability has a different effect: it
198 prevents a web client from viewing [embedded documentation][edoc],
199 using [the file browser](/help?name=/dir),
200 exploring the [history](/help?name=/timeline) of check-ins,
201 and pulling file content via the [`/artifact`](/help?name=/artifact),
202 [`/file`](/help?name=/file), and [`/raw`](/help?name=/raw) URLs.
203 It is common to withhold **Read** capability from low-status visitors
204 on private or semi-private repos to prevent them from pulling individual
205 elements of the repo over the web one at a time, as someone may do when
206 denied the bulk **Clone** capability.
207
208 [edoc]: ../embeddeddoc.wiki
209
--- www/caps/ref.html
+++ www/caps/ref.html
@@ -119,12 +119,13 @@
119119
<tr id="g">
120120
<th>g</th>
121121
<th>Clone</th>
122122
<td>
123123
Clone the repository. Note that this is distinct from <a
124
- href="#o">check-out capability, <b>o</b></a>. Mnemonic:
125
- <b>g</b>et.
124
+ href="#o">check-out capability, <b>o</b></a>; and that upon cloning
125
+ not just files, but also tickets, wikis, technotes and forum posts
126
+ are tranferred. Mnemonic: <b>g</b>et.
126127
</td>
127128
</tr>
128129
129130
<tr id="h">
130131
<th>h</th>
@@ -145,10 +146,12 @@
145146
<td>
146147
Check changes into the repository. Note that a lack of this
147148
capability does not prevent you from checking changes into your
148149
local clone, only from syncing those changes up to the parent
149150
repo, and then <a href="./basics.md#webonly">only over HTTP</a>.
151
+ Also note that not just files, but also tickets, wikis, technotes
152
+ and forum posts will be accepted from clones upon syncronization.
150153
Granting this capability also grants <b>o (Read)</b> Mnemonics:
151154
<b>i</b>nput, check <b>i</b>n changes.
152155
</td>
153156
</tr>
154157
@@ -202,11 +205,11 @@
202205
203206
<tr id="o">
204207
<th>o</th>
205208
<th>Read</th>
206209
<td>
207
- Read repository content from a remote Fossil instance over
210
+ Read content and history of files from a remote Fossil instance over
208211
HTTP. See <a href="index.md#read-v-clone">Reading vs.
209212
Cloning</a>. Mnemonic: check <b>o</b>ut remote repo contents.
210213
</td>
211214
</tr>
212215
213216
--- www/caps/ref.html
+++ www/caps/ref.html
@@ -119,12 +119,13 @@
119 <tr id="g">
120 <th>g</th>
121 <th>Clone</th>
122 <td>
123 Clone the repository. Note that this is distinct from <a
124 href="#o">check-out capability, <b>o</b></a>. Mnemonic:
125 <b>g</b>et.
 
126 </td>
127 </tr>
128
129 <tr id="h">
130 <th>h</th>
@@ -145,10 +146,12 @@
145 <td>
146 Check changes into the repository. Note that a lack of this
147 capability does not prevent you from checking changes into your
148 local clone, only from syncing those changes up to the parent
149 repo, and then <a href="./basics.md#webonly">only over HTTP</a>.
 
 
150 Granting this capability also grants <b>o (Read)</b> Mnemonics:
151 <b>i</b>nput, check <b>i</b>n changes.
152 </td>
153 </tr>
154
@@ -202,11 +205,11 @@
202
203 <tr id="o">
204 <th>o</th>
205 <th>Read</th>
206 <td>
207 Read repository content from a remote Fossil instance over
208 HTTP. See <a href="index.md#read-v-clone">Reading vs.
209 Cloning</a>. Mnemonic: check <b>o</b>ut remote repo contents.
210 </td>
211 </tr>
212
213
--- www/caps/ref.html
+++ www/caps/ref.html
@@ -119,12 +119,13 @@
119 <tr id="g">
120 <th>g</th>
121 <th>Clone</th>
122 <td>
123 Clone the repository. Note that this is distinct from <a
124 href="#o">check-out capability, <b>o</b></a>; and that upon cloning
125 not just files, but also tickets, wikis, technotes and forum posts
126 are tranferred. Mnemonic: <b>g</b>et.
127 </td>
128 </tr>
129
130 <tr id="h">
131 <th>h</th>
@@ -145,10 +146,12 @@
146 <td>
147 Check changes into the repository. Note that a lack of this
148 capability does not prevent you from checking changes into your
149 local clone, only from syncing those changes up to the parent
150 repo, and then <a href="./basics.md#webonly">only over HTTP</a>.
151 Also note that not just files, but also tickets, wikis, technotes
152 and forum posts will be accepted from clones upon syncronization.
153 Granting this capability also grants <b>o (Read)</b> Mnemonics:
154 <b>i</b>nput, check <b>i</b>n changes.
155 </td>
156 </tr>
157
@@ -202,11 +205,11 @@
205
206 <tr id="o">
207 <th>o</th>
208 <th>Read</th>
209 <td>
210 Read content and history of files from a remote Fossil instance over
211 HTTP. See <a href="index.md#read-v-clone">Reading vs.
212 Cloning</a>. Mnemonic: check <b>o</b>ut remote repo contents.
213 </td>
214 </tr>
215
216
--- www/changes.wiki
+++ www/changes.wiki
@@ -9,17 +9,32 @@
99
* Enhancements to the graph layout algorithm design to improve readability
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.
14
+ * Sort tag listings (command line and webpage) by taking numbers into
15
+ consideration so as to cater for tags that follow semantic versioning.
16
+ * On the wiki listings, omit by default wiki pages that are associated with
17
+ check-ins and branches.
1418
* Add the new "[/help?cmd=describe|fossil describe]" command.
1519
* Markdown subsystem extended with [../src/markdown.md#ftnts|footnotes support].
1620
See corresponding [../test/markdown-test3.md|test cases],
1721
[/wiki?name=branch/markdown-footnotes#il|known limitations] and
1822
[forum:/forumthread/ee1f1597e46ec07a|discussion].
1923
* Add the new special name "start:BRANCH" to refer to the first check-in of
2024
the branch.
25
+ * Support [/wiki?name=branch/generated-tkt-mimetype&p|generated "mimetype"]
26
+ columns in the <var>TICKET</var> and <var>TICKETCHNG</var> tables.
27
+ * Fix [/timeline?r=fix_remote_url_overwrite_with_proxy|remote-url-overwrite]
28
+ bug where remote-url is overwritten by the proxy setting during sync
29
+ operation. Also require explicit "system" proxy setting to use
30
+ "http_proxy" environment variable.
31
+ * Reimplemented the [/pikchrshow] app to use a WebAssembly build of
32
+ pikchr so that it can render pikchrs on the client instead of requiring
33
+ a server round-trip.
34
+ * Add the [/help?cmd=email-listid|email-listid setting]. If set, it is
35
+ used as the List-ID header for all outbound notification emails.
2136
2237
<h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
2338
* Added support for [./ssl-server.md|SSL/TLS server mode] for commands
2439
like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
2540
* The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
2641
--- www/changes.wiki
+++ www/changes.wiki
@@ -9,17 +9,32 @@
9 * Enhancements to the graph layout algorithm design to improve readability
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 * Add the new special name "start:BRANCH" to refer to the first check-in of
20 the branch.
 
 
 
 
 
 
 
 
 
 
 
21
22 <h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
23 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
24 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
25 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
26
--- www/changes.wiki
+++ www/changes.wiki
@@ -9,17 +9,32 @@
9 * Enhancements to the graph layout algorithm design to improve readability
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 * Sort tag listings (command line and webpage) by taking numbers into
15 consideration so as to cater for tags that follow semantic versioning.
16 * On the wiki listings, omit by default wiki pages that are associated with
17 check-ins and branches.
18 * Add the new "[/help?cmd=describe|fossil describe]" command.
19 * Markdown subsystem extended with [../src/markdown.md#ftnts|footnotes support].
20 See corresponding [../test/markdown-test3.md|test cases],
21 [/wiki?name=branch/markdown-footnotes#il|known limitations] and
22 [forum:/forumthread/ee1f1597e46ec07a|discussion].
23 * Add the new special name "start:BRANCH" to refer to the first check-in of
24 the branch.
25 * Support [/wiki?name=branch/generated-tkt-mimetype&p|generated "mimetype"]
26 columns in the <var>TICKET</var> and <var>TICKETCHNG</var> tables.
27 * Fix [/timeline?r=fix_remote_url_overwrite_with_proxy|remote-url-overwrite]
28 bug where remote-url is overwritten by the proxy setting during sync
29 operation. Also require explicit "system" proxy setting to use
30 "http_proxy" environment variable.
31 * Reimplemented the [/pikchrshow] app to use a WebAssembly build of
32 pikchr so that it can render pikchrs on the client instead of requiring
33 a server round-trip.
34 * Add the [/help?cmd=email-listid|email-listid setting]. If set, it is
35 used as the List-ID header for all outbound notification emails.
36
37 <h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
38 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
39 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
40 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
41
--- www/reviews.wiki
+++ www/reviews.wiki
@@ -1,13 +1,10 @@
11
<title>Reviews</title>
22
<b>External links:</b>
33
44
* [http://nixtu.blogspot.com/2010/03/fossil-dvcs-on-go-first-impressions.html |
55
Fossil DVCS on the Go - First Impressions]
6
- * [http://blog.mired.org/2011/02/fossil-sweet-spot-in-vcs-space.html |
7
- Fossil - a sweet spot in the VCS space] by Mike Meyer.
8
- * [http://blog.s11n.net/?p=72|Four reasons to take a closer look at the Fossil SCM] by Stephan Beal
96
107
<b>See Also:</b>
118
129
* [./quotes.wiki | Short Quotes on Fossil, Git, And DVCSes]
1310
1411
--- www/reviews.wiki
+++ www/reviews.wiki
@@ -1,13 +1,10 @@
1 <title>Reviews</title>
2 <b>External links:</b>
3
4 * [http://nixtu.blogspot.com/2010/03/fossil-dvcs-on-go-first-impressions.html |
5 Fossil DVCS on the Go - First Impressions]
6 * [http://blog.mired.org/2011/02/fossil-sweet-spot-in-vcs-space.html |
7 Fossil - a sweet spot in the VCS space] by Mike Meyer.
8 * [http://blog.s11n.net/?p=72|Four reasons to take a closer look at the Fossil SCM] by Stephan Beal
9
10 <b>See Also:</b>
11
12 * [./quotes.wiki | Short Quotes on Fossil, Git, And DVCSes]
13
14
--- www/reviews.wiki
+++ www/reviews.wiki
@@ -1,13 +1,10 @@
1 <title>Reviews</title>
2 <b>External links:</b>
3
4 * [http://nixtu.blogspot.com/2010/03/fossil-dvcs-on-go-first-impressions.html |
5 Fossil DVCS on the Go - First Impressions]
 
 
 
6
7 <b>See Also:</b>
8
9 * [./quotes.wiki | Short Quotes on Fossil, Git, And DVCSes]
10
11
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -177,11 +177,11 @@
177177
<h3>2.2 Repository Databases</h3>
178178
179179
The repository database is the file that is commonly referred to as
180180
"the repository". This is because the repository database contains,
181181
among other things, the complete revision, ticket, and wiki history for
182
-a project. It is customary to name the repository database after then
182
+a project. It is customary to name the repository database after the
183183
name of the project, with a ".fossil" suffix. For example, the repository
184184
database for the self-hosting Fossil repository is called "fossil.fossil"
185185
and the repository database for SQLite is called "sqlite.fossil".
186186
187187
<h4>2.2.1 Global Project State</h4>
188188
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -177,11 +177,11 @@
177 <h3>2.2 Repository Databases</h3>
178
179 The repository database is the file that is commonly referred to as
180 "the repository". This is because the repository database contains,
181 among other things, the complete revision, ticket, and wiki history for
182 a project. It is customary to name the repository database after then
183 name of the project, with a ".fossil" suffix. For example, the repository
184 database for the self-hosting Fossil repository is called "fossil.fossil"
185 and the repository database for SQLite is called "sqlite.fossil".
186
187 <h4>2.2.1 Global Project State</h4>
188
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -177,11 +177,11 @@
177 <h3>2.2 Repository Databases</h3>
178
179 The repository database is the file that is commonly referred to as
180 "the repository". This is because the repository database contains,
181 among other things, the complete revision, ticket, and wiki history for
182 a project. It is customary to name the repository database after the
183 name of the project, with a ".fossil" suffix. For example, the repository
184 database for the self-hosting Fossil repository is called "fossil.fossil"
185 and the repository database for SQLite is called "sqlite.fossil".
186
187 <h4>2.2.1 Global Project State</h4>
188

Keyboard Shortcuts

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