Fossil SCM

Merge trunk

jan.nijtmans 2018-12-03 12:08 openssl-1.1 merge
Commit e88c1ff4cc4ce1888d19fc48d99dc8ab5b9d69fdbcc0a0f2acf0632116b501c8
64 files changed +12 +12 +19 -1 +35 -28 +3 -2 +20 -11 +10 -1 +3 +75 -57 +1 -1 +1 -1 +67 -35 +13 +132 -28 +45 -4 +33 -2 +56 -15 +3 -3 +8 -2 +2 -149 +12 -2 +14 +7 -3 +7 -3 +1 -1 +3 -2 +10 +1 -1 +6 -39 +39 +37 -7 +52 -36 +12 -7 +373 -199 +10 -8 +18 -7 +2017 -647 +130 -12 +1 -1 +4 -4 +1 -1 +64 -42 +2 -2 +12 -6 +13 -3 +13 -3 +13 -3 +13 -3 +15 -3 +15 -3 +10 -43 +10 -43 +4 +1 -1 +8 -2 +31 +1 -1 +1 -1 +8 -1 +1 -1 +131 -131 +3 +4 +16
--- Makefile.classic
+++ Makefile.classic
@@ -52,10 +52,17 @@
5252
# static executable that will run in a chroot jail.
5353
#LIB = -static
5454
TCC += -DFOSSIL_DYNAMIC_BUILD=1
5555
5656
TCCFLAGS = $(CFLAGS)
57
+
58
+# We don't attempt to use libedit or libreadline in this simplified
59
+# build system (contrast auto.def and Makefile.in) so use the included
60
+# copy of linenoise. MinGW can't make use of this, but linenoise is
61
+# ifdef'd out elsewhere for that platform. Note that this is a make
62
+# flag handled in src/main.mk, not a C preprocessor flag.
63
+USE_LINENOISE := 1
5764
5865
#### Extra arguments for linking the finished binary. Fossil needs
5966
# to link against the Z-Lib compression library unless the miniz
6067
# library in the source tree is being used. There are no other
6168
# required dependencies.
@@ -66,10 +73,15 @@
6673
# If using zlib:
6774
LIB += $(ZLIB_LIB.$(FOSSIL_ENABLE_MINIZ)) $(LDFLAGS)
6875
6976
# If using HTTPS:
7077
LIB += -lcrypto -lssl
78
+
79
+# Many platforms put cos() needed by src/piechart.c in libm, rather than
80
+# in libc. We cannot enable this by default because libm doesn't exist
81
+# everywhere.
82
+#LIB += -lm
7183
7284
#### Tcl shell for use in running the fossil testsuite. If you do not
7385
# care about testing the end result, this can be blank.
7486
#
7587
TCLSH = tclsh
7688
--- Makefile.classic
+++ Makefile.classic
@@ -52,10 +52,17 @@
52 # static executable that will run in a chroot jail.
53 #LIB = -static
54 TCC += -DFOSSIL_DYNAMIC_BUILD=1
55
56 TCCFLAGS = $(CFLAGS)
 
 
 
 
 
 
 
57
58 #### Extra arguments for linking the finished binary. Fossil needs
59 # to link against the Z-Lib compression library unless the miniz
60 # library in the source tree is being used. There are no other
61 # required dependencies.
@@ -66,10 +73,15 @@
66 # If using zlib:
67 LIB += $(ZLIB_LIB.$(FOSSIL_ENABLE_MINIZ)) $(LDFLAGS)
68
69 # If using HTTPS:
70 LIB += -lcrypto -lssl
 
 
 
 
 
71
72 #### Tcl shell for use in running the fossil testsuite. If you do not
73 # care about testing the end result, this can be blank.
74 #
75 TCLSH = tclsh
76
--- Makefile.classic
+++ Makefile.classic
@@ -52,10 +52,17 @@
52 # static executable that will run in a chroot jail.
53 #LIB = -static
54 TCC += -DFOSSIL_DYNAMIC_BUILD=1
55
56 TCCFLAGS = $(CFLAGS)
57
58 # We don't attempt to use libedit or libreadline in this simplified
59 # build system (contrast auto.def and Makefile.in) so use the included
60 # copy of linenoise. MinGW can't make use of this, but linenoise is
61 # ifdef'd out elsewhere for that platform. Note that this is a make
62 # flag handled in src/main.mk, not a C preprocessor flag.
63 USE_LINENOISE := 1
64
65 #### Extra arguments for linking the finished binary. Fossil needs
66 # to link against the Z-Lib compression library unless the miniz
67 # library in the source tree is being used. There are no other
68 # required dependencies.
@@ -66,10 +73,15 @@
73 # If using zlib:
74 LIB += $(ZLIB_LIB.$(FOSSIL_ENABLE_MINIZ)) $(LDFLAGS)
75
76 # If using HTTPS:
77 LIB += -lcrypto -lssl
78
79 # Many platforms put cos() needed by src/piechart.c in libm, rather than
80 # in libc. We cannot enable this by default because libm doesn't exist
81 # everywhere.
82 #LIB += -lm
83
84 #### Tcl shell for use in running the fossil testsuite. If you do not
85 # care about testing the end result, this can be blank.
86 #
87 TCLSH = tclsh
88
--- Makefile.classic
+++ Makefile.classic
@@ -52,10 +52,17 @@
5252
# static executable that will run in a chroot jail.
5353
#LIB = -static
5454
TCC += -DFOSSIL_DYNAMIC_BUILD=1
5555
5656
TCCFLAGS = $(CFLAGS)
57
+
58
+# We don't attempt to use libedit or libreadline in this simplified
59
+# build system (contrast auto.def and Makefile.in) so use the included
60
+# copy of linenoise. MinGW can't make use of this, but linenoise is
61
+# ifdef'd out elsewhere for that platform. Note that this is a make
62
+# flag handled in src/main.mk, not a C preprocessor flag.
63
+USE_LINENOISE := 1
5764
5865
#### Extra arguments for linking the finished binary. Fossil needs
5966
# to link against the Z-Lib compression library unless the miniz
6067
# library in the source tree is being used. There are no other
6168
# required dependencies.
@@ -66,10 +73,15 @@
6673
# If using zlib:
6774
LIB += $(ZLIB_LIB.$(FOSSIL_ENABLE_MINIZ)) $(LDFLAGS)
6875
6976
# If using HTTPS:
7077
LIB += -lcrypto -lssl
78
+
79
+# Many platforms put cos() needed by src/piechart.c in libm, rather than
80
+# in libc. We cannot enable this by default because libm doesn't exist
81
+# everywhere.
82
+#LIB += -lm
7183
7284
#### Tcl shell for use in running the fossil testsuite. If you do not
7385
# care about testing the end result, this can be blank.
7486
#
7587
TCLSH = tclsh
7688
--- Makefile.classic
+++ Makefile.classic
@@ -52,10 +52,17 @@
52 # static executable that will run in a chroot jail.
53 #LIB = -static
54 TCC += -DFOSSIL_DYNAMIC_BUILD=1
55
56 TCCFLAGS = $(CFLAGS)
 
 
 
 
 
 
 
57
58 #### Extra arguments for linking the finished binary. Fossil needs
59 # to link against the Z-Lib compression library unless the miniz
60 # library in the source tree is being used. There are no other
61 # required dependencies.
@@ -66,10 +73,15 @@
66 # If using zlib:
67 LIB += $(ZLIB_LIB.$(FOSSIL_ENABLE_MINIZ)) $(LDFLAGS)
68
69 # If using HTTPS:
70 LIB += -lcrypto -lssl
 
 
 
 
 
71
72 #### Tcl shell for use in running the fossil testsuite. If you do not
73 # care about testing the end result, this can be blank.
74 #
75 TCLSH = tclsh
76
--- Makefile.classic
+++ Makefile.classic
@@ -52,10 +52,17 @@
52 # static executable that will run in a chroot jail.
53 #LIB = -static
54 TCC += -DFOSSIL_DYNAMIC_BUILD=1
55
56 TCCFLAGS = $(CFLAGS)
57
58 # We don't attempt to use libedit or libreadline in this simplified
59 # build system (contrast auto.def and Makefile.in) so use the included
60 # copy of linenoise. MinGW can't make use of this, but linenoise is
61 # ifdef'd out elsewhere for that platform. Note that this is a make
62 # flag handled in src/main.mk, not a C preprocessor flag.
63 USE_LINENOISE := 1
64
65 #### Extra arguments for linking the finished binary. Fossil needs
66 # to link against the Z-Lib compression library unless the miniz
67 # library in the source tree is being used. There are no other
68 # required dependencies.
@@ -66,10 +73,15 @@
73 # If using zlib:
74 LIB += $(ZLIB_LIB.$(FOSSIL_ENABLE_MINIZ)) $(LDFLAGS)
75
76 # If using HTTPS:
77 LIB += -lcrypto -lssl
78
79 # Many platforms put cos() needed by src/piechart.c in libm, rather than
80 # in libc. We cannot enable this by default because libm doesn't exist
81 # everywhere.
82 #LIB += -lm
83
84 #### Tcl shell for use in running the fossil testsuite. If you do not
85 # care about testing the end result, this can be blank.
86 #
87 TCLSH = tclsh
88
+19 -1
--- auto.def
+++ auto.def
@@ -513,11 +513,29 @@
513513
# Last resort, may be Windows
514514
if {[is_mingw]} {
515515
define-append LIBS -lwsock32
516516
}
517517
}
518
-cc-check-function-in-lib ns_name_uncompress resolv
518
+
519
+# The SMTP module requires special libraries and headers for MX DNS
520
+# record lookups and such.
521
+cc-check-includes arpa/nameser.h
522
+cc-include-needs bind/resolv.h netinet/in.h
523
+cc-check-includes bind/resolv.h
524
+cc-check-includes resolv.h
525
+if { !(([cc-check-function-in-lib dn_expand resolv] ||
526
+ [cc-check-function-in-lib ns_name_uncompress {bind resolv}] ||
527
+ [cc-check-function-in-lib __ns_name_uncompress {bind resolv}]) &&
528
+ ([cc-check-function-in-lib ns_parserr {bind resolv}] ||
529
+ [cc-check-function-in-lib __ns_parserr {bind resolv}]) &&
530
+ ([cc-check-function-in-lib res_query {bind resolv}] ||
531
+ [cc-check-function-in-lib __res_query {bind resolv}]))} {
532
+ msg-result "WARNING: SMTP feature will not be able to look up local MX."
533
+}
534
+cc-check-function-in-lib res_9_ns_initparse resolv
535
+
536
+# Other nonstandard function checks
519537
cc-check-functions utime
520538
cc-check-functions usleep
521539
cc-check-functions strchrnul
522540
cc-check-functions pledge
523541
cc-check-functions backtrace
524542
--- auto.def
+++ auto.def
@@ -513,11 +513,29 @@
513 # Last resort, may be Windows
514 if {[is_mingw]} {
515 define-append LIBS -lwsock32
516 }
517 }
518 cc-check-function-in-lib ns_name_uncompress resolv
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519 cc-check-functions utime
520 cc-check-functions usleep
521 cc-check-functions strchrnul
522 cc-check-functions pledge
523 cc-check-functions backtrace
524
--- auto.def
+++ auto.def
@@ -513,11 +513,29 @@
513 # Last resort, may be Windows
514 if {[is_mingw]} {
515 define-append LIBS -lwsock32
516 }
517 }
518
519 # The SMTP module requires special libraries and headers for MX DNS
520 # record lookups and such.
521 cc-check-includes arpa/nameser.h
522 cc-include-needs bind/resolv.h netinet/in.h
523 cc-check-includes bind/resolv.h
524 cc-check-includes resolv.h
525 if { !(([cc-check-function-in-lib dn_expand resolv] ||
526 [cc-check-function-in-lib ns_name_uncompress {bind resolv}] ||
527 [cc-check-function-in-lib __ns_name_uncompress {bind resolv}]) &&
528 ([cc-check-function-in-lib ns_parserr {bind resolv}] ||
529 [cc-check-function-in-lib __ns_parserr {bind resolv}]) &&
530 ([cc-check-function-in-lib res_query {bind resolv}] ||
531 [cc-check-function-in-lib __res_query {bind resolv}]))} {
532 msg-result "WARNING: SMTP feature will not be able to look up local MX."
533 }
534 cc-check-function-in-lib res_9_ns_initparse resolv
535
536 # Other nonstandard function checks
537 cc-check-functions utime
538 cc-check-functions usleep
539 cc-check-functions strchrnul
540 cc-check-functions pledge
541 cc-check-functions backtrace
542
+35 -28
--- fossil.1
+++ fossil.1
@@ -1,6 +1,6 @@
1
-.TH FOSSIL "1" "February 2015" "http://fossil-scm.org" "User Commands"
1
+.TH FOSSIL "1" "September 2018" "http://fossil-scm.org" "User Commands"
22
.SH NAME
33
fossil \- Distributed Version Control System
44
.SH SYNOPSIS
55
.B fossil
66
\fIhelp\fR
@@ -10,43 +10,46 @@
1010
.br
1111
.B fossil
1212
\fICOMMAND [OPTIONS]\fR
1313
.SH DESCRIPTION
1414
Fossil is a distributed version control system (DVCS) with built-in
15
-wiki, ticket tracker, CGI/http interface, and http server.
15
+forum, wiki, ticket tracker, CGI/HTTP interface, and HTTP server.
1616
1717
.SH Common COMMANDs:
1818
19
-add changes gdiff publish status
20
-.br
21
-addremove clean help pull sync
22
-.br
23
-all clone import push tag
24
-.br
25
-amend commit info rebuild timeline
26
-.br
27
-annotate delete init remote-url ui
28
-.br
29
-bisect diff ls revert undo
30
-.br
31
-blame export merge rm unpublished
32
-.br
33
-branch extras mv settings unversioned
34
-.br
35
-bundle finfo open sqlite3 update
36
-.br
37
-cat fusefs praise stash version
19
+add clean help push timeline
20
+.br
21
+addremove clone import rebuild ui
22
+.br
23
+all commit info remote-url undo
24
+.br
25
+amend delete init revert unpublished
26
+.br
27
+annotate diff ls rm unversioned
28
+.br
29
+bisect export merge settings update
30
+.br
31
+blame extras mv sql version
32
+.br
33
+branch finfo open stash
34
+.br
35
+bundle fusefs praise status
36
+.br
37
+cat gdiff publish sync
38
+.br
39
+changes grep pull tag
3840
3941
.SH FEATURES
4042
4143
Features as described on the fossil home page.
4244
4345
.HP
4446
1.
45
-.B Integrated Bug Tracking, Wiki, & Technotes
47
+.B Integrated Bug Tracking, Wiki, Forum, and Technotes
4648
- In addition to doing distributed version control like Git and
47
-Mercurial, Fossil also supports bug tracking, wiki, and technotes.
49
+Mercurial, Fossil also supports bug tracking, wiki, forum, and
50
+technotes.
4851
4952
.HP
5053
2.
5154
.B Built-in Web Interface
5255
- Fossil has a built-in and intuitive web interface that promotes
@@ -66,17 +69,18 @@
6669
4.
6770
.B Simple Networking
6871
- No custom protocols or TCP ports. Fossil uses plain old HTTP (or HTTPS
6972
or SSH) for all network communications, so it works fine from behind
7073
restrictive firewalls, including proxies. The protocol is bandwidth
71
-efficient to the point that Fossil can be used comfortably over dial-up.
74
+efficient to the point that Fossil can be used comfortably over dial-up
75
+or over the exceedingly slow Wifi on airliners.
7276
7377
.HP
7478
5.
7579
.B CGI/SCGI Enabled
7680
- No server is required, but if you want to set one up, Fossil supports
77
-four simple server configurations.
81
+four easy server configurations.
7882
7983
.HP
8084
6.
8185
.B Autosync
8286
- Fossil supports "autosync" mode which helps to keep projects moving
@@ -87,14 +91,17 @@
8791
7.
8892
.B Robust & Reliable
8993
- Fossil stores content using an enduring file format in an SQLite
9094
database so that transactions are atomic even if interrupted by a
9195
power loss or system crash. Automatic self-checks verify that all
92
-aspects of the repository are consistent prior to each commit. In
93
-over seven years of operation, no work has ever been lost after
94
-having been committed to a Fossil repository.
96
+aspects of the repository are consistent prior to each commit.
97
+
98
+.HP
99
+8.
100
+.B Free and Open-Source
101
+- Uses the 2-clause BSD license.
95102
96103
.SH DOCUMENTATION
97104
http://www.fossil-scm.org/
98105
.br
99106
.B fossil
100107
\fIui\fR
101108
--- fossil.1
+++ fossil.1
@@ -1,6 +1,6 @@
1 .TH FOSSIL "1" "February 2015" "http://fossil-scm.org" "User Commands"
2 .SH NAME
3 fossil \- Distributed Version Control System
4 .SH SYNOPSIS
5 .B fossil
6 \fIhelp\fR
@@ -10,43 +10,46 @@
10 .br
11 .B fossil
12 \fICOMMAND [OPTIONS]\fR
13 .SH DESCRIPTION
14 Fossil is a distributed version control system (DVCS) with built-in
15 wiki, ticket tracker, CGI/http interface, and http server.
16
17 .SH Common COMMANDs:
18
19 add changes gdiff publish status
20 .br
21 addremove clean help pull sync
22 .br
23 all clone import push tag
24 .br
25 amend commit info rebuild timeline
26 .br
27 annotate delete init remote-url ui
28 .br
29 bisect diff ls revert undo
30 .br
31 blame export merge rm unpublished
32 .br
33 branch extras mv settings unversioned
34 .br
35 bundle finfo open sqlite3 update
36 .br
37 cat fusefs praise stash version
 
 
38
39 .SH FEATURES
40
41 Features as described on the fossil home page.
42
43 .HP
44 1.
45 .B Integrated Bug Tracking, Wiki, & Technotes
46 - In addition to doing distributed version control like Git and
47 Mercurial, Fossil also supports bug tracking, wiki, and technotes.
 
48
49 .HP
50 2.
51 .B Built-in Web Interface
52 - Fossil has a built-in and intuitive web interface that promotes
@@ -66,17 +69,18 @@
66 4.
67 .B Simple Networking
68 - No custom protocols or TCP ports. Fossil uses plain old HTTP (or HTTPS
69 or SSH) for all network communications, so it works fine from behind
70 restrictive firewalls, including proxies. The protocol is bandwidth
71 efficient to the point that Fossil can be used comfortably over dial-up.
 
72
73 .HP
74 5.
75 .B CGI/SCGI Enabled
76 - No server is required, but if you want to set one up, Fossil supports
77 four simple server configurations.
78
79 .HP
80 6.
81 .B Autosync
82 - Fossil supports "autosync" mode which helps to keep projects moving
@@ -87,14 +91,17 @@
87 7.
88 .B Robust & Reliable
89 - Fossil stores content using an enduring file format in an SQLite
90 database so that transactions are atomic even if interrupted by a
91 power loss or system crash. Automatic self-checks verify that all
92 aspects of the repository are consistent prior to each commit. In
93 over seven years of operation, no work has ever been lost after
94 having been committed to a Fossil repository.
 
 
 
95
96 .SH DOCUMENTATION
97 http://www.fossil-scm.org/
98 .br
99 .B fossil
100 \fIui\fR
101
--- fossil.1
+++ fossil.1
@@ -1,6 +1,6 @@
1 .TH FOSSIL "1" "September 2018" "http://fossil-scm.org" "User Commands"
2 .SH NAME
3 fossil \- Distributed Version Control System
4 .SH SYNOPSIS
5 .B fossil
6 \fIhelp\fR
@@ -10,43 +10,46 @@
10 .br
11 .B fossil
12 \fICOMMAND [OPTIONS]\fR
13 .SH DESCRIPTION
14 Fossil is a distributed version control system (DVCS) with built-in
15 forum, wiki, ticket tracker, CGI/HTTP interface, and HTTP server.
16
17 .SH Common COMMANDs:
18
19 add clean help push timeline
20 .br
21 addremove clone import rebuild ui
22 .br
23 all commit info remote-url undo
24 .br
25 amend delete init revert unpublished
26 .br
27 annotate diff ls rm unversioned
28 .br
29 bisect export merge settings update
30 .br
31 blame extras mv sql version
32 .br
33 branch finfo open stash
34 .br
35 bundle fusefs praise status
36 .br
37 cat gdiff publish sync
38 .br
39 changes grep pull tag
40
41 .SH FEATURES
42
43 Features as described on the fossil home page.
44
45 .HP
46 1.
47 .B Integrated Bug Tracking, Wiki, Forum, and Technotes
48 - In addition to doing distributed version control like Git and
49 Mercurial, Fossil also supports bug tracking, wiki, forum, and
50 technotes.
51
52 .HP
53 2.
54 .B Built-in Web Interface
55 - Fossil has a built-in and intuitive web interface that promotes
@@ -66,17 +69,18 @@
69 4.
70 .B Simple Networking
71 - No custom protocols or TCP ports. Fossil uses plain old HTTP (or HTTPS
72 or SSH) for all network communications, so it works fine from behind
73 restrictive firewalls, including proxies. The protocol is bandwidth
74 efficient to the point that Fossil can be used comfortably over dial-up
75 or over the exceedingly slow Wifi on airliners.
76
77 .HP
78 5.
79 .B CGI/SCGI Enabled
80 - No server is required, but if you want to set one up, Fossil supports
81 four easy server configurations.
82
83 .HP
84 6.
85 .B Autosync
86 - Fossil supports "autosync" mode which helps to keep projects moving
@@ -87,14 +91,17 @@
91 7.
92 .B Robust & Reliable
93 - Fossil stores content using an enduring file format in an SQLite
94 database so that transactions are atomic even if interrupted by a
95 power loss or system crash. Automatic self-checks verify that all
96 aspects of the repository are consistent prior to each commit.
97
98 .HP
99 8.
100 .B Free and Open-Source
101 - Uses the 2-clause BSD license.
102
103 .SH DOCUMENTATION
104 http://www.fossil-scm.org/
105 .br
106 .B fossil
107 \fIui\fR
108
--- skins/bootstrap/header.txt
+++ skins/bootstrap/header.txt
@@ -2,10 +2,11 @@
22
<head>
33
<meta charset="utf-8">
44
<base href="$baseurl/$current_page" />
55
<title>$<project_name>: $<title></title>
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self' data:; script-src 'self' 'nonce-$<nonce>'; style-src 'self' 'unsafe-inline'"/>
78
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" />
89
<link rel="stylesheet" href="$home/style.css?default" type="text/css" media="screen" />
910
<script>
1011
function gebi(x){
1112
if(/^#/.test(x)) x = x.substr(1);
@@ -114,9 +115,9 @@
114115
</div>
115116
<div class="content">
116117
<th1>
117118
html "<div class='container'>"
118119
html "<ul class='breadcrumb'>"
119
- html "<li><a href='$index_page'>Home</a></li>"
120
- html "<li><a href='$home/$current_page'>$title</a></li>"
120
+ html "<li><a href='$home$index_page'>Home</a></li>"
121
+ html "<li><a href='$home/$current_page'>[htmlize $title]</a></li>"
121122
html "</ul>"
122123
</th1>
123124
--- skins/bootstrap/header.txt
+++ skins/bootstrap/header.txt
@@ -2,10 +2,11 @@
2 <head>
3 <meta charset="utf-8">
4 <base href="$baseurl/$current_page" />
5 <title>$<project_name>: $<title></title>
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 
7 <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" />
8 <link rel="stylesheet" href="$home/style.css?default" type="text/css" media="screen" />
9 <script>
10 function gebi(x){
11 if(/^#/.test(x)) x = x.substr(1);
@@ -114,9 +115,9 @@
114 </div>
115 <div class="content">
116 <th1>
117 html "<div class='container'>"
118 html "<ul class='breadcrumb'>"
119 html "<li><a href='$index_page'>Home</a></li>"
120 html "<li><a href='$home/$current_page'>$title</a></li>"
121 html "</ul>"
122 </th1>
123
--- skins/bootstrap/header.txt
+++ skins/bootstrap/header.txt
@@ -2,10 +2,11 @@
2 <head>
3 <meta charset="utf-8">
4 <base href="$baseurl/$current_page" />
5 <title>$<project_name>: $<title></title>
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <meta http-equiv="Content-Security-Policy" content="default-src 'self' data:; script-src 'self' 'nonce-$<nonce>'; style-src 'self' 'unsafe-inline'"/>
8 <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" />
9 <link rel="stylesheet" href="$home/style.css?default" type="text/css" media="screen" />
10 <script>
11 function gebi(x){
12 if(/^#/.test(x)) x = x.substr(1);
@@ -114,9 +115,9 @@
115 </div>
116 <div class="content">
117 <th1>
118 html "<div class='container'>"
119 html "<ul class='breadcrumb'>"
120 html "<li><a href='$home$index_page'>Home</a></li>"
121 html "<li><a href='$home/$current_page'>[htmlize $title]</a></li>"
122 html "</ul>"
123 </th1>
124
+20 -11
--- src/alerts.c
+++ src/alerts.c
@@ -922,11 +922,11 @@
922922
** designated host and port and all times.
923923
*/
924924
925925
926926
/*
927
-** COMMAND: alerts
927
+** COMMAND: alerts*
928928
**
929929
** Usage: %fossil alerts SUBCOMMAND ARGS...
930930
**
931931
** Subcommands:
932932
**
@@ -2035,12 +2035,12 @@
20352035
p->zFromName = 0;
20362036
p->pNext = 0;
20372037
switch( p->type ){
20382038
case 'c': zType = "Check-In"; break;
20392039
case 'f': zType = "Forum post"; break;
2040
- case 't': zType = "Wiki Edit"; break;
2041
- case 'w': zType = "Ticket Change"; break;
2040
+ case 't': zType = "Ticket Change"; break;
2041
+ case 'w': zType = "Wiki Edit"; break;
20422042
}
20432043
blob_init(&p->hdr, 0, 0);
20442044
blob_init(&p->txt, 0, 0);
20452045
blob_appendf(&p->txt,"== %s %s ==\n%s\n%s/info/%.20s\n",
20462046
db_column_text(&q,1),
@@ -2426,18 +2426,21 @@
24262426
int nHit = 0;
24272427
for(p=pEvents; p; p=p->pNext){
24282428
if( strchr(zSub,p->type)==0 ) continue;
24292429
if( p->needMod ){
24302430
/* For events that require moderator approval, only send an alert
2431
- ** if the recipient is a moderator for that type of event */
2431
+ ** if the recipient is a moderator for that type of event. Setup
2432
+ ** and Admin users always get notified. */
24322433
char xType = '*';
2433
- switch( p->type ){
2434
- case 'f': xType = '5'; break;
2435
- case 't': xType = 'q'; break;
2436
- case 'w': xType = 'l'; break;
2434
+ if( strpbrk(zCap,"as")==0 ){
2435
+ switch( p->type ){
2436
+ case 'f': xType = '5'; break;
2437
+ case 't': xType = 'q'; break;
2438
+ case 'w': xType = 'l'; break;
2439
+ }
2440
+ if( strchr(zCap,xType)==0 ) continue;
24372441
}
2438
- if( strchr(zCap,xType)==0 ) continue;
24392442
}else if( strchr(zCap,'s')!=0 || strchr(zCap,'a')!=0 ){
24402443
/* Setup and admin users can get any notification that does not
24412444
** require moderation */
24422445
}else{
24432446
/* Other users only see the alert if they have sufficient
@@ -2698,12 +2701,11 @@
26982701
if( fossil_strcmp(P("name"),"test1")==0 ){
26992702
/* Visit the /announce/test1 page to see the CGI variables */
27002703
@ <p style='border: 1px solid black; padding: 1ex;'>
27012704
cgi_print_all(0, 0);
27022705
@ </p>
2703
- }else
2704
- if( P("submit")!=0 && cgi_csrf_safe(1) ){
2706
+ }else if( P("submit")!=0 && cgi_csrf_safe(1) ){
27052707
char *zErr = alert_send_announcement();
27062708
style_header("Announcement Sent");
27072709
if( zErr ){
27082710
@ <h1>Internal Error</h1>
27092711
@ <p>The following error was reported by the system:
@@ -2713,11 +2715,18 @@
27132715
}else{
27142716
@ <p>The announcement has been sent.</p>
27152717
}
27162718
style_footer();
27172719
return;
2720
+ } else if( !alert_enabled() ){
2721
+ style_header("Cannot Send Announcement");
2722
+ @ <p>Either you have no subscribers yet, or email alerts are not yet
2723
+ @ <a href="https://fossil-scm.org/fossil/doc/trunk/www/alerts.md">set up</a>
2724
+ @ for this repository.</p>
2725
+ return;
27182726
}
2727
+
27192728
style_header("Send Announcement");
27202729
@ <form method="POST">
27212730
@ <table class="subscribe">
27222731
if( g.perm.Admin ){
27232732
int aa = PB("aa");
27242733
--- src/alerts.c
+++ src/alerts.c
@@ -922,11 +922,11 @@
922 ** designated host and port and all times.
923 */
924
925
926 /*
927 ** COMMAND: alerts
928 **
929 ** Usage: %fossil alerts SUBCOMMAND ARGS...
930 **
931 ** Subcommands:
932 **
@@ -2035,12 +2035,12 @@
2035 p->zFromName = 0;
2036 p->pNext = 0;
2037 switch( p->type ){
2038 case 'c': zType = "Check-In"; break;
2039 case 'f': zType = "Forum post"; break;
2040 case 't': zType = "Wiki Edit"; break;
2041 case 'w': zType = "Ticket Change"; break;
2042 }
2043 blob_init(&p->hdr, 0, 0);
2044 blob_init(&p->txt, 0, 0);
2045 blob_appendf(&p->txt,"== %s %s ==\n%s\n%s/info/%.20s\n",
2046 db_column_text(&q,1),
@@ -2426,18 +2426,21 @@
2426 int nHit = 0;
2427 for(p=pEvents; p; p=p->pNext){
2428 if( strchr(zSub,p->type)==0 ) continue;
2429 if( p->needMod ){
2430 /* For events that require moderator approval, only send an alert
2431 ** if the recipient is a moderator for that type of event */
 
2432 char xType = '*';
2433 switch( p->type ){
2434 case 'f': xType = '5'; break;
2435 case 't': xType = 'q'; break;
2436 case 'w': xType = 'l'; break;
 
 
 
2437 }
2438 if( strchr(zCap,xType)==0 ) continue;
2439 }else if( strchr(zCap,'s')!=0 || strchr(zCap,'a')!=0 ){
2440 /* Setup and admin users can get any notification that does not
2441 ** require moderation */
2442 }else{
2443 /* Other users only see the alert if they have sufficient
@@ -2698,12 +2701,11 @@
2698 if( fossil_strcmp(P("name"),"test1")==0 ){
2699 /* Visit the /announce/test1 page to see the CGI variables */
2700 @ <p style='border: 1px solid black; padding: 1ex;'>
2701 cgi_print_all(0, 0);
2702 @ </p>
2703 }else
2704 if( P("submit")!=0 && cgi_csrf_safe(1) ){
2705 char *zErr = alert_send_announcement();
2706 style_header("Announcement Sent");
2707 if( zErr ){
2708 @ <h1>Internal Error</h1>
2709 @ <p>The following error was reported by the system:
@@ -2713,11 +2715,18 @@
2713 }else{
2714 @ <p>The announcement has been sent.</p>
2715 }
2716 style_footer();
2717 return;
 
 
 
 
 
 
2718 }
 
2719 style_header("Send Announcement");
2720 @ <form method="POST">
2721 @ <table class="subscribe">
2722 if( g.perm.Admin ){
2723 int aa = PB("aa");
2724
--- src/alerts.c
+++ src/alerts.c
@@ -922,11 +922,11 @@
922 ** designated host and port and all times.
923 */
924
925
926 /*
927 ** COMMAND: alerts*
928 **
929 ** Usage: %fossil alerts SUBCOMMAND ARGS...
930 **
931 ** Subcommands:
932 **
@@ -2035,12 +2035,12 @@
2035 p->zFromName = 0;
2036 p->pNext = 0;
2037 switch( p->type ){
2038 case 'c': zType = "Check-In"; break;
2039 case 'f': zType = "Forum post"; break;
2040 case 't': zType = "Ticket Change"; break;
2041 case 'w': zType = "Wiki Edit"; break;
2042 }
2043 blob_init(&p->hdr, 0, 0);
2044 blob_init(&p->txt, 0, 0);
2045 blob_appendf(&p->txt,"== %s %s ==\n%s\n%s/info/%.20s\n",
2046 db_column_text(&q,1),
@@ -2426,18 +2426,21 @@
2426 int nHit = 0;
2427 for(p=pEvents; p; p=p->pNext){
2428 if( strchr(zSub,p->type)==0 ) continue;
2429 if( p->needMod ){
2430 /* For events that require moderator approval, only send an alert
2431 ** if the recipient is a moderator for that type of event. Setup
2432 ** and Admin users always get notified. */
2433 char xType = '*';
2434 if( strpbrk(zCap,"as")==0 ){
2435 switch( p->type ){
2436 case 'f': xType = '5'; break;
2437 case 't': xType = 'q'; break;
2438 case 'w': xType = 'l'; break;
2439 }
2440 if( strchr(zCap,xType)==0 ) continue;
2441 }
 
2442 }else if( strchr(zCap,'s')!=0 || strchr(zCap,'a')!=0 ){
2443 /* Setup and admin users can get any notification that does not
2444 ** require moderation */
2445 }else{
2446 /* Other users only see the alert if they have sufficient
@@ -2698,12 +2701,11 @@
2701 if( fossil_strcmp(P("name"),"test1")==0 ){
2702 /* Visit the /announce/test1 page to see the CGI variables */
2703 @ <p style='border: 1px solid black; padding: 1ex;'>
2704 cgi_print_all(0, 0);
2705 @ </p>
2706 }else if( P("submit")!=0 && cgi_csrf_safe(1) ){
 
2707 char *zErr = alert_send_announcement();
2708 style_header("Announcement Sent");
2709 if( zErr ){
2710 @ <h1>Internal Error</h1>
2711 @ <p>The following error was reported by the system:
@@ -2713,11 +2715,18 @@
2715 }else{
2716 @ <p>The announcement has been sent.</p>
2717 }
2718 style_footer();
2719 return;
2720 } else if( !alert_enabled() ){
2721 style_header("Cannot Send Announcement");
2722 @ <p>Either you have no subscribers yet, or email alerts are not yet
2723 @ <a href="https://fossil-scm.org/fossil/doc/trunk/www/alerts.md">set up</a>
2724 @ for this repository.</p>
2725 return;
2726 }
2727
2728 style_header("Send Announcement");
2729 @ <form method="POST">
2730 @ <table class="subscribe">
2731 if( g.perm.Admin ){
2732 int aa = PB("aa");
2733
+10 -1
--- src/backoffice.c
+++ src/backoffice.c
@@ -382,10 +382,11 @@
382382
383383
if( backofficeDb ) return;
384384
if( g.zRepositoryName==0 ) return;
385385
if( g.db==0 ) return;
386386
if( !db_table_exists("repository","config") ) return;
387
+ if( db_get_boolean("backoffice-disable",0) ) return;
387388
tmNow = time(0);
388389
backofficeReadLease(&x);
389390
if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
390391
/* Another backoffice process is already queued up to run. This
391392
** process does not need to do any backoffice work. */
@@ -393,10 +394,17 @@
393394
}else{
394395
/* We need to run backup to be (at a minimum) on-deck */
395396
backofficeDb = fossil_strdup(g.zRepositoryName);
396397
}
397398
}
399
+
400
+/*
401
+** Call this routine to disable backoffice
402
+*/
403
+void backoffice_disable(void){
404
+ backofficeDb = "x";
405
+}
398406
399407
/*
400408
** Check for errors prior to running backoffice_thread() or backoffice_run().
401409
*/
402410
static void backoffice_error_check_one(int *pOnce){
@@ -431,10 +439,11 @@
431439
sqlite3_uint64 idSelf;
432440
int lastWarning = 0;
433441
int warningDelay = 30;
434442
static int once = 0;
435443
444
+ if( sqlite3_db_readonly(g.db, 0) ) return;
436445
backoffice_error_check_one(&once);
437446
idSelf = backofficeProcessId();
438447
while(1){
439448
tmNow = time(0);
440449
db_begin_write();
@@ -524,11 +533,11 @@
524533
alert_backoffice(0);
525534
smtp_cleanup();
526535
}
527536
528537
/*
529
-** COMMAND: backoffice
538
+** COMMAND: backoffice*
530539
**
531540
** Usage: backoffice [-R repository]
532541
**
533542
** Run backoffice processing. This might be done by a cron job or
534543
** similar to make sure backoffice processing happens periodically.
535544
--- src/backoffice.c
+++ src/backoffice.c
@@ -382,10 +382,11 @@
382
383 if( backofficeDb ) return;
384 if( g.zRepositoryName==0 ) return;
385 if( g.db==0 ) return;
386 if( !db_table_exists("repository","config") ) return;
 
387 tmNow = time(0);
388 backofficeReadLease(&x);
389 if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
390 /* Another backoffice process is already queued up to run. This
391 ** process does not need to do any backoffice work. */
@@ -393,10 +394,17 @@
393 }else{
394 /* We need to run backup to be (at a minimum) on-deck */
395 backofficeDb = fossil_strdup(g.zRepositoryName);
396 }
397 }
 
 
 
 
 
 
 
398
399 /*
400 ** Check for errors prior to running backoffice_thread() or backoffice_run().
401 */
402 static void backoffice_error_check_one(int *pOnce){
@@ -431,10 +439,11 @@
431 sqlite3_uint64 idSelf;
432 int lastWarning = 0;
433 int warningDelay = 30;
434 static int once = 0;
435
 
436 backoffice_error_check_one(&once);
437 idSelf = backofficeProcessId();
438 while(1){
439 tmNow = time(0);
440 db_begin_write();
@@ -524,11 +533,11 @@
524 alert_backoffice(0);
525 smtp_cleanup();
526 }
527
528 /*
529 ** COMMAND: backoffice
530 **
531 ** Usage: backoffice [-R repository]
532 **
533 ** Run backoffice processing. This might be done by a cron job or
534 ** similar to make sure backoffice processing happens periodically.
535
--- src/backoffice.c
+++ src/backoffice.c
@@ -382,10 +382,11 @@
382
383 if( backofficeDb ) return;
384 if( g.zRepositoryName==0 ) return;
385 if( g.db==0 ) return;
386 if( !db_table_exists("repository","config") ) return;
387 if( db_get_boolean("backoffice-disable",0) ) return;
388 tmNow = time(0);
389 backofficeReadLease(&x);
390 if( x.tmNext>=tmNow && backofficeProcessExists(x.idNext) ){
391 /* Another backoffice process is already queued up to run. This
392 ** process does not need to do any backoffice work. */
@@ -393,10 +394,17 @@
394 }else{
395 /* We need to run backup to be (at a minimum) on-deck */
396 backofficeDb = fossil_strdup(g.zRepositoryName);
397 }
398 }
399
400 /*
401 ** Call this routine to disable backoffice
402 */
403 void backoffice_disable(void){
404 backofficeDb = "x";
405 }
406
407 /*
408 ** Check for errors prior to running backoffice_thread() or backoffice_run().
409 */
410 static void backoffice_error_check_one(int *pOnce){
@@ -431,10 +439,11 @@
439 sqlite3_uint64 idSelf;
440 int lastWarning = 0;
441 int warningDelay = 30;
442 static int once = 0;
443
444 if( sqlite3_db_readonly(g.db, 0) ) return;
445 backoffice_error_check_one(&once);
446 idSelf = backofficeProcessId();
447 while(1){
448 tmNow = time(0);
449 db_begin_write();
@@ -524,11 +533,11 @@
533 alert_backoffice(0);
534 smtp_cleanup();
535 }
536
537 /*
538 ** COMMAND: backoffice*
539 **
540 ** Usage: backoffice [-R repository]
541 **
542 ** Run backoffice processing. This might be done by a cron job or
543 ** similar to make sure backoffice processing happens periodically.
544
--- src/bisect.c
+++ src/bisect.c
@@ -385,15 +385,18 @@
385385
bisect_path();
386386
pMid = path_midpoint();
387387
if( pMid==0 ){
388388
fossil_print("bisect complete\n");
389389
}else{
390
+ int nSpan = path_length();
391
+ int nStep = path_search_depth();
390392
g.argv[1] = "update";
391393
g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid);
392394
g.argc = 3;
393395
g.fNoSync = 1;
394396
update_cmd();
397
+ fossil_print("span: %d steps-remaining: %d\n", nSpan, nStep);
395398
}
396399
397400
if( strncmp(zDisplay,"chart",m)==0 ){
398401
bisect_chart(1);
399402
}else if( strncmp(zDisplay, "log", m)==0 ){
400403
--- src/bisect.c
+++ src/bisect.c
@@ -385,15 +385,18 @@
385 bisect_path();
386 pMid = path_midpoint();
387 if( pMid==0 ){
388 fossil_print("bisect complete\n");
389 }else{
 
 
390 g.argv[1] = "update";
391 g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid);
392 g.argc = 3;
393 g.fNoSync = 1;
394 update_cmd();
 
395 }
396
397 if( strncmp(zDisplay,"chart",m)==0 ){
398 bisect_chart(1);
399 }else if( strncmp(zDisplay, "log", m)==0 ){
400
--- src/bisect.c
+++ src/bisect.c
@@ -385,15 +385,18 @@
385 bisect_path();
386 pMid = path_midpoint();
387 if( pMid==0 ){
388 fossil_print("bisect complete\n");
389 }else{
390 int nSpan = path_length();
391 int nStep = path_search_depth();
392 g.argv[1] = "update";
393 g.argv[2] = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pMid->rid);
394 g.argc = 3;
395 g.fNoSync = 1;
396 update_cmd();
397 fossil_print("span: %d steps-remaining: %d\n", nSpan, nStep);
398 }
399
400 if( strncmp(zDisplay,"chart",m)==0 ){
401 bisect_chart(1);
402 }else if( strncmp(zDisplay, "log", m)==0 ){
403
+75 -57
--- src/branch.c
+++ src/branch.c
@@ -178,21 +178,64 @@
178178
db_end_transaction(0);
179179
180180
/* Do an autosync push, if requested */
181181
if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
182182
}
183
+
184
+/*
185
+** Create a TEMP table named "tmp_brlist" with 7 columns:
186
+**
187
+** name Name of the branch
188
+** mtime Time of last checkin on this branch
189
+** isclosed True if the branch is closed
190
+** mergeto Another branch this branch was merged into
191
+** nckin Number of checkins on this branch
192
+** ckin Hash of the last checkin on this branch
193
+** bgclr Background color for this branch
194
+*/
195
+static const char createBrlistQuery[] =
196
+@ CREATE TEMP TABLE IF NOT EXISTS tmp_brlist AS
197
+@ SELECT
198
+@ tagxref.value AS name,
199
+@ max(event.mtime) AS mtime,
200
+@ EXISTS(SELECT 1 FROM tagxref AS tx
201
+@ WHERE tx.rid=tagxref.rid
202
+@ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
203
+@ AND tx.tagtype>0) AS isclosed,
204
+@ (SELECT tagxref.value
205
+@ FROM plink CROSS JOIN tagxref
206
+@ WHERE plink.pid=event.objid
207
+@ AND tagxref.rid=plink.cid
208
+@ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
209
+@ AND tagtype>0) AS mergeto,
210
+@ count(*) AS nckin,
211
+@ (SELECT uuid FROM blob WHERE rid=tagxref.rid) AS ckin,
212
+@ event.bgcolor AS bgclr
213
+@ FROM tagxref, tag, event
214
+@ WHERE tagxref.tagid=tag.tagid
215
+@ AND tagxref.tagtype>0
216
+@ AND tag.tagname='branch'
217
+@ AND event.objid=tagxref.rid
218
+@ GROUP BY 1;
219
+;
220
+
221
+/* Call this routine to create the TEMP table */
222
+static void brlist_create_temp_table(void){
223
+ db_multi_exec(createBrlistQuery/*works-like:""*/);
224
+}
225
+
183226
184227
#if INTERFACE
185228
/*
186229
** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
187230
*/
188231
#define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
189232
#define BRL_OPEN_ONLY 0x002 /* Show only open branches */
190233
#define BRL_BOTH 0x003 /* Show both open and closed branches */
191234
#define BRL_OPEN_CLOSED_MASK 0x003
192
-#define BRL_MTIME 0x004 /* Include lastest check-in time */
193
-#define BRL_ORDERBY_MTIME 0x008 /* Sort by MTIME. (otherwise sort by name)*/
235
+#define BRL_ORDERBY_MTIME 0x004 /* Sort by MTIME. (otherwise sort by name)*/
236
+#define BRL_REVERSE 0x008 /* Reverse the sort order */
194237
195238
#endif /* INTERFACE */
196239
197240
/*
198241
** Prepare a query that will list branches.
@@ -200,47 +243,43 @@
200243
** If (which<0) then the query pulls only closed branches. If
201244
** (which>0) then the query pulls all (closed and opened)
202245
** branches. Else the query pulls currently-opened branches.
203246
*/
204247
void branch_prepare_list_query(Stmt *pQuery, int brFlags){
248
+ Blob sql;
249
+ blob_init(&sql, 0, 0);
250
+ brlist_create_temp_table();
205251
switch( brFlags & BRL_OPEN_CLOSED_MASK ){
206252
case BRL_CLOSED_ONLY: {
207
- db_prepare(pQuery,
208
- "SELECT value FROM tagxref"
209
- " WHERE tagid=%d AND value NOT NULL "
210
- "EXCEPT "
211
- "SELECT value FROM tagxref"
212
- " WHERE tagid=%d"
213
- " AND rid IN leaf"
214
- " AND NOT %z"
215
- " ORDER BY value COLLATE nocase /*sort*/",
216
- TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
253
+ blob_append_sql(&sql,
254
+ "SELECT name FROM tmp_brlist WHERE isclosed"
217255
);
218256
break;
219257
}
220258
case BRL_BOTH: {
221
- db_prepare(pQuery,
222
- "SELECT DISTINCT value FROM tagxref"
223
- " WHERE tagid=%d AND value NOT NULL"
224
- " AND rid IN leaf"
225
- " ORDER BY value COLLATE nocase /*sort*/",
226
- TAG_BRANCH
259
+ blob_append_sql(&sql,
260
+ "SELECT name FROM tmp_brlist"
227261
);
228262
break;
229263
}
230264
case BRL_OPEN_ONLY: {
231
- db_prepare(pQuery,
232
- "SELECT DISTINCT value FROM tagxref"
233
- " WHERE tagid=%d AND value NOT NULL"
234
- " AND rid IN leaf"
235
- " AND NOT %z"
236
- " ORDER BY value COLLATE nocase /*sort*/",
237
- TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
265
+ blob_append_sql(&sql,
266
+ "SELECT name FROM tmp_brlist WHERE NOT isclosed"
238267
);
239268
break;
240269
}
241270
}
271
+ if( brFlags & BRL_ORDERBY_MTIME ){
272
+ blob_append_sql(&sql, " ORDER BY -mtime");
273
+ }else{
274
+ blob_append_sql(&sql, " ORDER BY name COLLATE nocase");
275
+ }
276
+ if( brFlags & BRL_REVERSE ){
277
+ blob_append_sql(&sql," DESC");
278
+ }
279
+ db_prepare_blob(pQuery, &sql);
280
+ blob_reset(&sql);
242281
}
243282
244283
/*
245284
** If the branch named in the argument is open, return a RID for one of
246285
** the open leaves of that branch. If the branch does not exists or is
@@ -276,15 +315,17 @@
276315
**
277316
** fossil branch info BRANCH-NAME
278317
**
279318
** Print information about a branch
280319
**
281
-** fossil branch list|ls ?-a|--all|-c|--closed?
320
+** fossil branch list|ls ?OPTIONS?
282321
**
283
-** List all branches. Use -a or --all to list all branches and
284
-** -c or --closed to list all closed branches. The default is to
285
-** show only open branches.
322
+** List all branches. Options:
323
+** -a|--all List all branches. Default show only open branches
324
+** -c|--closed List closed branches.
325
+** -r Reverse the sort order
326
+** -t Show recently changed branches first
286327
**
287328
** fossil branch new BRANCH-NAME BASIS ?OPTIONS?
288329
**
289330
** Create a new branch BRANCH-NAME off of check-in BASIS.
290331
** Supported options for this subcommand include:
@@ -345,10 +386,12 @@
345386
int vid;
346387
char *zCurrent = 0;
347388
int brFlags = BRL_OPEN_ONLY;
348389
if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
349390
if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
391
+ if( find_option("t",0,0)!=0 ) brFlags |= BRL_ORDERBY_MTIME;
392
+ if( find_option("r",0,0)!=0 ) brFlags |= BRL_REVERSE;
350393
351394
if( g.localOpen ){
352395
vid = db_lget_int("checkout", 0);
353396
zCurrent = db_text(0, "SELECT value FROM tagxref"
354397
" WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
@@ -366,36 +409,10 @@
366409
fossil_fatal("branch subcommand should be one of: "
367410
"current info list ls new");
368411
}
369412
}
370413
371
-static const char brlistQuery[] =
372
-@ SELECT
373
-@ tagxref.value,
374
-@ max(event.mtime),
375
-@ EXISTS(SELECT 1 FROM tagxref AS tx
376
-@ WHERE tx.rid=tagxref.rid
377
-@ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
378
-@ AND tx.tagtype>0),
379
-@ (SELECT tagxref.value
380
-@ FROM plink CROSS JOIN tagxref
381
-@ WHERE plink.pid=event.objid
382
-@ AND tagxref.rid=plink.cid
383
-@ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
384
-@ AND tagtype>0),
385
-@ count(*),
386
-@ (SELECT uuid FROM blob WHERE rid=tagxref.rid),
387
-@ event.bgcolor
388
-@ FROM tagxref, tag, event
389
-@ WHERE tagxref.tagid=tag.tagid
390
-@ AND tagxref.tagtype>0
391
-@ AND tag.tagname='branch'
392
-@ AND event.objid=tagxref.rid
393
-@ GROUP BY 1
394
-@ ORDER BY 2 DESC;
395
-;
396
-
397414
/*
398415
** This is the new-style branch-list page that shows the branch names
399416
** together with their ages (time of last check-in) and whether or not
400417
** they are closed or merged to another branch.
401418
**
@@ -411,11 +428,12 @@
411428
style_header("Branches");
412429
style_adunit_config(ADUNIT_RIGHT_OK);
413430
style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
414431
login_anonymous_available();
415432
416
- db_prepare(&q, brlistQuery/*works-like:""*/);
433
+ brlist_create_temp_table();
434
+ db_prepare(&q, "SELECT * FROM tmp_brlist ORDER BY mtime DESC");
417435
rNow = db_double(0.0, "SELECT julianday('now')");
418436
@ <div class="brlist">
419437
@ <table class='sortable' data-column-types='tkNtt' data-init-sort='2'>
420438
@ <thead><tr>
421439
@ <th>Branch Name</th>
@@ -446,11 +464,11 @@
446464
@ <tr style="background-color:%s(zBgClr)">
447465
}else{
448466
@ <tr>
449467
}
450468
@ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
451
- @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td>
469
+ @ <td data-sortkey="%016llx(iMtime)">%s(zAge)</td>
452470
@ <td>%d(nCkin)</td>
453471
fossil_free(zAge);
454472
@ <td>%s(isClosed?"closed":"")</td>
455473
if( zMergeTo ){
456474
@ <td>merged into
457475
--- src/branch.c
+++ src/branch.c
@@ -178,21 +178,64 @@
178 db_end_transaction(0);
179
180 /* Do an autosync push, if requested */
181 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
182 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
184 #if INTERFACE
185 /*
186 ** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
187 */
188 #define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
189 #define BRL_OPEN_ONLY 0x002 /* Show only open branches */
190 #define BRL_BOTH 0x003 /* Show both open and closed branches */
191 #define BRL_OPEN_CLOSED_MASK 0x003
192 #define BRL_MTIME 0x004 /* Include lastest check-in time */
193 #define BRL_ORDERBY_MTIME 0x008 /* Sort by MTIME. (otherwise sort by name)*/
194
195 #endif /* INTERFACE */
196
197 /*
198 ** Prepare a query that will list branches.
@@ -200,47 +243,43 @@
200 ** If (which<0) then the query pulls only closed branches. If
201 ** (which>0) then the query pulls all (closed and opened)
202 ** branches. Else the query pulls currently-opened branches.
203 */
204 void branch_prepare_list_query(Stmt *pQuery, int brFlags){
 
 
 
205 switch( brFlags & BRL_OPEN_CLOSED_MASK ){
206 case BRL_CLOSED_ONLY: {
207 db_prepare(pQuery,
208 "SELECT value FROM tagxref"
209 " WHERE tagid=%d AND value NOT NULL "
210 "EXCEPT "
211 "SELECT value FROM tagxref"
212 " WHERE tagid=%d"
213 " AND rid IN leaf"
214 " AND NOT %z"
215 " ORDER BY value COLLATE nocase /*sort*/",
216 TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
217 );
218 break;
219 }
220 case BRL_BOTH: {
221 db_prepare(pQuery,
222 "SELECT DISTINCT value FROM tagxref"
223 " WHERE tagid=%d AND value NOT NULL"
224 " AND rid IN leaf"
225 " ORDER BY value COLLATE nocase /*sort*/",
226 TAG_BRANCH
227 );
228 break;
229 }
230 case BRL_OPEN_ONLY: {
231 db_prepare(pQuery,
232 "SELECT DISTINCT value FROM tagxref"
233 " WHERE tagid=%d AND value NOT NULL"
234 " AND rid IN leaf"
235 " AND NOT %z"
236 " ORDER BY value COLLATE nocase /*sort*/",
237 TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
238 );
239 break;
240 }
241 }
 
 
 
 
 
 
 
 
 
 
242 }
243
244 /*
245 ** If the branch named in the argument is open, return a RID for one of
246 ** the open leaves of that branch. If the branch does not exists or is
@@ -276,15 +315,17 @@
276 **
277 ** fossil branch info BRANCH-NAME
278 **
279 ** Print information about a branch
280 **
281 ** fossil branch list|ls ?-a|--all|-c|--closed?
282 **
283 ** List all branches. Use -a or --all to list all branches and
284 ** -c or --closed to list all closed branches. The default is to
285 ** show only open branches.
 
 
286 **
287 ** fossil branch new BRANCH-NAME BASIS ?OPTIONS?
288 **
289 ** Create a new branch BRANCH-NAME off of check-in BASIS.
290 ** Supported options for this subcommand include:
@@ -345,10 +386,12 @@
345 int vid;
346 char *zCurrent = 0;
347 int brFlags = BRL_OPEN_ONLY;
348 if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
349 if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
 
 
350
351 if( g.localOpen ){
352 vid = db_lget_int("checkout", 0);
353 zCurrent = db_text(0, "SELECT value FROM tagxref"
354 " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
@@ -366,36 +409,10 @@
366 fossil_fatal("branch subcommand should be one of: "
367 "current info list ls new");
368 }
369 }
370
371 static const char brlistQuery[] =
372 @ SELECT
373 @ tagxref.value,
374 @ max(event.mtime),
375 @ EXISTS(SELECT 1 FROM tagxref AS tx
376 @ WHERE tx.rid=tagxref.rid
377 @ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
378 @ AND tx.tagtype>0),
379 @ (SELECT tagxref.value
380 @ FROM plink CROSS JOIN tagxref
381 @ WHERE plink.pid=event.objid
382 @ AND tagxref.rid=plink.cid
383 @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
384 @ AND tagtype>0),
385 @ count(*),
386 @ (SELECT uuid FROM blob WHERE rid=tagxref.rid),
387 @ event.bgcolor
388 @ FROM tagxref, tag, event
389 @ WHERE tagxref.tagid=tag.tagid
390 @ AND tagxref.tagtype>0
391 @ AND tag.tagname='branch'
392 @ AND event.objid=tagxref.rid
393 @ GROUP BY 1
394 @ ORDER BY 2 DESC;
395 ;
396
397 /*
398 ** This is the new-style branch-list page that shows the branch names
399 ** together with their ages (time of last check-in) and whether or not
400 ** they are closed or merged to another branch.
401 **
@@ -411,11 +428,12 @@
411 style_header("Branches");
412 style_adunit_config(ADUNIT_RIGHT_OK);
413 style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
414 login_anonymous_available();
415
416 db_prepare(&q, brlistQuery/*works-like:""*/);
 
417 rNow = db_double(0.0, "SELECT julianday('now')");
418 @ <div class="brlist">
419 @ <table class='sortable' data-column-types='tkNtt' data-init-sort='2'>
420 @ <thead><tr>
421 @ <th>Branch Name</th>
@@ -446,11 +464,11 @@
446 @ <tr style="background-color:%s(zBgClr)">
447 }else{
448 @ <tr>
449 }
450 @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
451 @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td>
452 @ <td>%d(nCkin)</td>
453 fossil_free(zAge);
454 @ <td>%s(isClosed?"closed":"")</td>
455 if( zMergeTo ){
456 @ <td>merged into
457
--- src/branch.c
+++ src/branch.c
@@ -178,21 +178,64 @@
178 db_end_transaction(0);
179
180 /* Do an autosync push, if requested */
181 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
182 }
183
184 /*
185 ** Create a TEMP table named "tmp_brlist" with 7 columns:
186 **
187 ** name Name of the branch
188 ** mtime Time of last checkin on this branch
189 ** isclosed True if the branch is closed
190 ** mergeto Another branch this branch was merged into
191 ** nckin Number of checkins on this branch
192 ** ckin Hash of the last checkin on this branch
193 ** bgclr Background color for this branch
194 */
195 static const char createBrlistQuery[] =
196 @ CREATE TEMP TABLE IF NOT EXISTS tmp_brlist AS
197 @ SELECT
198 @ tagxref.value AS name,
199 @ max(event.mtime) AS mtime,
200 @ EXISTS(SELECT 1 FROM tagxref AS tx
201 @ WHERE tx.rid=tagxref.rid
202 @ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
203 @ AND tx.tagtype>0) AS isclosed,
204 @ (SELECT tagxref.value
205 @ FROM plink CROSS JOIN tagxref
206 @ WHERE plink.pid=event.objid
207 @ AND tagxref.rid=plink.cid
208 @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
209 @ AND tagtype>0) AS mergeto,
210 @ count(*) AS nckin,
211 @ (SELECT uuid FROM blob WHERE rid=tagxref.rid) AS ckin,
212 @ event.bgcolor AS bgclr
213 @ FROM tagxref, tag, event
214 @ WHERE tagxref.tagid=tag.tagid
215 @ AND tagxref.tagtype>0
216 @ AND tag.tagname='branch'
217 @ AND event.objid=tagxref.rid
218 @ GROUP BY 1;
219 ;
220
221 /* Call this routine to create the TEMP table */
222 static void brlist_create_temp_table(void){
223 db_multi_exec(createBrlistQuery/*works-like:""*/);
224 }
225
226
227 #if INTERFACE
228 /*
229 ** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
230 */
231 #define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
232 #define BRL_OPEN_ONLY 0x002 /* Show only open branches */
233 #define BRL_BOTH 0x003 /* Show both open and closed branches */
234 #define BRL_OPEN_CLOSED_MASK 0x003
235 #define BRL_ORDERBY_MTIME 0x004 /* Sort by MTIME. (otherwise sort by name)*/
236 #define BRL_REVERSE 0x008 /* Reverse the sort order */
237
238 #endif /* INTERFACE */
239
240 /*
241 ** Prepare a query that will list branches.
@@ -200,47 +243,43 @@
243 ** If (which<0) then the query pulls only closed branches. If
244 ** (which>0) then the query pulls all (closed and opened)
245 ** branches. Else the query pulls currently-opened branches.
246 */
247 void branch_prepare_list_query(Stmt *pQuery, int brFlags){
248 Blob sql;
249 blob_init(&sql, 0, 0);
250 brlist_create_temp_table();
251 switch( brFlags & BRL_OPEN_CLOSED_MASK ){
252 case BRL_CLOSED_ONLY: {
253 blob_append_sql(&sql,
254 "SELECT name FROM tmp_brlist WHERE isclosed"
 
 
 
 
 
 
 
 
255 );
256 break;
257 }
258 case BRL_BOTH: {
259 blob_append_sql(&sql,
260 "SELECT name FROM tmp_brlist"
 
 
 
 
261 );
262 break;
263 }
264 case BRL_OPEN_ONLY: {
265 blob_append_sql(&sql,
266 "SELECT name FROM tmp_brlist WHERE NOT isclosed"
 
 
 
 
 
267 );
268 break;
269 }
270 }
271 if( brFlags & BRL_ORDERBY_MTIME ){
272 blob_append_sql(&sql, " ORDER BY -mtime");
273 }else{
274 blob_append_sql(&sql, " ORDER BY name COLLATE nocase");
275 }
276 if( brFlags & BRL_REVERSE ){
277 blob_append_sql(&sql," DESC");
278 }
279 db_prepare_blob(pQuery, &sql);
280 blob_reset(&sql);
281 }
282
283 /*
284 ** If the branch named in the argument is open, return a RID for one of
285 ** the open leaves of that branch. If the branch does not exists or is
@@ -276,15 +315,17 @@
315 **
316 ** fossil branch info BRANCH-NAME
317 **
318 ** Print information about a branch
319 **
320 ** fossil branch list|ls ?OPTIONS?
321 **
322 ** List all branches. Options:
323 ** -a|--all List all branches. Default show only open branches
324 ** -c|--closed List closed branches.
325 ** -r Reverse the sort order
326 ** -t Show recently changed branches first
327 **
328 ** fossil branch new BRANCH-NAME BASIS ?OPTIONS?
329 **
330 ** Create a new branch BRANCH-NAME off of check-in BASIS.
331 ** Supported options for this subcommand include:
@@ -345,10 +386,12 @@
386 int vid;
387 char *zCurrent = 0;
388 int brFlags = BRL_OPEN_ONLY;
389 if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
390 if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
391 if( find_option("t",0,0)!=0 ) brFlags |= BRL_ORDERBY_MTIME;
392 if( find_option("r",0,0)!=0 ) brFlags |= BRL_REVERSE;
393
394 if( g.localOpen ){
395 vid = db_lget_int("checkout", 0);
396 zCurrent = db_text(0, "SELECT value FROM tagxref"
397 " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
@@ -366,36 +409,10 @@
409 fossil_fatal("branch subcommand should be one of: "
410 "current info list ls new");
411 }
412 }
413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414 /*
415 ** This is the new-style branch-list page that shows the branch names
416 ** together with their ages (time of last check-in) and whether or not
417 ** they are closed or merged to another branch.
418 **
@@ -411,11 +428,12 @@
428 style_header("Branches");
429 style_adunit_config(ADUNIT_RIGHT_OK);
430 style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
431 login_anonymous_available();
432
433 brlist_create_temp_table();
434 db_prepare(&q, "SELECT * FROM tmp_brlist ORDER BY mtime DESC");
435 rNow = db_double(0.0, "SELECT julianday('now')");
436 @ <div class="brlist">
437 @ <table class='sortable' data-column-types='tkNtt' data-init-sort='2'>
438 @ <thead><tr>
439 @ <th>Branch Name</th>
@@ -446,11 +464,11 @@
464 @ <tr style="background-color:%s(zBgClr)">
465 }else{
466 @ <tr>
467 }
468 @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
469 @ <td data-sortkey="%016llx(iMtime)">%s(zAge)</td>
470 @ <td>%d(nCkin)</td>
471 fossil_free(zAge);
472 @ <td>%s(isClosed?"closed":"")</td>
473 if( zMergeTo ){
474 @ <td>merged into
475
+1 -1
--- src/browse.c
+++ src/browse.c
@@ -942,11 +942,11 @@
942942
}else if( rAge*24.0<36 ){
943943
return mprintf("%.1f hours", rAge*24.0);
944944
}else if( rAge<365.0 ){
945945
return mprintf("%.1f days", rAge);
946946
}else{
947
- return mprintf("%.2f years", rAge/365.0);
947
+ return mprintf("%.2f years", rAge/365.2425);
948948
}
949949
}
950950
951951
/*
952952
** COMMAND: test-fileage
953953
--- src/browse.c
+++ src/browse.c
@@ -942,11 +942,11 @@
942 }else if( rAge*24.0<36 ){
943 return mprintf("%.1f hours", rAge*24.0);
944 }else if( rAge<365.0 ){
945 return mprintf("%.1f days", rAge);
946 }else{
947 return mprintf("%.2f years", rAge/365.0);
948 }
949 }
950
951 /*
952 ** COMMAND: test-fileage
953
--- src/browse.c
+++ src/browse.c
@@ -942,11 +942,11 @@
942 }else if( rAge*24.0<36 ){
943 return mprintf("%.1f hours", rAge*24.0);
944 }else if( rAge<365.0 ){
945 return mprintf("%.1f days", rAge);
946 }else{
947 return mprintf("%.2f years", rAge/365.2425);
948 }
949 }
950
951 /*
952 ** COMMAND: test-fileage
953
+1 -1
--- src/cache.c
+++ src/cache.c
@@ -344,11 +344,11 @@
344344
}
345345
346346
/*
347347
** WEBPAGE: cachestat
348348
**
349
-** Show information about the webpage cache. Requires Admin privilege.
349
+** Show information about the webpage cache. Requires Setup privilege.
350350
*/
351351
void cache_page(void){
352352
sqlite3 *db;
353353
sqlite3_stmt *pStmt;
354354
char zBuf[100];
355355
--- src/cache.c
+++ src/cache.c
@@ -344,11 +344,11 @@
344 }
345
346 /*
347 ** WEBPAGE: cachestat
348 **
349 ** Show information about the webpage cache. Requires Admin privilege.
350 */
351 void cache_page(void){
352 sqlite3 *db;
353 sqlite3_stmt *pStmt;
354 char zBuf[100];
355
--- src/cache.c
+++ src/cache.c
@@ -344,11 +344,11 @@
344 }
345
346 /*
347 ** WEBPAGE: cachestat
348 **
349 ** Show information about the webpage cache. Requires Setup privilege.
350 */
351 void cache_page(void){
352 sqlite3 *db;
353 sqlite3_stmt *pStmt;
354 char zBuf[100];
355
+67 -35
--- src/capabilities.c
+++ src/capabilities.c
@@ -228,96 +228,128 @@
228228
** The following structure holds descriptions of the various capabilities.
229229
*/
230230
static struct Caps {
231231
char cCap; /* The capability letter */
232232
unsigned short eClass; /* The "class" for this capability */
233
+ unsigned nUser; /* Number of users with this capability */
233234
char *zAbbrev; /* Abbreviated mnemonic name */
234235
char *zOneLiner; /* One-line summary */
235236
} aCap[] = {
236
- { 'a', CAPCLASS_SUPER,
237
+ { 'a', CAPCLASS_SUPER, 0,
237238
"Admin", "Create and delete users" },
238
- { 'b', CAPCLASS_WIKI|CAPCLASS_TKT,
239
+ { 'b', CAPCLASS_WIKI|CAPCLASS_TKT, 0,
239240
"Attach", "Add attchments to wiki or tickets" },
240
- { 'c', CAPCLASS_TKT,
241
+ { 'c', CAPCLASS_TKT, 0,
241242
"Append-Tkt", "Append to existing tickets" },
242
- { 'd', CAPCLASS_WIKI|CAPCLASS_TKT,
243
+ { 'd', CAPCLASS_WIKI|CAPCLASS_TKT, 0,
243244
"Delete", "Delete wiki or tickets" },
244
- { 'e', CAPCLASS_DATA,
245
+ { 'e', CAPCLASS_DATA, 0,
245246
"View-PII", "View sensitive info such as email addresses" },
246
- { 'f', CAPCLASS_WIKI,
247
+ { 'f', CAPCLASS_WIKI, 0,
247248
"New-Wiki", "Create new wiki pages" },
248
- { 'g', CAPCLASS_DATA,
249
+ { 'g', CAPCLASS_DATA, 0,
249250
"Clone", "Clone the repository" },
250
- { 'h', CAPCLASS_OTHER,
251
+ { 'h', CAPCLASS_OTHER, 0,
251252
"Hyperlinks", "Show hyperlinks to detailed repository history" },
252
- { 'i', CAPCLASS_CODE,
253
+ { 'i', CAPCLASS_CODE, 0,
253254
"Check-In", "Check-in code changes" },
254
- { 'j', CAPCLASS_WIKI,
255
+ { 'j', CAPCLASS_WIKI, 0,
255256
"Read-Wiki", "View wiki pages" },
256
- { 'k', CAPCLASS_WIKI,
257
+ { 'k', CAPCLASS_WIKI, 0,
257258
"Write-Wiki", "Edit wiki pages" },
258
- { 'l', CAPCLASS_WIKI|CAPCLASS_SUPER,
259
+ { 'l', CAPCLASS_WIKI|CAPCLASS_SUPER, 0,
259260
"Mod-Wiki", "Moderator for wiki pages" },
260
- { 'm', CAPCLASS_WIKI,
261
+ { 'm', CAPCLASS_WIKI, 0,
261262
"Append-Wiki", "Append to wiki pages" },
262
- { 'n', CAPCLASS_TKT,
263
+ { 'n', CAPCLASS_TKT, 0,
263264
"New-Tkt", "Create new tickets" },
264
- { 'o', CAPCLASS_CODE,
265
+ { 'o', CAPCLASS_CODE, 0,
265266
"Check-Out", "Check out code" },
266
- { 'p', CAPCLASS_OTHER,
267
+ { 'p', CAPCLASS_OTHER, 0,
267268
"Password", "Change your own password" },
268
- { 'q', CAPCLASS_TKT|CAPCLASS_SUPER,
269
+ { 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
269270
"Mod-Tkt", "Moderate tickets" },
270
- { 'r', CAPCLASS_TKT,
271
+ { 'r', CAPCLASS_TKT, 0,
271272
"Read-Tkt", "View tickets" },
272
- { 's', CAPCLASS_SUPER,
273
+ { 's', CAPCLASS_SUPER, 0,
273274
"Superuser", "Setup and configure the respository" },
274
- { 't', CAPCLASS_TKT,
275
+ { 't', CAPCLASS_TKT, 0,
275276
"Reports", "Create new ticket report formats" },
276
- { 'u', CAPCLASS_OTHER,
277
+ { 'u', CAPCLASS_OTHER, 0,
277278
"Reader", "Inherit all the capabilities of the \"reader\" user" },
278
- { 'v', CAPCLASS_OTHER,
279
+ { 'v', CAPCLASS_OTHER, 0,
279280
"Developer", "Inherit all capabilities of the \"developer\" user" },
280
- { 'w', CAPCLASS_TKT,
281
+ { 'w', CAPCLASS_TKT, 0,
281282
"Write-Tkt", "Edit tickets" },
282
- { 'x', CAPCLASS_DATA,
283
+ { 'x', CAPCLASS_DATA, 0,
283284
"Private", "Push and/or pull private branches" },
284
- { 'y', CAPCLASS_SUPER,
285
+ { 'y', CAPCLASS_SUPER, 0,
285286
"Write-UV", "Push unversioned content" },
286
- { 'z', CAPCLASS_CODE,
287
+ { 'z', CAPCLASS_CODE, 0,
287288
"Zip-Download", "Download a ZIP archive, tarball, or SQL archive" },
288
- { '2', CAPCLASS_FORUM,
289
+ { '2', CAPCLASS_FORUM, 0,
289290
"Forum-Read", "Read forum posts by others" },
290
- { '3', CAPCLASS_FORUM,
291
+ { '3', CAPCLASS_FORUM, 0,
291292
"Forum-Write", "Create new forum messages" },
292
- { '4', CAPCLASS_FORUM,
293
+ { '4', CAPCLASS_FORUM, 0,
293294
"Forum-Trusted", "Create forum messages that bypass moderation" },
294
- { '5', CAPCLASS_FORUM|CAPCLASS_SUPER,
295
+ { '5', CAPCLASS_FORUM|CAPCLASS_SUPER, 0,
295296
"Forum-Mod", "Moderator for forum messages" },
296
- { '6', CAPCLASS_FORUM|CAPCLASS_SUPER,
297
+ { '6', CAPCLASS_FORUM|CAPCLASS_SUPER, 0,
297298
"Forum-Admin", "Set or remove capability '4' from other users" },
298
- { '7', CAPCLASS_ALERT,
299
+ { '7', CAPCLASS_ALERT, 0,
299300
"Alerts", "Sign up for email alerts" },
300
- { 'A', CAPCLASS_ALERT|CAPCLASS_SUPER,
301
+ { 'A', CAPCLASS_ALERT|CAPCLASS_SUPER, 0,
301302
"Announce", "Send announcements to all subscribers" },
302
- { 'D', CAPCLASS_OTHER,
303
+ { 'D', CAPCLASS_OTHER, 0,
303304
"Debug", "Enable debugging features" },
304305
};
306
+
307
+/*
308
+** Populate the aCap[].nUser values based on the current content
309
+** of the USER table.
310
+*/
311
+void capabilities_count(void){
312
+ int i;
313
+ static int done = 0;
314
+ Stmt q;
315
+ if( done ) return;
316
+ db_prepare(&q, "SELECT fullcap(cap) FROM user");
317
+ while( db_step(&q)==SQLITE_ROW ){
318
+ const char *zCap = db_column_text(&q, 0);
319
+ if( zCap==0 || zCap[0]==0 ) continue;
320
+ for(i=0; i<sizeof(aCap)/sizeof(aCap[0]); i++){
321
+ if( strchr(zCap, aCap[i].cCap) ) aCap[i].nUser++;
322
+ }
323
+ }
324
+ db_finalize(&q);
325
+ done = 1;
326
+}
305327
306328
307329
/*
308330
** Generate HTML that lists all of the capability letters together with
309331
** a brief summary of what each letter means.
310332
*/
311333
void capabilities_table(unsigned mClass){
312334
int i;
335
+ if( g.perm.Admin ) capabilities_count();
313336
@ <table>
337
+ @ <tbody>
314338
for(i=0; i<sizeof(aCap)/sizeof(aCap[0]); i++){
339
+ int n;
315340
if( (aCap[i].eClass & mClass)==0 ) continue;
316341
@ <tr><th valign="top">%c(aCap[i].cCap)</th>
317
- @ <td><i>%h(aCap[i].zAbbrev):</i> %h(aCap[i].zOneLiner)</td></tr>
342
+ @ <td>%h(aCap[i].zAbbrev)</td><td>%h(aCap[i].zOneLiner)</td>\
343
+ n = aCap[i].nUser;
344
+ if( n && g.perm.Admin ){
345
+ @ <td><a href="%R/setup_ulist?with=%c(aCap[i].cCap)">\
346
+ @ %d(n) user%s(n>1?"s":"")</a></td>\
347
+ }
348
+ @ </tr>
318349
}
350
+ @ </tbody>
319351
@ </table>
320352
}
321353
322354
/*
323355
** Generate a "capability summary table" that shows the major capabilities
324356
--- src/capabilities.c
+++ src/capabilities.c
@@ -228,96 +228,128 @@
228 ** The following structure holds descriptions of the various capabilities.
229 */
230 static struct Caps {
231 char cCap; /* The capability letter */
232 unsigned short eClass; /* The "class" for this capability */
 
233 char *zAbbrev; /* Abbreviated mnemonic name */
234 char *zOneLiner; /* One-line summary */
235 } aCap[] = {
236 { 'a', CAPCLASS_SUPER,
237 "Admin", "Create and delete users" },
238 { 'b', CAPCLASS_WIKI|CAPCLASS_TKT,
239 "Attach", "Add attchments to wiki or tickets" },
240 { 'c', CAPCLASS_TKT,
241 "Append-Tkt", "Append to existing tickets" },
242 { 'd', CAPCLASS_WIKI|CAPCLASS_TKT,
243 "Delete", "Delete wiki or tickets" },
244 { 'e', CAPCLASS_DATA,
245 "View-PII", "View sensitive info such as email addresses" },
246 { 'f', CAPCLASS_WIKI,
247 "New-Wiki", "Create new wiki pages" },
248 { 'g', CAPCLASS_DATA,
249 "Clone", "Clone the repository" },
250 { 'h', CAPCLASS_OTHER,
251 "Hyperlinks", "Show hyperlinks to detailed repository history" },
252 { 'i', CAPCLASS_CODE,
253 "Check-In", "Check-in code changes" },
254 { 'j', CAPCLASS_WIKI,
255 "Read-Wiki", "View wiki pages" },
256 { 'k', CAPCLASS_WIKI,
257 "Write-Wiki", "Edit wiki pages" },
258 { 'l', CAPCLASS_WIKI|CAPCLASS_SUPER,
259 "Mod-Wiki", "Moderator for wiki pages" },
260 { 'm', CAPCLASS_WIKI,
261 "Append-Wiki", "Append to wiki pages" },
262 { 'n', CAPCLASS_TKT,
263 "New-Tkt", "Create new tickets" },
264 { 'o', CAPCLASS_CODE,
265 "Check-Out", "Check out code" },
266 { 'p', CAPCLASS_OTHER,
267 "Password", "Change your own password" },
268 { 'q', CAPCLASS_TKT|CAPCLASS_SUPER,
269 "Mod-Tkt", "Moderate tickets" },
270 { 'r', CAPCLASS_TKT,
271 "Read-Tkt", "View tickets" },
272 { 's', CAPCLASS_SUPER,
273 "Superuser", "Setup and configure the respository" },
274 { 't', CAPCLASS_TKT,
275 "Reports", "Create new ticket report formats" },
276 { 'u', CAPCLASS_OTHER,
277 "Reader", "Inherit all the capabilities of the \"reader\" user" },
278 { 'v', CAPCLASS_OTHER,
279 "Developer", "Inherit all capabilities of the \"developer\" user" },
280 { 'w', CAPCLASS_TKT,
281 "Write-Tkt", "Edit tickets" },
282 { 'x', CAPCLASS_DATA,
283 "Private", "Push and/or pull private branches" },
284 { 'y', CAPCLASS_SUPER,
285 "Write-UV", "Push unversioned content" },
286 { 'z', CAPCLASS_CODE,
287 "Zip-Download", "Download a ZIP archive, tarball, or SQL archive" },
288 { '2', CAPCLASS_FORUM,
289 "Forum-Read", "Read forum posts by others" },
290 { '3', CAPCLASS_FORUM,
291 "Forum-Write", "Create new forum messages" },
292 { '4', CAPCLASS_FORUM,
293 "Forum-Trusted", "Create forum messages that bypass moderation" },
294 { '5', CAPCLASS_FORUM|CAPCLASS_SUPER,
295 "Forum-Mod", "Moderator for forum messages" },
296 { '6', CAPCLASS_FORUM|CAPCLASS_SUPER,
297 "Forum-Admin", "Set or remove capability '4' from other users" },
298 { '7', CAPCLASS_ALERT,
299 "Alerts", "Sign up for email alerts" },
300 { 'A', CAPCLASS_ALERT|CAPCLASS_SUPER,
301 "Announce", "Send announcements to all subscribers" },
302 { 'D', CAPCLASS_OTHER,
303 "Debug", "Enable debugging features" },
304 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
306
307 /*
308 ** Generate HTML that lists all of the capability letters together with
309 ** a brief summary of what each letter means.
310 */
311 void capabilities_table(unsigned mClass){
312 int i;
 
313 @ <table>
 
314 for(i=0; i<sizeof(aCap)/sizeof(aCap[0]); i++){
 
315 if( (aCap[i].eClass & mClass)==0 ) continue;
316 @ <tr><th valign="top">%c(aCap[i].cCap)</th>
317 @ <td><i>%h(aCap[i].zAbbrev):</i> %h(aCap[i].zOneLiner)</td></tr>
 
 
 
 
 
 
318 }
 
319 @ </table>
320 }
321
322 /*
323 ** Generate a "capability summary table" that shows the major capabilities
324
--- src/capabilities.c
+++ src/capabilities.c
@@ -228,96 +228,128 @@
228 ** The following structure holds descriptions of the various capabilities.
229 */
230 static struct Caps {
231 char cCap; /* The capability letter */
232 unsigned short eClass; /* The "class" for this capability */
233 unsigned nUser; /* Number of users with this capability */
234 char *zAbbrev; /* Abbreviated mnemonic name */
235 char *zOneLiner; /* One-line summary */
236 } aCap[] = {
237 { 'a', CAPCLASS_SUPER, 0,
238 "Admin", "Create and delete users" },
239 { 'b', CAPCLASS_WIKI|CAPCLASS_TKT, 0,
240 "Attach", "Add attchments to wiki or tickets" },
241 { 'c', CAPCLASS_TKT, 0,
242 "Append-Tkt", "Append to existing tickets" },
243 { 'd', CAPCLASS_WIKI|CAPCLASS_TKT, 0,
244 "Delete", "Delete wiki or tickets" },
245 { 'e', CAPCLASS_DATA, 0,
246 "View-PII", "View sensitive info such as email addresses" },
247 { 'f', CAPCLASS_WIKI, 0,
248 "New-Wiki", "Create new wiki pages" },
249 { 'g', CAPCLASS_DATA, 0,
250 "Clone", "Clone the repository" },
251 { 'h', CAPCLASS_OTHER, 0,
252 "Hyperlinks", "Show hyperlinks to detailed repository history" },
253 { 'i', CAPCLASS_CODE, 0,
254 "Check-In", "Check-in code changes" },
255 { 'j', CAPCLASS_WIKI, 0,
256 "Read-Wiki", "View wiki pages" },
257 { 'k', CAPCLASS_WIKI, 0,
258 "Write-Wiki", "Edit wiki pages" },
259 { 'l', CAPCLASS_WIKI|CAPCLASS_SUPER, 0,
260 "Mod-Wiki", "Moderator for wiki pages" },
261 { 'm', CAPCLASS_WIKI, 0,
262 "Append-Wiki", "Append to wiki pages" },
263 { 'n', CAPCLASS_TKT, 0,
264 "New-Tkt", "Create new tickets" },
265 { 'o', CAPCLASS_CODE, 0,
266 "Check-Out", "Check out code" },
267 { 'p', CAPCLASS_OTHER, 0,
268 "Password", "Change your own password" },
269 { 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
270 "Mod-Tkt", "Moderate tickets" },
271 { 'r', CAPCLASS_TKT, 0,
272 "Read-Tkt", "View tickets" },
273 { 's', CAPCLASS_SUPER, 0,
274 "Superuser", "Setup and configure the respository" },
275 { 't', CAPCLASS_TKT, 0,
276 "Reports", "Create new ticket report formats" },
277 { 'u', CAPCLASS_OTHER, 0,
278 "Reader", "Inherit all the capabilities of the \"reader\" user" },
279 { 'v', CAPCLASS_OTHER, 0,
280 "Developer", "Inherit all capabilities of the \"developer\" user" },
281 { 'w', CAPCLASS_TKT, 0,
282 "Write-Tkt", "Edit tickets" },
283 { 'x', CAPCLASS_DATA, 0,
284 "Private", "Push and/or pull private branches" },
285 { 'y', CAPCLASS_SUPER, 0,
286 "Write-UV", "Push unversioned content" },
287 { 'z', CAPCLASS_CODE, 0,
288 "Zip-Download", "Download a ZIP archive, tarball, or SQL archive" },
289 { '2', CAPCLASS_FORUM, 0,
290 "Forum-Read", "Read forum posts by others" },
291 { '3', CAPCLASS_FORUM, 0,
292 "Forum-Write", "Create new forum messages" },
293 { '4', CAPCLASS_FORUM, 0,
294 "Forum-Trusted", "Create forum messages that bypass moderation" },
295 { '5', CAPCLASS_FORUM|CAPCLASS_SUPER, 0,
296 "Forum-Mod", "Moderator for forum messages" },
297 { '6', CAPCLASS_FORUM|CAPCLASS_SUPER, 0,
298 "Forum-Admin", "Set or remove capability '4' from other users" },
299 { '7', CAPCLASS_ALERT, 0,
300 "Alerts", "Sign up for email alerts" },
301 { 'A', CAPCLASS_ALERT|CAPCLASS_SUPER, 0,
302 "Announce", "Send announcements to all subscribers" },
303 { 'D', CAPCLASS_OTHER, 0,
304 "Debug", "Enable debugging features" },
305 };
306
307 /*
308 ** Populate the aCap[].nUser values based on the current content
309 ** of the USER table.
310 */
311 void capabilities_count(void){
312 int i;
313 static int done = 0;
314 Stmt q;
315 if( done ) return;
316 db_prepare(&q, "SELECT fullcap(cap) FROM user");
317 while( db_step(&q)==SQLITE_ROW ){
318 const char *zCap = db_column_text(&q, 0);
319 if( zCap==0 || zCap[0]==0 ) continue;
320 for(i=0; i<sizeof(aCap)/sizeof(aCap[0]); i++){
321 if( strchr(zCap, aCap[i].cCap) ) aCap[i].nUser++;
322 }
323 }
324 db_finalize(&q);
325 done = 1;
326 }
327
328
329 /*
330 ** Generate HTML that lists all of the capability letters together with
331 ** a brief summary of what each letter means.
332 */
333 void capabilities_table(unsigned mClass){
334 int i;
335 if( g.perm.Admin ) capabilities_count();
336 @ <table>
337 @ <tbody>
338 for(i=0; i<sizeof(aCap)/sizeof(aCap[0]); i++){
339 int n;
340 if( (aCap[i].eClass & mClass)==0 ) continue;
341 @ <tr><th valign="top">%c(aCap[i].cCap)</th>
342 @ <td>%h(aCap[i].zAbbrev)</td><td>%h(aCap[i].zOneLiner)</td>\
343 n = aCap[i].nUser;
344 if( n && g.perm.Admin ){
345 @ <td><a href="%R/setup_ulist?with=%c(aCap[i].cCap)">\
346 @ %d(n) user%s(n>1?"s":"")</a></td>\
347 }
348 @ </tr>
349 }
350 @ </tbody>
351 @ </table>
352 }
353
354 /*
355 ** Generate a "capability summary table" that shows the major capabilities
356
+13
--- src/cgi.c
+++ src/cgi.c
@@ -2067,5 +2067,18 @@
20672067
int cgi_is_loopback(const char *zIpAddr){
20682068
return fossil_strcmp(zIpAddr, "127.0.0.1")==0 ||
20692069
fossil_strcmp(zIpAddr, "::ffff:127.0.0.1")==0 ||
20702070
fossil_strcmp(zIpAddr, "::1")==0;
20712071
}
2072
+
2073
+/*
2074
+** Return true if the HTTP request is likely to be from a small-screen
2075
+** mobile device.
2076
+**
2077
+** The returned value is a guess. Use it only for setting up defaults.
2078
+*/
2079
+int cgi_from_mobile(void){
2080
+ const char *zAgent = P("HTTP_USER_AGENT");
2081
+ if( zAgent==0 ) return 0;
2082
+ if( sqlite3_strglob("*iPad*", zAgent)==0 ) return 0;
2083
+ return sqlite3_strlike("%mobile%", zAgent, 0)==0;
2084
+}
20722085
--- src/cgi.c
+++ src/cgi.c
@@ -2067,5 +2067,18 @@
2067 int cgi_is_loopback(const char *zIpAddr){
2068 return fossil_strcmp(zIpAddr, "127.0.0.1")==0 ||
2069 fossil_strcmp(zIpAddr, "::ffff:127.0.0.1")==0 ||
2070 fossil_strcmp(zIpAddr, "::1")==0;
2071 }
 
 
 
 
 
 
 
 
 
 
 
 
 
2072
--- src/cgi.c
+++ src/cgi.c
@@ -2067,5 +2067,18 @@
2067 int cgi_is_loopback(const char *zIpAddr){
2068 return fossil_strcmp(zIpAddr, "127.0.0.1")==0 ||
2069 fossil_strcmp(zIpAddr, "::ffff:127.0.0.1")==0 ||
2070 fossil_strcmp(zIpAddr, "::1")==0;
2071 }
2072
2073 /*
2074 ** Return true if the HTTP request is likely to be from a small-screen
2075 ** mobile device.
2076 **
2077 ** The returned value is a guess. Use it only for setting up defaults.
2078 */
2079 int cgi_from_mobile(void){
2080 const char *zAgent = P("HTTP_USER_AGENT");
2081 if( zAgent==0 ) return 0;
2082 if( sqlite3_strglob("*iPad*", zAgent)==0 ) return 0;
2083 return sqlite3_strlike("%mobile%", zAgent, 0)==0;
2084 }
2085
+132 -28
--- src/comformat.c
+++ src/comformat.c
@@ -2,11 +2,11 @@
22
** Copyright (c) 2007 D. Richard Hipp
33
**
44
** This program is free software; you can redistribute it and/or
55
** modify it under the terms of the Simplified BSD License (also
66
** known as the "2-Clause License" or "FreeBSD License".)
7
-
7
+**
88
** This program is distributed in the hope that it will be useful,
99
** but without any warranty; without even the implied warranty of
1010
** merchantability or fitness for a particular purpose.
1111
**
1212
** Author contact information:
@@ -95,21 +95,20 @@
9595
#endif
9696
}
9797
9898
/*
9999
** This function checks the current line being printed against the original
100
-** comment text. Upon matching, it emits a new line and updates the provided
101
-** character and line counts, if applicable.
100
+** comment text. Upon matching, it updates the provided character and line
101
+** counts, if applicable. The caller needs to emit a new line, if desired.
102102
*/
103103
static int comment_check_orig(
104104
const char *zOrigText, /* [in] Original comment text ONLY, may be NULL. */
105105
const char *zLine, /* [in] The comment line to print. */
106106
int *pCharCnt, /* [in/out] Pointer to the line character count. */
107107
int *pLineCnt /* [in/out] Pointer to the total line count. */
108108
){
109109
if( zOrigText && fossil_strcmp(zLine, zOrigText)==0 ){
110
- fossil_print("\n");
111110
if( pCharCnt ) *pCharCnt = 0;
112111
if( pLineCnt ) (*pLineCnt)++;
113112
return 1;
114113
}
115114
return 0;
@@ -121,37 +120,76 @@
121120
** zero if such a character cannot be found. For the purposes of this
122121
** algorithm, the NUL character is treated the same as a spacing character.
123122
*/
124123
static int comment_next_space(
125124
const char *zLine, /* [in] The comment line being printed. */
126
- int index /* [in] The current character index being handled. */
125
+ int index, /* [in] The current character index being handled. */
126
+ int *distUTF8 /* [out] Distance to next space in UTF-8 sequences. */
127127
){
128128
int nextIndex = index + 1;
129
+ int fNonASCII=0;
129130
for(;;){
130131
char c = zLine[nextIndex];
132
+ if( (c&0x80)==0x80 ) fNonASCII=1;
131133
if( c==0 || fossil_isspace(c) ){
134
+ if( distUTF8 ){
135
+ if( fNonASCII!=0 ){
136
+ *distUTF8 = strlen_utf8(&zLine[index], nextIndex-index);
137
+ }else{
138
+ *distUTF8 = nextIndex-index;
139
+ }
140
+ }
132141
return nextIndex;
133142
}
134143
nextIndex++;
135144
}
136145
return 0; /* NOT REACHED */
137146
}
138147
139148
/*
140
-** This function is called when printing a logical comment line to perform
141
-** the necessary indenting.
149
+** Count the number of UTF-8 sequences in a string. Incomplete, ill-formed and
150
+** overlong sequences are counted as one sequence. The invalid lead bytes 0xC0
151
+** to 0xC1 and 0xF5 to 0xF7 are allowed to initiate (ill-formed) 2- and 4-byte
152
+** sequences, respectively, the other invalid lead bytes 0xF8 to 0xFF are
153
+** treated as invalid 1-byte sequences (as lone trail bytes).
154
+** Combining characters and East Asian Wide and Fullwidth characters are counted
155
+** as one, so this function does not calculate the effective "display width".
156
+*/
157
+int strlen_utf8(const char *zString, int lengthBytes){
158
+ int i; /* Counted bytes. */
159
+ int lengthUTF8; /* Counted UTF-8 sequences. */
160
+#if 0
161
+ assert( lengthBytes>=0 );
162
+#endif
163
+ for(i=0, lengthUTF8=0; i<lengthBytes; i++, lengthUTF8++){
164
+ char c = zString[i];
165
+ int cchUTF8=1; /* Code units consumed. */
166
+ int maxUTF8=1; /* Expected sequence length. */
167
+ if( (c&0xe0)==0xc0 )maxUTF8=2; /* UTF-8 lead byte 110vvvvv */
168
+ else if( (c&0xf0)==0xe0 )maxUTF8=3; /* UTF-8 lead byte 1110vvvv */
169
+ else if( (c&0xf8)==0xf0 )maxUTF8=4; /* UTF-8 lead byte 11110vvv */
170
+ while( cchUTF8<maxUTF8 &&
171
+ i<lengthBytes-1 &&
172
+ (zString[i+1]&0xc0)==0x80 ){ /* UTF-8 trail byte 10vvvvvv */
173
+ cchUTF8++;
174
+ i++;
175
+ }
176
+ }
177
+ return lengthUTF8;
178
+}
179
+
180
+/*
181
+** This function is called when printing a logical comment line to calculate
182
+** the necessary indenting. The caller needs to emit the indenting spaces.
142183
*/
143
-static void comment_print_indent(
184
+static void comment_calc_indent(
144185
const char *zLine, /* [in] The comment line being printed. */
145186
int indent, /* [in] Number of spaces to indent, zero for none. */
146187
int trimCrLf, /* [in] Non-zero to trim leading/trailing CR/LF. */
147188
int trimSpace, /* [in] Non-zero to trim leading/trailing spaces. */
148189
int *piIndex /* [in/out] Pointer to first non-space character. */
149190
){
150
- if( indent>0 ){
151
- fossil_print("%*s", indent, "");
152
- }
153191
if( zLine && piIndex ){
154192
int index = *piIndex;
155193
if( trimCrLf ){
156194
while( zLine[index]=='\r' || zLine[index]=='\n' ){ index++; }
157195
}
@@ -179,26 +217,56 @@
179217
int wordBreak, /* [in] Non-zero to try breaking on word boundaries. */
180218
int origBreak, /* [in] Non-zero to break before original comment. */
181219
int *pLineCnt, /* [in/out] Pointer to the total line count. */
182220
const char **pzLine /* [out] Pointer to the end of the logical line. */
183221
){
184
- int index = 0, charCnt = 0, lineCnt = 0, maxChars;
222
+ int index = 0, charCnt = 0, lineCnt = 0, maxChars, i;
223
+ char zBuf[400]; int iBuf=0; /* Output buffer and counter. */
224
+ int cchUTF8, maxUTF8; /* Helper variables to count UTF-8 sequences. */
185225
if( !zLine ) return;
186226
if( lineChars<=0 ) return;
187
- comment_print_indent(zLine, indent, trimCrLf, trimSpace, &index);
227
+#if 0
228
+ assert( indent<sizeof(zBuf)-5 ); /* See following comments to explain */
229
+ assert( origIndent<sizeof(zBuf)-5 ); /* these limits. */
230
+#endif
231
+ if( indent>sizeof(zBuf)-6 ){
232
+ /* Limit initial indent to fit output buffer. */
233
+ indent = sizeof(zBuf)-6;
234
+ }
235
+ comment_calc_indent(zLine, indent, trimCrLf, trimSpace, &index);
236
+ if( indent>0 ){
237
+ for(i=0; i<indent; i++){
238
+ zBuf[iBuf++] = ' ';
239
+ }
240
+ }
241
+ if( origIndent>sizeof(zBuf)-6 ){
242
+ /* Limit line indent to fit output buffer. */
243
+ origIndent = sizeof(zBuf)-6;
244
+ }
188245
maxChars = lineChars;
189246
for(;;){
190247
int useChars = 1;
191248
char c = zLine[index];
249
+ /* Flush the output buffer if there's no space left for at least one more
250
+ ** (potentially 4-byte) UTF-8 sequence, one level of indentation spaces,
251
+ ** a new line, and a terminating NULL. */
252
+ if( iBuf>sizeof(zBuf)-origIndent-6 ){
253
+ zBuf[iBuf]=0;
254
+ iBuf=0;
255
+ fossil_print("%s", zBuf);
256
+ }
192257
if( c==0 ){
193258
break;
194259
}else{
195260
if( origBreak && index>0 ){
196261
const char *zCurrent = &zLine[index];
197262
if( comment_check_orig(zOrigText, zCurrent, &charCnt, &lineCnt) ){
198
- comment_print_indent(zCurrent, origIndent, trimCrLf, trimSpace,
199
- &index);
263
+ zBuf[iBuf++] = '\n';
264
+ comment_calc_indent(zLine, origIndent, trimCrLf, trimSpace, &index);
265
+ for( i=0; i<origIndent; i++ ){
266
+ zBuf[iBuf++] = ' ';
267
+ }
200268
maxChars = lineChars;
201269
}
202270
}
203271
index++;
204272
}
@@ -205,38 +273,57 @@
205273
if( c=='\n' ){
206274
lineCnt++;
207275
charCnt = 0;
208276
useChars = 0;
209277
}else if( c=='\t' ){
210
- int nextIndex = comment_next_space(zLine, index);
211
- if( nextIndex<=0 || (nextIndex-index)>maxChars ){
278
+ int distUTF8;
279
+ int nextIndex = comment_next_space(zLine, index, &distUTF8);
280
+ if( nextIndex<=0 || distUTF8>maxChars ){
212281
break;
213282
}
214283
charCnt++;
215284
useChars = COMMENT_TAB_WIDTH;
216285
if( maxChars<useChars ){
217
- fossil_print(" ");
286
+ zBuf[iBuf++] = ' ';
218287
break;
219288
}
220289
}else if( wordBreak && fossil_isspace(c) ){
221
- int nextIndex = comment_next_space(zLine, index);
222
- if( nextIndex<=0 || (nextIndex-index)>maxChars ){
290
+ int distUTF8;
291
+ int nextIndex = comment_next_space(zLine, index, &distUTF8);
292
+ if( nextIndex<=0 || distUTF8>maxChars ){
223293
break;
224294
}
225295
charCnt++;
226296
}else{
227297
charCnt++;
228298
}
229299
assert( c!='\n' || charCnt==0 );
230
- fossil_print("%c", c);
231
- if( (c&0x80)==0 || (zLine[index+1]&0xc0)!=0xc0 ) maxChars -= useChars;
300
+ zBuf[iBuf++] = c;
301
+ /* Skip over UTF-8 sequences, see comment on strlen_utf8() for details. */
302
+ cchUTF8=1; /* Code units consumed. */
303
+ maxUTF8=1; /* Expected sequence length. */
304
+ if( (c&0xe0)==0xc0 )maxUTF8=2; /* UTF-8 lead byte 110vvvvv */
305
+ else if( (c&0xf0)==0xe0 )maxUTF8=3; /* UTF-8 lead byte 1110vvvv */
306
+ else if( (c&0xf8)==0xf0 )maxUTF8=4; /* UTF-8 lead byte 11110vvv */
307
+ while( cchUTF8<maxUTF8 &&
308
+ (zLine[index]&0xc0)==0x80 ){ /* UTF-8 trail byte 10vvvvvv */
309
+ cchUTF8++;
310
+ zBuf[iBuf++] = zLine[index++];
311
+ }
312
+ maxChars -= useChars;
232313
if( maxChars<=0 ) break;
233314
if( c=='\n' ) break;
234315
}
235316
if( charCnt>0 ){
236
- fossil_print("\n");
317
+ zBuf[iBuf++] = '\n';
237318
lineCnt++;
319
+ }
320
+ /* Flush the remaining output buffer. */
321
+ if( iBuf>0 ){
322
+ zBuf[iBuf]=0;
323
+ iBuf=0;
324
+ fossil_print("%s", zBuf);
238325
}
239326
if( pLineCnt ){
240327
*pLineCnt += lineCnt;
241328
}
242329
if( pzLine ){
@@ -259,25 +346,27 @@
259346
const char *zText, /* The comment text to be printed. */
260347
int indent, /* Number of spaces to indent each non-initial line. */
261348
int width /* Maximum number of characters per line. */
262349
){
263350
int maxChars = width - indent;
264
- int si, sk, i, k;
351
+ int si, sk, i, k, kc;
265352
int doIndent = 0;
266353
char *zBuf;
267354
char zBuffer[400];
268355
int lineCnt = 0;
356
+ int cchUTF8, maxUTF8; /* Helper variables to count UTF-8 sequences. */
269357
270358
if( width<0 ){
271359
comment_set_maxchars(indent, &maxChars);
272360
}
273361
if( zText==0 ) zText = "(NULL)";
274362
if( maxChars<=0 ){
275363
maxChars = strlen(zText);
276364
}
277
- if( maxChars >= (sizeof(zBuffer)) ){
278
- zBuf = fossil_malloc(maxChars+1);
365
+ /* Ensure the buffer can hold the longest-possible UTF-8 sequences. */
366
+ if( maxChars >= (sizeof(zBuffer)/4-1) ){
367
+ zBuf = fossil_malloc(maxChars*4+1);
279368
}else{
280369
zBuf = zBuffer;
281370
}
282371
for(;;){
283372
while( fossil_isspace(zText[0]) ){ zText++; }
@@ -287,13 +376,28 @@
287376
lineCnt = 1;
288377
}
289378
if( zBuf!=zBuffer) fossil_free(zBuf);
290379
return lineCnt;
291380
}
292
- for(sk=si=i=k=0; zText[i] && k<maxChars; i++){
381
+ for(sk=si=i=k=kc=0; zText[i] && kc<maxChars; i++){
293382
char c = zText[i];
294
- if( fossil_isspace(c) ){
383
+ kc++; /* Count complete UTF-8 sequences. */
384
+ /* Skip over UTF-8 sequences, see comment on strlen_utf8() for details. */
385
+ cchUTF8=1; /* Code units consumed. */
386
+ maxUTF8=1; /* Expected sequence length. */
387
+ if( (c&0xe0)==0xc0 )maxUTF8=2; /* UTF-8 lead byte 110vvvvv */
388
+ else if( (c&0xf0)==0xe0 )maxUTF8=3; /* UTF-8 lead byte 1110vvvv */
389
+ else if( (c&0xf8)==0xf0 )maxUTF8=4; /* UTF-8 lead byte 11110vvv */
390
+ if( maxUTF8>1 ){
391
+ zBuf[k++] = c;
392
+ while( cchUTF8<maxUTF8 &&
393
+ (zText[i+1]&0xc0)==0x80 ){ /* UTF-8 trail byte 10vvvvvv */
394
+ cchUTF8++;
395
+ zBuf[k++] = zText[++i];
396
+ }
397
+ }
398
+ else if( fossil_isspace(c) ){
295399
si = i;
296400
sk = k;
297401
if( k==0 || zBuf[k-1]!=' ' ){
298402
zBuf[k++] = ' ';
299403
}
300404
--- src/comformat.c
+++ src/comformat.c
@@ -2,11 +2,11 @@
2 ** Copyright (c) 2007 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause License" or "FreeBSD License".)
7
8 ** This program is distributed in the hope that it will be useful,
9 ** but without any warranty; without even the implied warranty of
10 ** merchantability or fitness for a particular purpose.
11 **
12 ** Author contact information:
@@ -95,21 +95,20 @@
95 #endif
96 }
97
98 /*
99 ** This function checks the current line being printed against the original
100 ** comment text. Upon matching, it emits a new line and updates the provided
101 ** character and line counts, if applicable.
102 */
103 static int comment_check_orig(
104 const char *zOrigText, /* [in] Original comment text ONLY, may be NULL. */
105 const char *zLine, /* [in] The comment line to print. */
106 int *pCharCnt, /* [in/out] Pointer to the line character count. */
107 int *pLineCnt /* [in/out] Pointer to the total line count. */
108 ){
109 if( zOrigText && fossil_strcmp(zLine, zOrigText)==0 ){
110 fossil_print("\n");
111 if( pCharCnt ) *pCharCnt = 0;
112 if( pLineCnt ) (*pLineCnt)++;
113 return 1;
114 }
115 return 0;
@@ -121,37 +120,76 @@
121 ** zero if such a character cannot be found. For the purposes of this
122 ** algorithm, the NUL character is treated the same as a spacing character.
123 */
124 static int comment_next_space(
125 const char *zLine, /* [in] The comment line being printed. */
126 int index /* [in] The current character index being handled. */
 
127 ){
128 int nextIndex = index + 1;
 
129 for(;;){
130 char c = zLine[nextIndex];
 
131 if( c==0 || fossil_isspace(c) ){
 
 
 
 
 
 
 
132 return nextIndex;
133 }
134 nextIndex++;
135 }
136 return 0; /* NOT REACHED */
137 }
138
139 /*
140 ** This function is called when printing a logical comment line to perform
141 ** the necessary indenting.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142 */
143 static void comment_print_indent(
144 const char *zLine, /* [in] The comment line being printed. */
145 int indent, /* [in] Number of spaces to indent, zero for none. */
146 int trimCrLf, /* [in] Non-zero to trim leading/trailing CR/LF. */
147 int trimSpace, /* [in] Non-zero to trim leading/trailing spaces. */
148 int *piIndex /* [in/out] Pointer to first non-space character. */
149 ){
150 if( indent>0 ){
151 fossil_print("%*s", indent, "");
152 }
153 if( zLine && piIndex ){
154 int index = *piIndex;
155 if( trimCrLf ){
156 while( zLine[index]=='\r' || zLine[index]=='\n' ){ index++; }
157 }
@@ -179,26 +217,56 @@
179 int wordBreak, /* [in] Non-zero to try breaking on word boundaries. */
180 int origBreak, /* [in] Non-zero to break before original comment. */
181 int *pLineCnt, /* [in/out] Pointer to the total line count. */
182 const char **pzLine /* [out] Pointer to the end of the logical line. */
183 ){
184 int index = 0, charCnt = 0, lineCnt = 0, maxChars;
 
 
185 if( !zLine ) return;
186 if( lineChars<=0 ) return;
187 comment_print_indent(zLine, indent, trimCrLf, trimSpace, &index);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188 maxChars = lineChars;
189 for(;;){
190 int useChars = 1;
191 char c = zLine[index];
 
 
 
 
 
 
 
 
192 if( c==0 ){
193 break;
194 }else{
195 if( origBreak && index>0 ){
196 const char *zCurrent = &zLine[index];
197 if( comment_check_orig(zOrigText, zCurrent, &charCnt, &lineCnt) ){
198 comment_print_indent(zCurrent, origIndent, trimCrLf, trimSpace,
199 &index);
 
 
 
200 maxChars = lineChars;
201 }
202 }
203 index++;
204 }
@@ -205,38 +273,57 @@
205 if( c=='\n' ){
206 lineCnt++;
207 charCnt = 0;
208 useChars = 0;
209 }else if( c=='\t' ){
210 int nextIndex = comment_next_space(zLine, index);
211 if( nextIndex<=0 || (nextIndex-index)>maxChars ){
 
212 break;
213 }
214 charCnt++;
215 useChars = COMMENT_TAB_WIDTH;
216 if( maxChars<useChars ){
217 fossil_print(" ");
218 break;
219 }
220 }else if( wordBreak && fossil_isspace(c) ){
221 int nextIndex = comment_next_space(zLine, index);
222 if( nextIndex<=0 || (nextIndex-index)>maxChars ){
 
223 break;
224 }
225 charCnt++;
226 }else{
227 charCnt++;
228 }
229 assert( c!='\n' || charCnt==0 );
230 fossil_print("%c", c);
231 if( (c&0x80)==0 || (zLine[index+1]&0xc0)!=0xc0 ) maxChars -= useChars;
 
 
 
 
 
 
 
 
 
 
 
232 if( maxChars<=0 ) break;
233 if( c=='\n' ) break;
234 }
235 if( charCnt>0 ){
236 fossil_print("\n");
237 lineCnt++;
 
 
 
 
 
 
238 }
239 if( pLineCnt ){
240 *pLineCnt += lineCnt;
241 }
242 if( pzLine ){
@@ -259,25 +346,27 @@
259 const char *zText, /* The comment text to be printed. */
260 int indent, /* Number of spaces to indent each non-initial line. */
261 int width /* Maximum number of characters per line. */
262 ){
263 int maxChars = width - indent;
264 int si, sk, i, k;
265 int doIndent = 0;
266 char *zBuf;
267 char zBuffer[400];
268 int lineCnt = 0;
 
269
270 if( width<0 ){
271 comment_set_maxchars(indent, &maxChars);
272 }
273 if( zText==0 ) zText = "(NULL)";
274 if( maxChars<=0 ){
275 maxChars = strlen(zText);
276 }
277 if( maxChars >= (sizeof(zBuffer)) ){
278 zBuf = fossil_malloc(maxChars+1);
 
279 }else{
280 zBuf = zBuffer;
281 }
282 for(;;){
283 while( fossil_isspace(zText[0]) ){ zText++; }
@@ -287,13 +376,28 @@
287 lineCnt = 1;
288 }
289 if( zBuf!=zBuffer) fossil_free(zBuf);
290 return lineCnt;
291 }
292 for(sk=si=i=k=0; zText[i] && k<maxChars; i++){
293 char c = zText[i];
294 if( fossil_isspace(c) ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295 si = i;
296 sk = k;
297 if( k==0 || zBuf[k-1]!=' ' ){
298 zBuf[k++] = ' ';
299 }
300
--- src/comformat.c
+++ src/comformat.c
@@ -2,11 +2,11 @@
2 ** Copyright (c) 2007 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause License" or "FreeBSD License".)
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but without any warranty; without even the implied warranty of
10 ** merchantability or fitness for a particular purpose.
11 **
12 ** Author contact information:
@@ -95,21 +95,20 @@
95 #endif
96 }
97
98 /*
99 ** This function checks the current line being printed against the original
100 ** comment text. Upon matching, it updates the provided character and line
101 ** counts, if applicable. The caller needs to emit a new line, if desired.
102 */
103 static int comment_check_orig(
104 const char *zOrigText, /* [in] Original comment text ONLY, may be NULL. */
105 const char *zLine, /* [in] The comment line to print. */
106 int *pCharCnt, /* [in/out] Pointer to the line character count. */
107 int *pLineCnt /* [in/out] Pointer to the total line count. */
108 ){
109 if( zOrigText && fossil_strcmp(zLine, zOrigText)==0 ){
 
110 if( pCharCnt ) *pCharCnt = 0;
111 if( pLineCnt ) (*pLineCnt)++;
112 return 1;
113 }
114 return 0;
@@ -121,37 +120,76 @@
120 ** zero if such a character cannot be found. For the purposes of this
121 ** algorithm, the NUL character is treated the same as a spacing character.
122 */
123 static int comment_next_space(
124 const char *zLine, /* [in] The comment line being printed. */
125 int index, /* [in] The current character index being handled. */
126 int *distUTF8 /* [out] Distance to next space in UTF-8 sequences. */
127 ){
128 int nextIndex = index + 1;
129 int fNonASCII=0;
130 for(;;){
131 char c = zLine[nextIndex];
132 if( (c&0x80)==0x80 ) fNonASCII=1;
133 if( c==0 || fossil_isspace(c) ){
134 if( distUTF8 ){
135 if( fNonASCII!=0 ){
136 *distUTF8 = strlen_utf8(&zLine[index], nextIndex-index);
137 }else{
138 *distUTF8 = nextIndex-index;
139 }
140 }
141 return nextIndex;
142 }
143 nextIndex++;
144 }
145 return 0; /* NOT REACHED */
146 }
147
148 /*
149 ** Count the number of UTF-8 sequences in a string. Incomplete, ill-formed and
150 ** overlong sequences are counted as one sequence. The invalid lead bytes 0xC0
151 ** to 0xC1 and 0xF5 to 0xF7 are allowed to initiate (ill-formed) 2- and 4-byte
152 ** sequences, respectively, the other invalid lead bytes 0xF8 to 0xFF are
153 ** treated as invalid 1-byte sequences (as lone trail bytes).
154 ** Combining characters and East Asian Wide and Fullwidth characters are counted
155 ** as one, so this function does not calculate the effective "display width".
156 */
157 int strlen_utf8(const char *zString, int lengthBytes){
158 int i; /* Counted bytes. */
159 int lengthUTF8; /* Counted UTF-8 sequences. */
160 #if 0
161 assert( lengthBytes>=0 );
162 #endif
163 for(i=0, lengthUTF8=0; i<lengthBytes; i++, lengthUTF8++){
164 char c = zString[i];
165 int cchUTF8=1; /* Code units consumed. */
166 int maxUTF8=1; /* Expected sequence length. */
167 if( (c&0xe0)==0xc0 )maxUTF8=2; /* UTF-8 lead byte 110vvvvv */
168 else if( (c&0xf0)==0xe0 )maxUTF8=3; /* UTF-8 lead byte 1110vvvv */
169 else if( (c&0xf8)==0xf0 )maxUTF8=4; /* UTF-8 lead byte 11110vvv */
170 while( cchUTF8<maxUTF8 &&
171 i<lengthBytes-1 &&
172 (zString[i+1]&0xc0)==0x80 ){ /* UTF-8 trail byte 10vvvvvv */
173 cchUTF8++;
174 i++;
175 }
176 }
177 return lengthUTF8;
178 }
179
180 /*
181 ** This function is called when printing a logical comment line to calculate
182 ** the necessary indenting. The caller needs to emit the indenting spaces.
183 */
184 static void comment_calc_indent(
185 const char *zLine, /* [in] The comment line being printed. */
186 int indent, /* [in] Number of spaces to indent, zero for none. */
187 int trimCrLf, /* [in] Non-zero to trim leading/trailing CR/LF. */
188 int trimSpace, /* [in] Non-zero to trim leading/trailing spaces. */
189 int *piIndex /* [in/out] Pointer to first non-space character. */
190 ){
 
 
 
191 if( zLine && piIndex ){
192 int index = *piIndex;
193 if( trimCrLf ){
194 while( zLine[index]=='\r' || zLine[index]=='\n' ){ index++; }
195 }
@@ -179,26 +217,56 @@
217 int wordBreak, /* [in] Non-zero to try breaking on word boundaries. */
218 int origBreak, /* [in] Non-zero to break before original comment. */
219 int *pLineCnt, /* [in/out] Pointer to the total line count. */
220 const char **pzLine /* [out] Pointer to the end of the logical line. */
221 ){
222 int index = 0, charCnt = 0, lineCnt = 0, maxChars, i;
223 char zBuf[400]; int iBuf=0; /* Output buffer and counter. */
224 int cchUTF8, maxUTF8; /* Helper variables to count UTF-8 sequences. */
225 if( !zLine ) return;
226 if( lineChars<=0 ) return;
227 #if 0
228 assert( indent<sizeof(zBuf)-5 ); /* See following comments to explain */
229 assert( origIndent<sizeof(zBuf)-5 ); /* these limits. */
230 #endif
231 if( indent>sizeof(zBuf)-6 ){
232 /* Limit initial indent to fit output buffer. */
233 indent = sizeof(zBuf)-6;
234 }
235 comment_calc_indent(zLine, indent, trimCrLf, trimSpace, &index);
236 if( indent>0 ){
237 for(i=0; i<indent; i++){
238 zBuf[iBuf++] = ' ';
239 }
240 }
241 if( origIndent>sizeof(zBuf)-6 ){
242 /* Limit line indent to fit output buffer. */
243 origIndent = sizeof(zBuf)-6;
244 }
245 maxChars = lineChars;
246 for(;;){
247 int useChars = 1;
248 char c = zLine[index];
249 /* Flush the output buffer if there's no space left for at least one more
250 ** (potentially 4-byte) UTF-8 sequence, one level of indentation spaces,
251 ** a new line, and a terminating NULL. */
252 if( iBuf>sizeof(zBuf)-origIndent-6 ){
253 zBuf[iBuf]=0;
254 iBuf=0;
255 fossil_print("%s", zBuf);
256 }
257 if( c==0 ){
258 break;
259 }else{
260 if( origBreak && index>0 ){
261 const char *zCurrent = &zLine[index];
262 if( comment_check_orig(zOrigText, zCurrent, &charCnt, &lineCnt) ){
263 zBuf[iBuf++] = '\n';
264 comment_calc_indent(zLine, origIndent, trimCrLf, trimSpace, &index);
265 for( i=0; i<origIndent; i++ ){
266 zBuf[iBuf++] = ' ';
267 }
268 maxChars = lineChars;
269 }
270 }
271 index++;
272 }
@@ -205,38 +273,57 @@
273 if( c=='\n' ){
274 lineCnt++;
275 charCnt = 0;
276 useChars = 0;
277 }else if( c=='\t' ){
278 int distUTF8;
279 int nextIndex = comment_next_space(zLine, index, &distUTF8);
280 if( nextIndex<=0 || distUTF8>maxChars ){
281 break;
282 }
283 charCnt++;
284 useChars = COMMENT_TAB_WIDTH;
285 if( maxChars<useChars ){
286 zBuf[iBuf++] = ' ';
287 break;
288 }
289 }else if( wordBreak && fossil_isspace(c) ){
290 int distUTF8;
291 int nextIndex = comment_next_space(zLine, index, &distUTF8);
292 if( nextIndex<=0 || distUTF8>maxChars ){
293 break;
294 }
295 charCnt++;
296 }else{
297 charCnt++;
298 }
299 assert( c!='\n' || charCnt==0 );
300 zBuf[iBuf++] = c;
301 /* Skip over UTF-8 sequences, see comment on strlen_utf8() for details. */
302 cchUTF8=1; /* Code units consumed. */
303 maxUTF8=1; /* Expected sequence length. */
304 if( (c&0xe0)==0xc0 )maxUTF8=2; /* UTF-8 lead byte 110vvvvv */
305 else if( (c&0xf0)==0xe0 )maxUTF8=3; /* UTF-8 lead byte 1110vvvv */
306 else if( (c&0xf8)==0xf0 )maxUTF8=4; /* UTF-8 lead byte 11110vvv */
307 while( cchUTF8<maxUTF8 &&
308 (zLine[index]&0xc0)==0x80 ){ /* UTF-8 trail byte 10vvvvvv */
309 cchUTF8++;
310 zBuf[iBuf++] = zLine[index++];
311 }
312 maxChars -= useChars;
313 if( maxChars<=0 ) break;
314 if( c=='\n' ) break;
315 }
316 if( charCnt>0 ){
317 zBuf[iBuf++] = '\n';
318 lineCnt++;
319 }
320 /* Flush the remaining output buffer. */
321 if( iBuf>0 ){
322 zBuf[iBuf]=0;
323 iBuf=0;
324 fossil_print("%s", zBuf);
325 }
326 if( pLineCnt ){
327 *pLineCnt += lineCnt;
328 }
329 if( pzLine ){
@@ -259,25 +346,27 @@
346 const char *zText, /* The comment text to be printed. */
347 int indent, /* Number of spaces to indent each non-initial line. */
348 int width /* Maximum number of characters per line. */
349 ){
350 int maxChars = width - indent;
351 int si, sk, i, k, kc;
352 int doIndent = 0;
353 char *zBuf;
354 char zBuffer[400];
355 int lineCnt = 0;
356 int cchUTF8, maxUTF8; /* Helper variables to count UTF-8 sequences. */
357
358 if( width<0 ){
359 comment_set_maxchars(indent, &maxChars);
360 }
361 if( zText==0 ) zText = "(NULL)";
362 if( maxChars<=0 ){
363 maxChars = strlen(zText);
364 }
365 /* Ensure the buffer can hold the longest-possible UTF-8 sequences. */
366 if( maxChars >= (sizeof(zBuffer)/4-1) ){
367 zBuf = fossil_malloc(maxChars*4+1);
368 }else{
369 zBuf = zBuffer;
370 }
371 for(;;){
372 while( fossil_isspace(zText[0]) ){ zText++; }
@@ -287,13 +376,28 @@
376 lineCnt = 1;
377 }
378 if( zBuf!=zBuffer) fossil_free(zBuf);
379 return lineCnt;
380 }
381 for(sk=si=i=k=kc=0; zText[i] && kc<maxChars; i++){
382 char c = zText[i];
383 kc++; /* Count complete UTF-8 sequences. */
384 /* Skip over UTF-8 sequences, see comment on strlen_utf8() for details. */
385 cchUTF8=1; /* Code units consumed. */
386 maxUTF8=1; /* Expected sequence length. */
387 if( (c&0xe0)==0xc0 )maxUTF8=2; /* UTF-8 lead byte 110vvvvv */
388 else if( (c&0xf0)==0xe0 )maxUTF8=3; /* UTF-8 lead byte 1110vvvv */
389 else if( (c&0xf8)==0xf0 )maxUTF8=4; /* UTF-8 lead byte 11110vvv */
390 if( maxUTF8>1 ){
391 zBuf[k++] = c;
392 while( cchUTF8<maxUTF8 &&
393 (zText[i+1]&0xc0)==0x80 ){ /* UTF-8 trail byte 10vvvvvv */
394 cchUTF8++;
395 zBuf[k++] = zText[++i];
396 }
397 }
398 else if( fossil_isspace(c) ){
399 si = i;
400 sk = k;
401 if( k==0 || zBuf[k-1]!=' ' ){
402 zBuf[k++] = ' ';
403 }
404
+45 -4
--- src/db.c
+++ src/db.c
@@ -3030,10 +3030,24 @@
30303030
** SETTING: backoffice-nodelay boolean default=off
30313031
** If backoffice-nodelay is true, then the backoffice processing
30323032
** will never invoke sleep(). If it has nothing useful to do,
30333033
** it simply exits.
30343034
*/
3035
+/*
3036
+** SETTING: backoffice-disable boolean default=off
3037
+** If backoffice-disable is true, then the automatic backoffice
3038
+** processing is disabled. Automatic backoffice processing is the
3039
+** backoffice work that normally runs after each web page is
3040
+** rendered. Backoffice processing that is triggered by the
3041
+** "fossil backoffice" command is unaffected by this setting.
3042
+**
3043
+** Backoffice processing does things such as delivering
3044
+** email notifications. So if this setting is true, and if
3045
+** there is no cron job periodically running "fossil backoffice",
3046
+** email notifications and other work normally done by the
3047
+** backoffice will not occur.
3048
+*/
30353049
/*
30363050
** SETTING: backoffice-logfile width=40
30373051
** If backoffice-logfile is not an empty string and is a valid
30383052
** filename, then a one-line message is appended to that file
30393053
** every time the backoffice runs. This can be used for debugging,
@@ -3188,14 +3202,41 @@
31883202
** The value is a comma or newline-separated list of GLOB
31893203
** patterns specifying files that the "clean" command will keep.
31903204
*/
31913205
/*
31923206
** SETTING: localauth boolean default=off
3193
-** If enabled, require that HTTP connections from
3194
-** 127.0.0.1 be authenticated by password. If
3195
-** false, all HTTP requests from localhost have
3196
-** unrestricted access to the repository.
3207
+** If enabled, require that HTTP connections from the loopback
3208
+** address (127.0.0.1) be authenticated by password. If false,
3209
+** some HTTP requests might be granted full "Setup" user
3210
+** privileges without having to present login credentials.
3211
+** This mechanism allows the "fossil ui" command to provide
3212
+** full access to the repository without requiring the user to
3213
+** log in first.
3214
+**
3215
+** In order for full "Setup" privilege to be granted without a
3216
+** login, the following conditions must be met:
3217
+**
3218
+** (1) This setting ("localauth") must be off
3219
+** (2) The HTTP request arrive over the loopback TCP/IP
3220
+** address (127.0.01) or else via SSH.
3221
+** (3) The request must be HTTP, not HTTPS. (This
3222
+** restriction is designed to help prevent accidentally
3223
+** providing "Setup" privileges to requests arriving
3224
+** over a reverse proxy.)
3225
+** (4) The command that launched the fossil server must be
3226
+** one of the following:
3227
+** (a) "fossil ui"
3228
+** (b) "fossil server" with the --localauth option
3229
+** (c) "fossil http" with the --localauth option
3230
+** (d) CGI with the "localauth" setting in the cgi script.
3231
+**
3232
+** For maximum security, set "localauth" to 1. However, because
3233
+** of the other restrictions (2) through (4), it should be safe
3234
+** to leave "localauth" set to 0 in most installations, and
3235
+** especially on cloned repositories on workstations. Leaving
3236
+** "localauth" at 0 makes the "fossil ui" command more convenient
3237
+** to use.
31973238
*/
31983239
/*
31993240
** SETTING: main-branch width=40 default=trunk
32003241
** The value is the primary branch for the project.
32013242
*/
32023243
--- src/db.c
+++ src/db.c
@@ -3030,10 +3030,24 @@
3030 ** SETTING: backoffice-nodelay boolean default=off
3031 ** If backoffice-nodelay is true, then the backoffice processing
3032 ** will never invoke sleep(). If it has nothing useful to do,
3033 ** it simply exits.
3034 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3035 /*
3036 ** SETTING: backoffice-logfile width=40
3037 ** If backoffice-logfile is not an empty string and is a valid
3038 ** filename, then a one-line message is appended to that file
3039 ** every time the backoffice runs. This can be used for debugging,
@@ -3188,14 +3202,41 @@
3188 ** The value is a comma or newline-separated list of GLOB
3189 ** patterns specifying files that the "clean" command will keep.
3190 */
3191 /*
3192 ** SETTING: localauth boolean default=off
3193 ** If enabled, require that HTTP connections from
3194 ** 127.0.0.1 be authenticated by password. If
3195 ** false, all HTTP requests from localhost have
3196 ** unrestricted access to the repository.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3197 */
3198 /*
3199 ** SETTING: main-branch width=40 default=trunk
3200 ** The value is the primary branch for the project.
3201 */
3202
--- src/db.c
+++ src/db.c
@@ -3030,10 +3030,24 @@
3030 ** SETTING: backoffice-nodelay boolean default=off
3031 ** If backoffice-nodelay is true, then the backoffice processing
3032 ** will never invoke sleep(). If it has nothing useful to do,
3033 ** it simply exits.
3034 */
3035 /*
3036 ** SETTING: backoffice-disable boolean default=off
3037 ** If backoffice-disable is true, then the automatic backoffice
3038 ** processing is disabled. Automatic backoffice processing is the
3039 ** backoffice work that normally runs after each web page is
3040 ** rendered. Backoffice processing that is triggered by the
3041 ** "fossil backoffice" command is unaffected by this setting.
3042 **
3043 ** Backoffice processing does things such as delivering
3044 ** email notifications. So if this setting is true, and if
3045 ** there is no cron job periodically running "fossil backoffice",
3046 ** email notifications and other work normally done by the
3047 ** backoffice will not occur.
3048 */
3049 /*
3050 ** SETTING: backoffice-logfile width=40
3051 ** If backoffice-logfile is not an empty string and is a valid
3052 ** filename, then a one-line message is appended to that file
3053 ** every time the backoffice runs. This can be used for debugging,
@@ -3188,14 +3202,41 @@
3202 ** The value is a comma or newline-separated list of GLOB
3203 ** patterns specifying files that the "clean" command will keep.
3204 */
3205 /*
3206 ** SETTING: localauth boolean default=off
3207 ** If enabled, require that HTTP connections from the loopback
3208 ** address (127.0.0.1) be authenticated by password. If false,
3209 ** some HTTP requests might be granted full "Setup" user
3210 ** privileges without having to present login credentials.
3211 ** This mechanism allows the "fossil ui" command to provide
3212 ** full access to the repository without requiring the user to
3213 ** log in first.
3214 **
3215 ** In order for full "Setup" privilege to be granted without a
3216 ** login, the following conditions must be met:
3217 **
3218 ** (1) This setting ("localauth") must be off
3219 ** (2) The HTTP request arrive over the loopback TCP/IP
3220 ** address (127.0.01) or else via SSH.
3221 ** (3) The request must be HTTP, not HTTPS. (This
3222 ** restriction is designed to help prevent accidentally
3223 ** providing "Setup" privileges to requests arriving
3224 ** over a reverse proxy.)
3225 ** (4) The command that launched the fossil server must be
3226 ** one of the following:
3227 ** (a) "fossil ui"
3228 ** (b) "fossil server" with the --localauth option
3229 ** (c) "fossil http" with the --localauth option
3230 ** (d) CGI with the "localauth" setting in the cgi script.
3231 **
3232 ** For maximum security, set "localauth" to 1. However, because
3233 ** of the other restrictions (2) through (4), it should be safe
3234 ** to leave "localauth" set to 0 in most installations, and
3235 ** especially on cloned repositories on workstations. Leaving
3236 ** "localauth" at 0 makes the "fossil ui" command more convenient
3237 ** to use.
3238 */
3239 /*
3240 ** SETTING: main-branch width=40 default=trunk
3241 ** The value is the primary branch for the project.
3242 */
3243
+33 -2
--- src/dispatch.c
+++ src/dispatch.c
@@ -365,11 +365,11 @@
365365
const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
366366
if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
367367
if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
368368
@ <li><a href="%R/help?cmd=%s(z)">%s(zBoldOn)%s(z)%s(zBoldOff)</a></li>
369369
}
370
- @ </ui></div>
370
+ @ </ul></div>
371371
372372
@ <a name='webpages'></a>
373373
@ <h1>Available web UI pages:</h1>
374374
@ <div class="columns" style="column-width: 18ex;">
375375
@ <ul>
@@ -489,10 +489,36 @@
489489
if( zPrefix && memcmp(zPrefix, z, nPrefix)!=0 ) continue;
490490
aCmd[nCmd++] = aCommand[i].zName;
491491
}
492492
multi_column_list(aCmd, nCmd);
493493
}
494
+
495
+/*
496
+** Documentation on universal command-line options.
497
+*/
498
+/* @-comment: # */
499
+static const char zOptions[] =
500
+@ Command-line options common to all commands:
501
+@
502
+@ --args FILENAME Read additional arguments and options from FILENAME
503
+@ --cgitrace Active CGI tracing
504
+@ --comfmtflags VALUE Set comment formatting flags to VALUE
505
+@ --errorlog FILENAME Log errors to FILENAME
506
+@ --help Show help on the command rather than running it
507
+@ --httptrace Trace outbound HTTP requests
508
+@ --localtime Display times using the local timezone
509
+@ --no-th-hook Do not run TH1 hooks
510
+@ --quiet Reduce the amount of output
511
+@ --sqlstats Show SQL usage statistics when done
512
+@ --sqltrace Trace all SQL commands
513
+@ --sshtrace Trace SSH activity
514
+@ --ssl-identity NAME Set the SSL identity to NAME
515
+@ --systemtrace Trace calls to system()
516
+@ --user|-U USER Make the default user be USER
517
+@ --utc Display times using UTC
518
+@ --vfs NAME Cause SQLite to use the NAME VFS
519
+;
494520
495521
/*
496522
** COMMAND: help
497523
**
498524
** Usage: %fossil help TOPIC
@@ -502,10 +528,11 @@
502528
** setting. Webpage names begin with "/". To display a list of available
503529
** topics, use one of:
504530
**
505531
** %fossil help Show common commands
506532
** %fossil help -a|--all Show both common and auxiliary commands
533
+** %fossil help -o|--options Show command-line options common to all cmds
507534
** %fossil help -s|--setting Show setting names
508535
** %fossil help -t|--test Show test commands only
509536
** %fossil help -x|--aux Show auxiliary commands only
510537
** %fossil help -w|--www Show list of webpages
511538
*/
@@ -518,15 +545,19 @@
518545
const CmdOrPage *pCmd = 0;
519546
if( g.argc<3 ){
520547
z = g.argv[0];
521548
fossil_print(
522549
"Usage: %s help TOPIC\n"
523
- "Common commands: (use \"%s help -a|--all\" for a complete list)\n",
550
+ "Common commands: (use \"%s help help\" for more options)\n",
524551
z, z);
525552
command_list(0, CMDFLAG_1ST_TIER);
526553
version_cmd();
527554
return;
555
+ }
556
+ if( find_option("options","o",0) ){
557
+ fossil_print("%s", zOptions);
558
+ return;
528559
}
529560
if( find_option("all","a",0) ){
530561
command_list(0, CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER);
531562
return;
532563
}
533564
--- src/dispatch.c
+++ src/dispatch.c
@@ -365,11 +365,11 @@
365 const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
366 if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
367 if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
368 @ <li><a href="%R/help?cmd=%s(z)">%s(zBoldOn)%s(z)%s(zBoldOff)</a></li>
369 }
370 @ </ui></div>
371
372 @ <a name='webpages'></a>
373 @ <h1>Available web UI pages:</h1>
374 @ <div class="columns" style="column-width: 18ex;">
375 @ <ul>
@@ -489,10 +489,36 @@
489 if( zPrefix && memcmp(zPrefix, z, nPrefix)!=0 ) continue;
490 aCmd[nCmd++] = aCommand[i].zName;
491 }
492 multi_column_list(aCmd, nCmd);
493 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
495 /*
496 ** COMMAND: help
497 **
498 ** Usage: %fossil help TOPIC
@@ -502,10 +528,11 @@
502 ** setting. Webpage names begin with "/". To display a list of available
503 ** topics, use one of:
504 **
505 ** %fossil help Show common commands
506 ** %fossil help -a|--all Show both common and auxiliary commands
 
507 ** %fossil help -s|--setting Show setting names
508 ** %fossil help -t|--test Show test commands only
509 ** %fossil help -x|--aux Show auxiliary commands only
510 ** %fossil help -w|--www Show list of webpages
511 */
@@ -518,15 +545,19 @@
518 const CmdOrPage *pCmd = 0;
519 if( g.argc<3 ){
520 z = g.argv[0];
521 fossil_print(
522 "Usage: %s help TOPIC\n"
523 "Common commands: (use \"%s help -a|--all\" for a complete list)\n",
524 z, z);
525 command_list(0, CMDFLAG_1ST_TIER);
526 version_cmd();
527 return;
 
 
 
 
528 }
529 if( find_option("all","a",0) ){
530 command_list(0, CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER);
531 return;
532 }
533
--- src/dispatch.c
+++ src/dispatch.c
@@ -365,11 +365,11 @@
365 const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
366 if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
367 if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
368 @ <li><a href="%R/help?cmd=%s(z)">%s(zBoldOn)%s(z)%s(zBoldOff)</a></li>
369 }
370 @ </ul></div>
371
372 @ <a name='webpages'></a>
373 @ <h1>Available web UI pages:</h1>
374 @ <div class="columns" style="column-width: 18ex;">
375 @ <ul>
@@ -489,10 +489,36 @@
489 if( zPrefix && memcmp(zPrefix, z, nPrefix)!=0 ) continue;
490 aCmd[nCmd++] = aCommand[i].zName;
491 }
492 multi_column_list(aCmd, nCmd);
493 }
494
495 /*
496 ** Documentation on universal command-line options.
497 */
498 /* @-comment: # */
499 static const char zOptions[] =
500 @ Command-line options common to all commands:
501 @
502 @ --args FILENAME Read additional arguments and options from FILENAME
503 @ --cgitrace Active CGI tracing
504 @ --comfmtflags VALUE Set comment formatting flags to VALUE
505 @ --errorlog FILENAME Log errors to FILENAME
506 @ --help Show help on the command rather than running it
507 @ --httptrace Trace outbound HTTP requests
508 @ --localtime Display times using the local timezone
509 @ --no-th-hook Do not run TH1 hooks
510 @ --quiet Reduce the amount of output
511 @ --sqlstats Show SQL usage statistics when done
512 @ --sqltrace Trace all SQL commands
513 @ --sshtrace Trace SSH activity
514 @ --ssl-identity NAME Set the SSL identity to NAME
515 @ --systemtrace Trace calls to system()
516 @ --user|-U USER Make the default user be USER
517 @ --utc Display times using UTC
518 @ --vfs NAME Cause SQLite to use the NAME VFS
519 ;
520
521 /*
522 ** COMMAND: help
523 **
524 ** Usage: %fossil help TOPIC
@@ -502,10 +528,11 @@
528 ** setting. Webpage names begin with "/". To display a list of available
529 ** topics, use one of:
530 **
531 ** %fossil help Show common commands
532 ** %fossil help -a|--all Show both common and auxiliary commands
533 ** %fossil help -o|--options Show command-line options common to all cmds
534 ** %fossil help -s|--setting Show setting names
535 ** %fossil help -t|--test Show test commands only
536 ** %fossil help -x|--aux Show auxiliary commands only
537 ** %fossil help -w|--www Show list of webpages
538 */
@@ -518,15 +545,19 @@
545 const CmdOrPage *pCmd = 0;
546 if( g.argc<3 ){
547 z = g.argv[0];
548 fossil_print(
549 "Usage: %s help TOPIC\n"
550 "Common commands: (use \"%s help help\" for more options)\n",
551 z, z);
552 command_list(0, CMDFLAG_1ST_TIER);
553 version_cmd();
554 return;
555 }
556 if( find_option("options","o",0) ){
557 fossil_print("%s", zOptions);
558 return;
559 }
560 if( find_option("all","a",0) ){
561 command_list(0, CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER);
562 return;
563 }
564
+56 -15
--- src/forum.c
+++ src/forum.c
@@ -265,10 +265,28 @@
265265
}
266266
if( zClass ){
267267
@ </div>
268268
}
269269
}
270
+
271
+/*
272
+** Generate the buttons in the display that allow a forum supervisor to
273
+** mark a user as trusted. Only do this if:
274
+**
275
+** (1) The poster is an individual, not a special user like "anonymous"
276
+** (2) The current user has Forum Supervisor privilege
277
+*/
278
+static void generateTrustControls(Manifest *pPost){
279
+ if( !g.perm.AdminForum ) return;
280
+ if( login_is_special(pPost->zUser) ) return;
281
+ @ <br>
282
+ @ <label><input type="checkbox" name="trust">
283
+ @ Trust user "%h(pPost->zUser)"
284
+ @ so that future posts by "%h(pPost->zUser)" do not require moderation.
285
+ @ </label>
286
+ @ <input type="hidden" name="trustuser" value="%h(pPost->zUser)">
287
+}
270288
271289
/*
272290
** Display all posts in a forum thread in chronological order
273291
*/
274292
static void forum_display_chronological(int froot, int target){
@@ -295,29 +313,29 @@
295313
}
296314
zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
297315
@ <p>By %h(pPost->zUser) on %h(zDate) (%d(p->fpid))
298316
fossil_free(zDate);
299317
if( p->pEdit ){
300
- @ edit of %z(href("%R/forumpost/%S?t",p->pEdit->zUuid))%d(p->fprev)</a>
318
+ @ edit of %z(href("%R/forumpost/%S?t=c",p->pEdit->zUuid))%d(p->fprev)</a>
301319
}
302320
if( p->firt ){
303321
ForumEntry *pIrt = p->pPrev;
304322
while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev;
305323
if( pIrt ){
306
- @ reply to %z(href("%R/forumpost/%S?t",pIrt->zUuid))%d(p->firt)</a>
324
+ @ reply to %z(href("%R/forumpost/%S?t=c",pIrt->zUuid))%d(p->firt)</a>
307325
}
308326
}
309327
if( p->pLeaf ){
310
- @ updated by %z(href("%R/forumpost/%S?t",p->pLeaf->zUuid))\
328
+ @ updated by %z(href("%R/forumpost/%S?t=c",p->pLeaf->zUuid))\
311329
@ %d(p->pLeaf->fpid)</a>
312330
}
313331
if( g.perm.Debug ){
314332
@ <span class="debug">\
315333
@ <a href="%R/artifact/%h(p->zUuid)">artifact</a></span>
316334
}
317335
if( p->fpid!=target ){
318
- @ %z(href("%R/forumpost/%S?t",p->zUuid))[link]</a>
336
+ @ %z(href("%R/forumpost/%S?t=c",p->zUuid))[link]</a>
319337
}
320338
isPrivate = content_is_private(p->fpid);
321339
sameUser = notAnon && fossil_strcmp(pPost->zUser, g.zLogin)==0;
322340
if( isPrivate && !g.perm.ModForum && !sameUser ){
323341
@ <p><span class="modpending">Awaiting Moderator Approval</span></p>
@@ -340,10 +358,11 @@
340358
}else if( g.perm.ModForum ){
341359
/* Provide moderators with moderation buttons for posts that
342360
** are pending moderation */
343361
@ <input type="submit" name="approve" value="Approve">
344362
@ <input type="submit" name="reject" value="Reject">
363
+ generateTrustControls(pPost);
345364
}else if( sameUser ){
346365
/* A post that is pending moderation can be deleted by the
347366
** person who originally submitted the post */
348367
@ <input type="submit" name="reject" value="Delete">
349368
}
@@ -446,10 +465,11 @@
446465
}else if( g.perm.ModForum ){
447466
/* Provide moderators with moderation buttons for posts that
448467
** are pending moderation */
449468
@ <input type="submit" name="approve" value="Approve">
450469
@ <input type="submit" name="reject" value="Reject">
470
+ generateTrustControls(pPost);
451471
}else if( sameUser ){
452472
/* A post that is pending moderation can be deleted by the
453473
** person who originally submitted the post */
454474
@ <input type="submit" name="reject" value="Delete">
455475
}
@@ -471,11 +491,12 @@
471491
** selected posting into view after the page loads.
472492
**
473493
** Query parameters:
474494
**
475495
** name=X REQUIRED. The hash of the post to display
476
-** t Show a chronologic listing instead of hierarchical
496
+** t=MODE Display mode. MODE is 'c' for chronological or
497
+** 'h' for hierarchical, or 'a' for automatic.
477498
*/
478499
void forumpost_page(void){
479500
forumthread_page();
480501
}
481502
@@ -487,16 +508,18 @@
487508
** the postings in the thread are selected.
488509
**
489510
** Query parameters:
490511
**
491512
** name=X REQUIRED. The hash of any post of the thread.
492
-** t Show a chronologic listing instead of hierarchical
513
+** t=MODE Display mode. MODE is 'c' for chronological or
514
+** 'h' for hierarchical, or 'a' for automatic.
493515
*/
494516
void forumthread_page(void){
495517
int fpid;
496518
int froot;
497519
const char *zName = P("name");
520
+ const char *zMode = PD("t","a");
498521
login_check_credentials();
499522
if( !g.perm.RdForum ){
500523
login_needed(g.anon.RdForum);
501524
return;
502525
}
@@ -511,19 +534,22 @@
511534
froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid);
512535
if( froot==0 ){
513536
webpage_error("Not a forum post: \"%s\"", zName);
514537
}
515538
if( fossil_strcmp(g.zPath,"forumthread")==0 ) fpid = 0;
516
- if( P("t") ){
517
- if( g.perm.Debug ){
518
- style_submenu_element("Hierarchical", "%R/%s/%s", g.zPath, zName);
519
- }
539
+ if( zMode[0]=='a' ){
540
+ if( cgi_from_mobile() ){
541
+ zMode = "c"; /* Default to chronological on mobile */
542
+ }else{
543
+ zMode = "h";
544
+ }
545
+ }
546
+ if( zMode[0]=='c' ){
547
+ style_submenu_element("Hierarchical", "%R/%s/%s?t=h", g.zPath, zName);
520548
forum_display_chronological(froot, fpid);
521549
}else{
522
- if( g.perm.Debug ){
523
- style_submenu_element("Chronological", "%R/%s/%s?t", g.zPath, zName);
524
- }
550
+ style_submenu_element("Chronological", "%R/%s/%s?t=c", g.zPath, zName);
525551
forum_display_hierarchical(froot, fpid);
526552
}
527553
style_load_js("forum.js");
528554
style_footer();
529555
}
@@ -740,11 +766,11 @@
740766
@ <h1>Preview:</h1>
741767
forum_render(zTitle, zMimetype, zContent, "forumEdit");
742768
}
743769
style_header("New Forum Thread");
744770
@ <form action="%R/forume1" method="POST">
745
- @ <h1>New Message:</h1>
771
+ @ <h1>New Thread:</h1>
746772
forum_from_line();
747773
forum_entry_widget(zTitle, zMimetype, zContent);
748774
@ <input type="submit" name="preview" value="Preview">
749775
if( P("preview") ){
750776
@ <input type="submit" name="submit" value="Submit">
@@ -797,11 +823,20 @@
797823
return;
798824
}
799825
isCsrfSafe = cgi_csrf_safe(1);
800826
if( g.perm.ModForum && isCsrfSafe ){
801827
if( P("approve") ){
828
+ const char *zUserToTrust;
802829
moderation_approve(fpid);
830
+ if( g.perm.AdminForum
831
+ && PB("trust")
832
+ && (zUserToTrust = P("trustuser"))!=0
833
+ ){
834
+ db_multi_exec("UPDATE user SET cap=cap||'4' "
835
+ "WHERE login=%Q AND cap NOT GLOB '*4*'",
836
+ zUserToTrust);
837
+ }
803838
cgi_redirectf("%R/forumpost/%S",P("fpid"));
804839
return;
805840
}
806841
if( P("reject") ){
807842
char *zParent =
@@ -937,11 +972,17 @@
937972
login_needed(g.anon.RdForum);
938973
return;
939974
}
940975
style_header("Forum");
941976
if( g.perm.WrForum ){
942
- style_submenu_element("New Message","%R/forumnew");
977
+ style_submenu_element("New Thread","%R/forumnew");
978
+ }else{
979
+ /* Can't combine this with previous case using the ternary operator
980
+ * because that causes an error yelling about "non-constant format"
981
+ * with some compilers. I can't see it, since both expressions have
982
+ * the same format, but I'm no C spec lawyer. */
983
+ style_submenu_element("New Thread","%R/login");
943984
}
944985
if( g.perm.ModForum && moderation_needed() ){
945986
style_submenu_element("Moderation Requests", "%R/modreq");
946987
}
947988
if( (srchFlags & SRCH_FORUM)!=0 ){
948989
--- src/forum.c
+++ src/forum.c
@@ -265,10 +265,28 @@
265 }
266 if( zClass ){
267 @ </div>
268 }
269 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
271 /*
272 ** Display all posts in a forum thread in chronological order
273 */
274 static void forum_display_chronological(int froot, int target){
@@ -295,29 +313,29 @@
295 }
296 zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
297 @ <p>By %h(pPost->zUser) on %h(zDate) (%d(p->fpid))
298 fossil_free(zDate);
299 if( p->pEdit ){
300 @ edit of %z(href("%R/forumpost/%S?t",p->pEdit->zUuid))%d(p->fprev)</a>
301 }
302 if( p->firt ){
303 ForumEntry *pIrt = p->pPrev;
304 while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev;
305 if( pIrt ){
306 @ reply to %z(href("%R/forumpost/%S?t",pIrt->zUuid))%d(p->firt)</a>
307 }
308 }
309 if( p->pLeaf ){
310 @ updated by %z(href("%R/forumpost/%S?t",p->pLeaf->zUuid))\
311 @ %d(p->pLeaf->fpid)</a>
312 }
313 if( g.perm.Debug ){
314 @ <span class="debug">\
315 @ <a href="%R/artifact/%h(p->zUuid)">artifact</a></span>
316 }
317 if( p->fpid!=target ){
318 @ %z(href("%R/forumpost/%S?t",p->zUuid))[link]</a>
319 }
320 isPrivate = content_is_private(p->fpid);
321 sameUser = notAnon && fossil_strcmp(pPost->zUser, g.zLogin)==0;
322 if( isPrivate && !g.perm.ModForum && !sameUser ){
323 @ <p><span class="modpending">Awaiting Moderator Approval</span></p>
@@ -340,10 +358,11 @@
340 }else if( g.perm.ModForum ){
341 /* Provide moderators with moderation buttons for posts that
342 ** are pending moderation */
343 @ <input type="submit" name="approve" value="Approve">
344 @ <input type="submit" name="reject" value="Reject">
 
345 }else if( sameUser ){
346 /* A post that is pending moderation can be deleted by the
347 ** person who originally submitted the post */
348 @ <input type="submit" name="reject" value="Delete">
349 }
@@ -446,10 +465,11 @@
446 }else if( g.perm.ModForum ){
447 /* Provide moderators with moderation buttons for posts that
448 ** are pending moderation */
449 @ <input type="submit" name="approve" value="Approve">
450 @ <input type="submit" name="reject" value="Reject">
 
451 }else if( sameUser ){
452 /* A post that is pending moderation can be deleted by the
453 ** person who originally submitted the post */
454 @ <input type="submit" name="reject" value="Delete">
455 }
@@ -471,11 +491,12 @@
471 ** selected posting into view after the page loads.
472 **
473 ** Query parameters:
474 **
475 ** name=X REQUIRED. The hash of the post to display
476 ** t Show a chronologic listing instead of hierarchical
 
477 */
478 void forumpost_page(void){
479 forumthread_page();
480 }
481
@@ -487,16 +508,18 @@
487 ** the postings in the thread are selected.
488 **
489 ** Query parameters:
490 **
491 ** name=X REQUIRED. The hash of any post of the thread.
492 ** t Show a chronologic listing instead of hierarchical
 
493 */
494 void forumthread_page(void){
495 int fpid;
496 int froot;
497 const char *zName = P("name");
 
498 login_check_credentials();
499 if( !g.perm.RdForum ){
500 login_needed(g.anon.RdForum);
501 return;
502 }
@@ -511,19 +534,22 @@
511 froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid);
512 if( froot==0 ){
513 webpage_error("Not a forum post: \"%s\"", zName);
514 }
515 if( fossil_strcmp(g.zPath,"forumthread")==0 ) fpid = 0;
516 if( P("t") ){
517 if( g.perm.Debug ){
518 style_submenu_element("Hierarchical", "%R/%s/%s", g.zPath, zName);
519 }
 
 
 
 
 
520 forum_display_chronological(froot, fpid);
521 }else{
522 if( g.perm.Debug ){
523 style_submenu_element("Chronological", "%R/%s/%s?t", g.zPath, zName);
524 }
525 forum_display_hierarchical(froot, fpid);
526 }
527 style_load_js("forum.js");
528 style_footer();
529 }
@@ -740,11 +766,11 @@
740 @ <h1>Preview:</h1>
741 forum_render(zTitle, zMimetype, zContent, "forumEdit");
742 }
743 style_header("New Forum Thread");
744 @ <form action="%R/forume1" method="POST">
745 @ <h1>New Message:</h1>
746 forum_from_line();
747 forum_entry_widget(zTitle, zMimetype, zContent);
748 @ <input type="submit" name="preview" value="Preview">
749 if( P("preview") ){
750 @ <input type="submit" name="submit" value="Submit">
@@ -797,11 +823,20 @@
797 return;
798 }
799 isCsrfSafe = cgi_csrf_safe(1);
800 if( g.perm.ModForum && isCsrfSafe ){
801 if( P("approve") ){
 
802 moderation_approve(fpid);
 
 
 
 
 
 
 
 
803 cgi_redirectf("%R/forumpost/%S",P("fpid"));
804 return;
805 }
806 if( P("reject") ){
807 char *zParent =
@@ -937,11 +972,17 @@
937 login_needed(g.anon.RdForum);
938 return;
939 }
940 style_header("Forum");
941 if( g.perm.WrForum ){
942 style_submenu_element("New Message","%R/forumnew");
 
 
 
 
 
 
943 }
944 if( g.perm.ModForum && moderation_needed() ){
945 style_submenu_element("Moderation Requests", "%R/modreq");
946 }
947 if( (srchFlags & SRCH_FORUM)!=0 ){
948
--- src/forum.c
+++ src/forum.c
@@ -265,10 +265,28 @@
265 }
266 if( zClass ){
267 @ </div>
268 }
269 }
270
271 /*
272 ** Generate the buttons in the display that allow a forum supervisor to
273 ** mark a user as trusted. Only do this if:
274 **
275 ** (1) The poster is an individual, not a special user like "anonymous"
276 ** (2) The current user has Forum Supervisor privilege
277 */
278 static void generateTrustControls(Manifest *pPost){
279 if( !g.perm.AdminForum ) return;
280 if( login_is_special(pPost->zUser) ) return;
281 @ <br>
282 @ <label><input type="checkbox" name="trust">
283 @ Trust user "%h(pPost->zUser)"
284 @ so that future posts by "%h(pPost->zUser)" do not require moderation.
285 @ </label>
286 @ <input type="hidden" name="trustuser" value="%h(pPost->zUser)">
287 }
288
289 /*
290 ** Display all posts in a forum thread in chronological order
291 */
292 static void forum_display_chronological(int froot, int target){
@@ -295,29 +313,29 @@
313 }
314 zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
315 @ <p>By %h(pPost->zUser) on %h(zDate) (%d(p->fpid))
316 fossil_free(zDate);
317 if( p->pEdit ){
318 @ edit of %z(href("%R/forumpost/%S?t=c",p->pEdit->zUuid))%d(p->fprev)</a>
319 }
320 if( p->firt ){
321 ForumEntry *pIrt = p->pPrev;
322 while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev;
323 if( pIrt ){
324 @ reply to %z(href("%R/forumpost/%S?t=c",pIrt->zUuid))%d(p->firt)</a>
325 }
326 }
327 if( p->pLeaf ){
328 @ updated by %z(href("%R/forumpost/%S?t=c",p->pLeaf->zUuid))\
329 @ %d(p->pLeaf->fpid)</a>
330 }
331 if( g.perm.Debug ){
332 @ <span class="debug">\
333 @ <a href="%R/artifact/%h(p->zUuid)">artifact</a></span>
334 }
335 if( p->fpid!=target ){
336 @ %z(href("%R/forumpost/%S?t=c",p->zUuid))[link]</a>
337 }
338 isPrivate = content_is_private(p->fpid);
339 sameUser = notAnon && fossil_strcmp(pPost->zUser, g.zLogin)==0;
340 if( isPrivate && !g.perm.ModForum && !sameUser ){
341 @ <p><span class="modpending">Awaiting Moderator Approval</span></p>
@@ -340,10 +358,11 @@
358 }else if( g.perm.ModForum ){
359 /* Provide moderators with moderation buttons for posts that
360 ** are pending moderation */
361 @ <input type="submit" name="approve" value="Approve">
362 @ <input type="submit" name="reject" value="Reject">
363 generateTrustControls(pPost);
364 }else if( sameUser ){
365 /* A post that is pending moderation can be deleted by the
366 ** person who originally submitted the post */
367 @ <input type="submit" name="reject" value="Delete">
368 }
@@ -446,10 +465,11 @@
465 }else if( g.perm.ModForum ){
466 /* Provide moderators with moderation buttons for posts that
467 ** are pending moderation */
468 @ <input type="submit" name="approve" value="Approve">
469 @ <input type="submit" name="reject" value="Reject">
470 generateTrustControls(pPost);
471 }else if( sameUser ){
472 /* A post that is pending moderation can be deleted by the
473 ** person who originally submitted the post */
474 @ <input type="submit" name="reject" value="Delete">
475 }
@@ -471,11 +491,12 @@
491 ** selected posting into view after the page loads.
492 **
493 ** Query parameters:
494 **
495 ** name=X REQUIRED. The hash of the post to display
496 ** t=MODE Display mode. MODE is 'c' for chronological or
497 ** 'h' for hierarchical, or 'a' for automatic.
498 */
499 void forumpost_page(void){
500 forumthread_page();
501 }
502
@@ -487,16 +508,18 @@
508 ** the postings in the thread are selected.
509 **
510 ** Query parameters:
511 **
512 ** name=X REQUIRED. The hash of any post of the thread.
513 ** t=MODE Display mode. MODE is 'c' for chronological or
514 ** 'h' for hierarchical, or 'a' for automatic.
515 */
516 void forumthread_page(void){
517 int fpid;
518 int froot;
519 const char *zName = P("name");
520 const char *zMode = PD("t","a");
521 login_check_credentials();
522 if( !g.perm.RdForum ){
523 login_needed(g.anon.RdForum);
524 return;
525 }
@@ -511,19 +534,22 @@
534 froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid);
535 if( froot==0 ){
536 webpage_error("Not a forum post: \"%s\"", zName);
537 }
538 if( fossil_strcmp(g.zPath,"forumthread")==0 ) fpid = 0;
539 if( zMode[0]=='a' ){
540 if( cgi_from_mobile() ){
541 zMode = "c"; /* Default to chronological on mobile */
542 }else{
543 zMode = "h";
544 }
545 }
546 if( zMode[0]=='c' ){
547 style_submenu_element("Hierarchical", "%R/%s/%s?t=h", g.zPath, zName);
548 forum_display_chronological(froot, fpid);
549 }else{
550 style_submenu_element("Chronological", "%R/%s/%s?t=c", g.zPath, zName);
 
 
551 forum_display_hierarchical(froot, fpid);
552 }
553 style_load_js("forum.js");
554 style_footer();
555 }
@@ -740,11 +766,11 @@
766 @ <h1>Preview:</h1>
767 forum_render(zTitle, zMimetype, zContent, "forumEdit");
768 }
769 style_header("New Forum Thread");
770 @ <form action="%R/forume1" method="POST">
771 @ <h1>New Thread:</h1>
772 forum_from_line();
773 forum_entry_widget(zTitle, zMimetype, zContent);
774 @ <input type="submit" name="preview" value="Preview">
775 if( P("preview") ){
776 @ <input type="submit" name="submit" value="Submit">
@@ -797,11 +823,20 @@
823 return;
824 }
825 isCsrfSafe = cgi_csrf_safe(1);
826 if( g.perm.ModForum && isCsrfSafe ){
827 if( P("approve") ){
828 const char *zUserToTrust;
829 moderation_approve(fpid);
830 if( g.perm.AdminForum
831 && PB("trust")
832 && (zUserToTrust = P("trustuser"))!=0
833 ){
834 db_multi_exec("UPDATE user SET cap=cap||'4' "
835 "WHERE login=%Q AND cap NOT GLOB '*4*'",
836 zUserToTrust);
837 }
838 cgi_redirectf("%R/forumpost/%S",P("fpid"));
839 return;
840 }
841 if( P("reject") ){
842 char *zParent =
@@ -937,11 +972,17 @@
972 login_needed(g.anon.RdForum);
973 return;
974 }
975 style_header("Forum");
976 if( g.perm.WrForum ){
977 style_submenu_element("New Thread","%R/forumnew");
978 }else{
979 /* Can't combine this with previous case using the ternary operator
980 * because that causes an error yelling about "non-constant format"
981 * with some compilers. I can't see it, since both expressions have
982 * the same format, but I'm no C spec lawyer. */
983 style_submenu_element("New Thread","%R/login");
984 }
985 if( g.perm.ModForum && moderation_needed() ){
986 style_submenu_element("Moderation Requests", "%R/modreq");
987 }
988 if( (srchFlags & SRCH_FORUM)!=0 ){
989
--- src/http_socket.c
+++ src/http_socket.c
@@ -196,17 +196,17 @@
196196
197197
/*
198198
** Send content out over the open socket connection.
199199
*/
200200
size_t socket_send(void *NotUsed, const void *pContent, size_t N){
201
- size_t sent;
201
+ ssize_t sent;
202202
size_t total = 0;
203203
while( N>0 ){
204204
sent = send(iSocket, pContent, N, 0);
205205
if( sent<=0 ) break;
206
- total += sent;
207
- N -= sent;
206
+ total += (size_t)sent;
207
+ N -= (size_t)sent;
208208
pContent = (void*)&((char*)pContent)[sent];
209209
}
210210
return total;
211211
}
212212
213213
--- src/http_socket.c
+++ src/http_socket.c
@@ -196,17 +196,17 @@
196
197 /*
198 ** Send content out over the open socket connection.
199 */
200 size_t socket_send(void *NotUsed, const void *pContent, size_t N){
201 size_t sent;
202 size_t total = 0;
203 while( N>0 ){
204 sent = send(iSocket, pContent, N, 0);
205 if( sent<=0 ) break;
206 total += sent;
207 N -= sent;
208 pContent = (void*)&((char*)pContent)[sent];
209 }
210 return total;
211 }
212
213
--- src/http_socket.c
+++ src/http_socket.c
@@ -196,17 +196,17 @@
196
197 /*
198 ** Send content out over the open socket connection.
199 */
200 size_t socket_send(void *NotUsed, const void *pContent, size_t N){
201 ssize_t sent;
202 size_t total = 0;
203 while( N>0 ){
204 sent = send(iSocket, pContent, N, 0);
205 if( sent<=0 ) break;
206 total += (size_t)sent;
207 N -= (size_t)sent;
208 pContent = (void*)&((char*)pContent)[sent];
209 }
210 return total;
211 }
212
213
+8 -2
--- src/info.c
+++ src/info.c
@@ -2129,13 +2129,19 @@
21292129
if( renderAsWiki ){
21302130
wiki_render_by_mimetype(&content, zMime);
21312131
}else if( renderAsHtml ){
21322132
@ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
21332133
@ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2134
- @ sandbox="allow-same-origin"
2135
- @ onload="this.height=this.contentDocument.documentElement.scrollHeight;">
2134
+ @ sandbox="allow-same-origin" id="ifm1">
21362135
@ </iframe>
2136
+ @ <script nonce="%h(style_nonce())">
2137
+ @ document.getElementById("ifm1").addEventListener("load",
2138
+ @ function(){
2139
+ @ this.height=this.contentDocument.documentElement.scrollHeight + 75;
2140
+ @ }
2141
+ @ );
2142
+ @ </script>
21372143
}else{
21382144
style_submenu_element("Hex", "%s/hexdump?name=%s", g.zTop, zUuid);
21392145
blob_to_utf8_no_bom(&content, 0);
21402146
zMime = mimetype_from_content(&content);
21412147
@ <blockquote>
21422148
--- src/info.c
+++ src/info.c
@@ -2129,13 +2129,19 @@
2129 if( renderAsWiki ){
2130 wiki_render_by_mimetype(&content, zMime);
2131 }else if( renderAsHtml ){
2132 @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
2133 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2134 @ sandbox="allow-same-origin"
2135 @ onload="this.height=this.contentDocument.documentElement.scrollHeight;">
2136 @ </iframe>
 
 
 
 
 
 
 
2137 }else{
2138 style_submenu_element("Hex", "%s/hexdump?name=%s", g.zTop, zUuid);
2139 blob_to_utf8_no_bom(&content, 0);
2140 zMime = mimetype_from_content(&content);
2141 @ <blockquote>
2142
--- src/info.c
+++ src/info.c
@@ -2129,13 +2129,19 @@
2129 if( renderAsWiki ){
2130 wiki_render_by_mimetype(&content, zMime);
2131 }else if( renderAsHtml ){
2132 @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
2133 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2134 @ sandbox="allow-same-origin" id="ifm1">
 
2135 @ </iframe>
2136 @ <script nonce="%h(style_nonce())">
2137 @ document.getElementById("ifm1").addEventListener("load",
2138 @ function(){
2139 @ this.height=this.contentDocument.documentElement.scrollHeight + 75;
2140 @ }
2141 @ );
2142 @ </script>
2143 }else{
2144 style_submenu_element("Hex", "%s/hexdump?name=%s", g.zTop, zUuid);
2145 blob_to_utf8_no_bom(&content, 0);
2146 zMime = mimetype_from_content(&content);
2147 @ <blockquote>
2148
+2 -149
--- src/main.c
+++ src/main.c
@@ -972,14 +972,10 @@
972972
g.argv[i]);
973973
}
974974
}
975975
}
976976
977
-/*
978
-** Print a list of words in multiple columns.
979
-*/
980
-
981977
982978
/*
983979
** This function returns a human readable version string.
984980
*/
985981
const char *get_version(){
@@ -1301,154 +1297,10 @@
13011297
}
13021298
#endif
13031299
return zRepo;
13041300
}
13051301
1306
-/*
1307
-** Generate a web-page that lists all repositories located under the
1308
-** g.zRepositoryName directory and return non-zero.
1309
-**
1310
-** For the special case when g.zRepositoryName a non-chroot-jail "/",
1311
-** compose the list using the "repo:" entries in the global_config
1312
-** table of the configuration database. These entries comprise all
1313
-** of the repositories known to the "all" command. The special case
1314
-** processing is disallowed for chroot jails because g.zRepositoryName
1315
-** is always "/" inside a chroot jail and so it cannot be used as a flag
1316
-** to signal the special processing in that case. The special case
1317
-** processing is intended for the "fossil all ui" command which never
1318
-** runs in a chroot jail anyhow.
1319
-**
1320
-** Or, if no repositories can be located beneath g.zRepositoryName,
1321
-** return 0.
1322
-*/
1323
-static int repo_list_page(void){
1324
- Blob base;
1325
- int n = 0;
1326
- int allRepo;
1327
-
1328
- assert( g.db==0 );
1329
- if( fossil_strcmp(g.zRepositoryName,"/")==0 && !g.fJail ){
1330
- /* For the special case of the "repository directory" being "/",
1331
- ** show all of the repositories named in the ~/.fossil database.
1332
- **
1333
- ** On unix systems, then entries are of the form "repo:/home/..."
1334
- ** and on Windows systems they are like on unix, starting with a "/"
1335
- ** or they can begin with a drive letter: "repo:C:/Users/...". In either
1336
- ** case, we want returned path to omit any initial "/".
1337
- */
1338
- db_open_config(1, 0);
1339
- db_multi_exec(
1340
- "CREATE TEMP VIEW sfile AS"
1341
- " SELECT ltrim(substr(name,6),'/') AS 'pathname' FROM global_config"
1342
- " WHERE name GLOB 'repo:*'"
1343
- );
1344
- allRepo = 1;
1345
- }else{
1346
- /* The default case: All repositories under the g.zRepositoryName
1347
- ** directory.
1348
- */
1349
- blob_init(&base, g.zRepositoryName, -1);
1350
- sqlite3_open(":memory:", &g.db);
1351
- db_multi_exec("CREATE TABLE sfile(pathname TEXT);");
1352
- db_multi_exec("CREATE TABLE vfile(pathname);");
1353
- vfile_scan(&base, blob_size(&base), 0, 0, 0);
1354
- db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'");
1355
- allRepo = 0;
1356
- }
1357
- @ <html>
1358
- @ <head>
1359
- @ <base href="%s(g.zBaseURL)/" />
1360
- @ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1361
- @ <title>Repository List</title>
1362
- @ </head>
1363
- @ <body>
1364
- n = db_int(0, "SELECT count(*) FROM sfile");
1365
- if( n>0 ){
1366
- Stmt q;
1367
- sqlite3_int64 iNow, iMTime;
1368
- @ <h1 align="center">Fossil Repositories</h1>
1369
- @ <table border="0" class="sortable" data-init-sort="1" \
1370
- @ data-column-types="tnk"><thead>
1371
- @ <tr><th>Filename<th width="20"><th>Last Modified</tr>
1372
- @ </thead><tbody>
1373
- db_prepare(&q, "SELECT pathname"
1374
- " FROM sfile ORDER BY pathname COLLATE nocase;");
1375
- iNow = db_int64(0, "SELECT strftime('%%s','now')");
1376
- while( db_step(&q)==SQLITE_ROW ){
1377
- const char *zName = db_column_text(&q, 0);
1378
- int nName = (int)strlen(zName);
1379
- char *zUrl;
1380
- char *zAge;
1381
- char *zFull;
1382
- if( nName<7 ) continue;
1383
- zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
1384
- if( zName[0]=='/'
1385
-#ifdef _WIN32
1386
- || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
1387
-#endif
1388
- ){
1389
- zFull = mprintf("%s", zName);
1390
- }else if ( allRepo ){
1391
- zFull = mprintf("/%s", zName);
1392
- }else{
1393
- zFull = mprintf("%s/%s", g.zRepositoryName, zName);
1394
- }
1395
- iMTime = file_mtime(zFull, ExtFILE);
1396
- fossil_free(zFull);
1397
- if( iMTime<=0 ){
1398
- zAge = mprintf("...");
1399
- }else{
1400
- zAge = human_readable_age((iNow - iMTime)/86400.0);
1401
- }
1402
- if( sqlite3_strglob("*.fossil", zName)!=0 ){
1403
- /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
1404
- ** do not work for repositories whose names do not end in ".fossil".
1405
- ** So do not hyperlink those cases. */
1406
- @ <tr><td>%h(zName)
1407
- } else if( sqlite3_strglob("*/.*", zName)==0 ){
1408
- /* Do not show hidden repos */
1409
- @ <tr><td>%h(zName) (hidden)
1410
- } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
1411
- @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a>
1412
- }else{
1413
- @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a>
1414
- }
1415
- @ <td></td><td data-sortkey='%010llx(iNow - iMTime)'>%h(zAge)</tr>
1416
- fossil_free(zAge);
1417
- sqlite3_free(zUrl);
1418
- }
1419
- @ </tbody></table>
1420
- }else{
1421
- @ <h1>No Repositories Found</h1>
1422
- }
1423
- @ <script>%s(builtin_text("sorttable.js"))</script>
1424
- @ </body>
1425
- @ </html>
1426
- cgi_reply();
1427
- sqlite3_close(g.db);
1428
- g.db = 0;
1429
- return n;
1430
-}
1431
-
1432
-/*
1433
-** COMMAND: test-list-page
1434
-**
1435
-** Usage: %fossil test-list-page DIRECTORY
1436
-**
1437
-** Show all repositories underneath DIRECTORY. Or if DIRECTORY is "/"
1438
-** show all repositories in the ~/.fossil file.
1439
-*/
1440
-void test_list_page(void){
1441
- if( g.argc<3 ){
1442
- g.zRepositoryName = "/";
1443
- }else{
1444
- g.zRepositoryName = g.argv[2];
1445
- }
1446
- g.httpOut = stdout;
1447
- repo_list_page();
1448
-}
1449
-
14501302
/*
14511303
** Called whenever a crash is encountered while processing a webpage.
14521304
*/
14531305
void sigsegv_handler(int x){
14541306
#if HAVE_BACKTRACE
@@ -2381,10 +2233,11 @@
23812233
g.useLocalauth = find_option("localauth", 0, 0)!=0;
23822234
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
23832235
g.fNoHttpCompress = find_option("nocompress",0,0)!=0;
23842236
zInFile = find_option("in",0,1);
23852237
if( zInFile ){
2238
+ backoffice_disable();
23862239
g.httpIn = fossil_fopen(zInFile, "rb");
23872240
if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
23882241
}else{
23892242
g.httpIn = stdin;
23902243
}
@@ -2845,11 +2698,11 @@
28452698
*/
28462699
void test_warning_page(void){
28472700
int iCase = atoi(PD("case","0"));
28482701
int i;
28492702
login_check_credentials();
2850
- if( !g.perm.Setup && !g.perm.Admin ){
2703
+ if( !g.perm.Admin ){
28512704
login_needed(0);
28522705
return;
28532706
}
28542707
style_header("Warning Test Page");
28552708
style_submenu_element("Error Log","%R/errorlog");
28562709
--- src/main.c
+++ src/main.c
@@ -972,14 +972,10 @@
972 g.argv[i]);
973 }
974 }
975 }
976
977 /*
978 ** Print a list of words in multiple columns.
979 */
980
981
982 /*
983 ** This function returns a human readable version string.
984 */
985 const char *get_version(){
@@ -1301,154 +1297,10 @@
1301 }
1302 #endif
1303 return zRepo;
1304 }
1305
1306 /*
1307 ** Generate a web-page that lists all repositories located under the
1308 ** g.zRepositoryName directory and return non-zero.
1309 **
1310 ** For the special case when g.zRepositoryName a non-chroot-jail "/",
1311 ** compose the list using the "repo:" entries in the global_config
1312 ** table of the configuration database. These entries comprise all
1313 ** of the repositories known to the "all" command. The special case
1314 ** processing is disallowed for chroot jails because g.zRepositoryName
1315 ** is always "/" inside a chroot jail and so it cannot be used as a flag
1316 ** to signal the special processing in that case. The special case
1317 ** processing is intended for the "fossil all ui" command which never
1318 ** runs in a chroot jail anyhow.
1319 **
1320 ** Or, if no repositories can be located beneath g.zRepositoryName,
1321 ** return 0.
1322 */
1323 static int repo_list_page(void){
1324 Blob base;
1325 int n = 0;
1326 int allRepo;
1327
1328 assert( g.db==0 );
1329 if( fossil_strcmp(g.zRepositoryName,"/")==0 && !g.fJail ){
1330 /* For the special case of the "repository directory" being "/",
1331 ** show all of the repositories named in the ~/.fossil database.
1332 **
1333 ** On unix systems, then entries are of the form "repo:/home/..."
1334 ** and on Windows systems they are like on unix, starting with a "/"
1335 ** or they can begin with a drive letter: "repo:C:/Users/...". In either
1336 ** case, we want returned path to omit any initial "/".
1337 */
1338 db_open_config(1, 0);
1339 db_multi_exec(
1340 "CREATE TEMP VIEW sfile AS"
1341 " SELECT ltrim(substr(name,6),'/') AS 'pathname' FROM global_config"
1342 " WHERE name GLOB 'repo:*'"
1343 );
1344 allRepo = 1;
1345 }else{
1346 /* The default case: All repositories under the g.zRepositoryName
1347 ** directory.
1348 */
1349 blob_init(&base, g.zRepositoryName, -1);
1350 sqlite3_open(":memory:", &g.db);
1351 db_multi_exec("CREATE TABLE sfile(pathname TEXT);");
1352 db_multi_exec("CREATE TABLE vfile(pathname);");
1353 vfile_scan(&base, blob_size(&base), 0, 0, 0);
1354 db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'");
1355 allRepo = 0;
1356 }
1357 @ <html>
1358 @ <head>
1359 @ <base href="%s(g.zBaseURL)/" />
1360 @ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1361 @ <title>Repository List</title>
1362 @ </head>
1363 @ <body>
1364 n = db_int(0, "SELECT count(*) FROM sfile");
1365 if( n>0 ){
1366 Stmt q;
1367 sqlite3_int64 iNow, iMTime;
1368 @ <h1 align="center">Fossil Repositories</h1>
1369 @ <table border="0" class="sortable" data-init-sort="1" \
1370 @ data-column-types="tnk"><thead>
1371 @ <tr><th>Filename<th width="20"><th>Last Modified</tr>
1372 @ </thead><tbody>
1373 db_prepare(&q, "SELECT pathname"
1374 " FROM sfile ORDER BY pathname COLLATE nocase;");
1375 iNow = db_int64(0, "SELECT strftime('%%s','now')");
1376 while( db_step(&q)==SQLITE_ROW ){
1377 const char *zName = db_column_text(&q, 0);
1378 int nName = (int)strlen(zName);
1379 char *zUrl;
1380 char *zAge;
1381 char *zFull;
1382 if( nName<7 ) continue;
1383 zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
1384 if( zName[0]=='/'
1385 #ifdef _WIN32
1386 || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
1387 #endif
1388 ){
1389 zFull = mprintf("%s", zName);
1390 }else if ( allRepo ){
1391 zFull = mprintf("/%s", zName);
1392 }else{
1393 zFull = mprintf("%s/%s", g.zRepositoryName, zName);
1394 }
1395 iMTime = file_mtime(zFull, ExtFILE);
1396 fossil_free(zFull);
1397 if( iMTime<=0 ){
1398 zAge = mprintf("...");
1399 }else{
1400 zAge = human_readable_age((iNow - iMTime)/86400.0);
1401 }
1402 if( sqlite3_strglob("*.fossil", zName)!=0 ){
1403 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
1404 ** do not work for repositories whose names do not end in ".fossil".
1405 ** So do not hyperlink those cases. */
1406 @ <tr><td>%h(zName)
1407 } else if( sqlite3_strglob("*/.*", zName)==0 ){
1408 /* Do not show hidden repos */
1409 @ <tr><td>%h(zName) (hidden)
1410 } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
1411 @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a>
1412 }else{
1413 @ <tr><td><a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a>
1414 }
1415 @ <td></td><td data-sortkey='%010llx(iNow - iMTime)'>%h(zAge)</tr>
1416 fossil_free(zAge);
1417 sqlite3_free(zUrl);
1418 }
1419 @ </tbody></table>
1420 }else{
1421 @ <h1>No Repositories Found</h1>
1422 }
1423 @ <script>%s(builtin_text("sorttable.js"))</script>
1424 @ </body>
1425 @ </html>
1426 cgi_reply();
1427 sqlite3_close(g.db);
1428 g.db = 0;
1429 return n;
1430 }
1431
1432 /*
1433 ** COMMAND: test-list-page
1434 **
1435 ** Usage: %fossil test-list-page DIRECTORY
1436 **
1437 ** Show all repositories underneath DIRECTORY. Or if DIRECTORY is "/"
1438 ** show all repositories in the ~/.fossil file.
1439 */
1440 void test_list_page(void){
1441 if( g.argc<3 ){
1442 g.zRepositoryName = "/";
1443 }else{
1444 g.zRepositoryName = g.argv[2];
1445 }
1446 g.httpOut = stdout;
1447 repo_list_page();
1448 }
1449
1450 /*
1451 ** Called whenever a crash is encountered while processing a webpage.
1452 */
1453 void sigsegv_handler(int x){
1454 #if HAVE_BACKTRACE
@@ -2381,10 +2233,11 @@
2381 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2382 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2383 g.fNoHttpCompress = find_option("nocompress",0,0)!=0;
2384 zInFile = find_option("in",0,1);
2385 if( zInFile ){
 
2386 g.httpIn = fossil_fopen(zInFile, "rb");
2387 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2388 }else{
2389 g.httpIn = stdin;
2390 }
@@ -2845,11 +2698,11 @@
2845 */
2846 void test_warning_page(void){
2847 int iCase = atoi(PD("case","0"));
2848 int i;
2849 login_check_credentials();
2850 if( !g.perm.Setup && !g.perm.Admin ){
2851 login_needed(0);
2852 return;
2853 }
2854 style_header("Warning Test Page");
2855 style_submenu_element("Error Log","%R/errorlog");
2856
--- src/main.c
+++ src/main.c
@@ -972,14 +972,10 @@
972 g.argv[i]);
973 }
974 }
975 }
976
 
 
 
 
977
978 /*
979 ** This function returns a human readable version string.
980 */
981 const char *get_version(){
@@ -1301,154 +1297,10 @@
1297 }
1298 #endif
1299 return zRepo;
1300 }
1301
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1302 /*
1303 ** Called whenever a crash is encountered while processing a webpage.
1304 */
1305 void sigsegv_handler(int x){
1306 #if HAVE_BACKTRACE
@@ -2381,10 +2233,11 @@
2233 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2234 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2235 g.fNoHttpCompress = find_option("nocompress",0,0)!=0;
2236 zInFile = find_option("in",0,1);
2237 if( zInFile ){
2238 backoffice_disable();
2239 g.httpIn = fossil_fopen(zInFile, "rb");
2240 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2241 }else{
2242 g.httpIn = stdin;
2243 }
@@ -2845,11 +2698,11 @@
2698 */
2699 void test_warning_page(void){
2700 int iCase = atoi(PD("case","0"));
2701 int i;
2702 login_check_credentials();
2703 if( !g.perm.Admin ){
2704 login_needed(0);
2705 return;
2706 }
2707 style_header("Warning Test Page");
2708 style_submenu_element("Error Log","%R/errorlog");
2709
+12 -2
--- src/main.mk
+++ src/main.mk
@@ -104,10 +104,11 @@
104104
$(SRCDIR)/printf.c \
105105
$(SRCDIR)/publish.c \
106106
$(SRCDIR)/purge.c \
107107
$(SRCDIR)/rebuild.c \
108108
$(SRCDIR)/regexp.c \
109
+ $(SRCDIR)/repolist.c \
109110
$(SRCDIR)/report.c \
110111
$(SRCDIR)/rss.c \
111112
$(SRCDIR)/schema.c \
112113
$(SRCDIR)/search.c \
113114
$(SRCDIR)/security_audit.c \
@@ -314,10 +315,11 @@
314315
$(OBJDIR)/printf_.c \
315316
$(OBJDIR)/publish_.c \
316317
$(OBJDIR)/purge_.c \
317318
$(OBJDIR)/rebuild_.c \
318319
$(OBJDIR)/regexp_.c \
320
+ $(OBJDIR)/repolist_.c \
319321
$(OBJDIR)/report_.c \
320322
$(OBJDIR)/rss_.c \
321323
$(OBJDIR)/schema_.c \
322324
$(OBJDIR)/search_.c \
323325
$(OBJDIR)/security_audit_.c \
@@ -451,10 +453,11 @@
451453
$(OBJDIR)/printf.o \
452454
$(OBJDIR)/publish.o \
453455
$(OBJDIR)/purge.o \
454456
$(OBJDIR)/rebuild.o \
455457
$(OBJDIR)/regexp.o \
458
+ $(OBJDIR)/repolist.o \
456459
$(OBJDIR)/report.o \
457460
$(OBJDIR)/rss.o \
458461
$(OBJDIR)/schema.o \
459462
$(OBJDIR)/search.o \
460463
$(OBJDIR)/security_audit.o \
@@ -574,11 +577,10 @@
574577
-DSQLITE_USE_ALLOCA \
575578
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
576579
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
577580
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
578581
-DSQLITE_ENABLE_FTS4 \
579
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
580582
-DSQLITE_ENABLE_DBSTAT_VTAB \
581583
-DSQLITE_ENABLE_JSON1 \
582584
-DSQLITE_ENABLE_FTS5 \
583585
-DSQLITE_ENABLE_STMTVTAB \
584586
-DSQLITE_HAVE_ZLIB \
@@ -601,11 +603,10 @@
601603
-DSQLITE_USE_ALLOCA \
602604
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
603605
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
604606
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
605607
-DSQLITE_ENABLE_FTS4 \
606
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
607608
-DSQLITE_ENABLE_DBSTAT_VTAB \
608609
-DSQLITE_ENABLE_JSON1 \
609610
-DSQLITE_ENABLE_FTS5 \
610611
-DSQLITE_ENABLE_STMTVTAB \
611612
-DSQLITE_HAVE_ZLIB \
@@ -786,10 +787,11 @@
786787
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
787788
$(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
788789
$(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
789790
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
790791
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
792
+ $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
791793
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
792794
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
793795
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
794796
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
795797
$(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -1557,10 +1559,18 @@
15571559
15581560
$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
15591561
$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
15601562
15611563
$(OBJDIR)/regexp.h: $(OBJDIR)/headers
1564
+
1565
+$(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(OBJDIR)/translate
1566
+ $(OBJDIR)/translate $(SRCDIR)/repolist.c >$@
1567
+
1568
+$(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
1569
+ $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
1570
+
1571
+$(OBJDIR)/repolist.h: $(OBJDIR)/headers
15621572
15631573
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
15641574
$(OBJDIR)/translate $(SRCDIR)/report.c >$@
15651575
15661576
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
15671577
--- src/main.mk
+++ src/main.mk
@@ -104,10 +104,11 @@
104 $(SRCDIR)/printf.c \
105 $(SRCDIR)/publish.c \
106 $(SRCDIR)/purge.c \
107 $(SRCDIR)/rebuild.c \
108 $(SRCDIR)/regexp.c \
 
109 $(SRCDIR)/report.c \
110 $(SRCDIR)/rss.c \
111 $(SRCDIR)/schema.c \
112 $(SRCDIR)/search.c \
113 $(SRCDIR)/security_audit.c \
@@ -314,10 +315,11 @@
314 $(OBJDIR)/printf_.c \
315 $(OBJDIR)/publish_.c \
316 $(OBJDIR)/purge_.c \
317 $(OBJDIR)/rebuild_.c \
318 $(OBJDIR)/regexp_.c \
 
319 $(OBJDIR)/report_.c \
320 $(OBJDIR)/rss_.c \
321 $(OBJDIR)/schema_.c \
322 $(OBJDIR)/search_.c \
323 $(OBJDIR)/security_audit_.c \
@@ -451,10 +453,11 @@
451 $(OBJDIR)/printf.o \
452 $(OBJDIR)/publish.o \
453 $(OBJDIR)/purge.o \
454 $(OBJDIR)/rebuild.o \
455 $(OBJDIR)/regexp.o \
 
456 $(OBJDIR)/report.o \
457 $(OBJDIR)/rss.o \
458 $(OBJDIR)/schema.o \
459 $(OBJDIR)/search.o \
460 $(OBJDIR)/security_audit.o \
@@ -574,11 +577,10 @@
574 -DSQLITE_USE_ALLOCA \
575 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
576 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
577 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
578 -DSQLITE_ENABLE_FTS4 \
579 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
580 -DSQLITE_ENABLE_DBSTAT_VTAB \
581 -DSQLITE_ENABLE_JSON1 \
582 -DSQLITE_ENABLE_FTS5 \
583 -DSQLITE_ENABLE_STMTVTAB \
584 -DSQLITE_HAVE_ZLIB \
@@ -601,11 +603,10 @@
601 -DSQLITE_USE_ALLOCA \
602 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
603 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
604 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
605 -DSQLITE_ENABLE_FTS4 \
606 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
607 -DSQLITE_ENABLE_DBSTAT_VTAB \
608 -DSQLITE_ENABLE_JSON1 \
609 -DSQLITE_ENABLE_FTS5 \
610 -DSQLITE_ENABLE_STMTVTAB \
611 -DSQLITE_HAVE_ZLIB \
@@ -786,10 +787,11 @@
786 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
787 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
788 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
789 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
790 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
 
791 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
792 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
793 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
794 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
795 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -1557,10 +1559,18 @@
1557
1558 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1559 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1560
1561 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1562
1563 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1564 $(OBJDIR)/translate $(SRCDIR)/report.c >$@
1565
1566 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
1567
--- src/main.mk
+++ src/main.mk
@@ -104,10 +104,11 @@
104 $(SRCDIR)/printf.c \
105 $(SRCDIR)/publish.c \
106 $(SRCDIR)/purge.c \
107 $(SRCDIR)/rebuild.c \
108 $(SRCDIR)/regexp.c \
109 $(SRCDIR)/repolist.c \
110 $(SRCDIR)/report.c \
111 $(SRCDIR)/rss.c \
112 $(SRCDIR)/schema.c \
113 $(SRCDIR)/search.c \
114 $(SRCDIR)/security_audit.c \
@@ -314,10 +315,11 @@
315 $(OBJDIR)/printf_.c \
316 $(OBJDIR)/publish_.c \
317 $(OBJDIR)/purge_.c \
318 $(OBJDIR)/rebuild_.c \
319 $(OBJDIR)/regexp_.c \
320 $(OBJDIR)/repolist_.c \
321 $(OBJDIR)/report_.c \
322 $(OBJDIR)/rss_.c \
323 $(OBJDIR)/schema_.c \
324 $(OBJDIR)/search_.c \
325 $(OBJDIR)/security_audit_.c \
@@ -451,10 +453,11 @@
453 $(OBJDIR)/printf.o \
454 $(OBJDIR)/publish.o \
455 $(OBJDIR)/purge.o \
456 $(OBJDIR)/rebuild.o \
457 $(OBJDIR)/regexp.o \
458 $(OBJDIR)/repolist.o \
459 $(OBJDIR)/report.o \
460 $(OBJDIR)/rss.o \
461 $(OBJDIR)/schema.o \
462 $(OBJDIR)/search.o \
463 $(OBJDIR)/security_audit.o \
@@ -574,11 +577,10 @@
577 -DSQLITE_USE_ALLOCA \
578 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
579 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
580 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
581 -DSQLITE_ENABLE_FTS4 \
 
582 -DSQLITE_ENABLE_DBSTAT_VTAB \
583 -DSQLITE_ENABLE_JSON1 \
584 -DSQLITE_ENABLE_FTS5 \
585 -DSQLITE_ENABLE_STMTVTAB \
586 -DSQLITE_HAVE_ZLIB \
@@ -601,11 +603,10 @@
603 -DSQLITE_USE_ALLOCA \
604 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
605 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
606 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
607 -DSQLITE_ENABLE_FTS4 \
 
608 -DSQLITE_ENABLE_DBSTAT_VTAB \
609 -DSQLITE_ENABLE_JSON1 \
610 -DSQLITE_ENABLE_FTS5 \
611 -DSQLITE_ENABLE_STMTVTAB \
612 -DSQLITE_HAVE_ZLIB \
@@ -786,10 +787,11 @@
787 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
788 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
789 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
790 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
791 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
792 $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
793 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
794 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
795 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
796 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
797 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -1557,10 +1559,18 @@
1559
1560 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1561 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1562
1563 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
1564
1565 $(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(OBJDIR)/translate
1566 $(OBJDIR)/translate $(SRCDIR)/repolist.c >$@
1567
1568 $(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
1569 $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
1570
1571 $(OBJDIR)/repolist.h: $(OBJDIR)/headers
1572
1573 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1574 $(OBJDIR)/translate $(SRCDIR)/report.c >$@
1575
1576 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
1577
--- src/makeheaders.c
+++ src/makeheaders.c
@@ -1903,10 +1903,22 @@
19031903
pFirst = pFirst->pNext;
19041904
}
19051905
return 1;
19061906
}
19071907
1908
+/*
1909
+** Return TRUE if pFirst is the first token of a static assert.
1910
+*/
1911
+static int isStaticAssert(Token *pFirst){
1912
+ if( (pFirst->nText==13 && strncmp(pFirst->zText, "static_assert", 13)==0)
1913
+ || (pFirst->nText==14 && strncmp(pFirst->zText, "_Static_assert", 14)==0)
1914
+ ){
1915
+ return 1;
1916
+ }else{
1917
+ return 0;
1918
+ }
1919
+}
19081920
19091921
/*
19101922
** This routine is called whenever we encounter a ";" or "=". The stuff
19111923
** between pFirst and pLast constitutes either a typedef or a global
19121924
** variable definition. Do the right thing.
@@ -1961,10 +1973,12 @@
19611973
return nErr;
19621974
}
19631975
}else if( flags & PS_Method ){
19641976
/* Methods are declared by their class. Don't declare separately. */
19651977
return nErr;
1978
+ }else if( isStaticAssert(pFirst) ){
1979
+ return 0;
19661980
}
19671981
isVar = (flags & (PS_Typedef|PS_Method))==0 && isVariableDef(pFirst,pEnd);
19681982
if( isVar && (flags & (PS_Interface|PS_Export|PS_Local))!=0
19691983
&& (flags & PS_Extern)==0 ){
19701984
fprintf(stderr,"%s:%d: Can't define a variable in this context\n",
19711985
--- src/makeheaders.c
+++ src/makeheaders.c
@@ -1903,10 +1903,22 @@
1903 pFirst = pFirst->pNext;
1904 }
1905 return 1;
1906 }
1907
 
 
 
 
 
 
 
 
 
 
 
 
1908
1909 /*
1910 ** This routine is called whenever we encounter a ";" or "=". The stuff
1911 ** between pFirst and pLast constitutes either a typedef or a global
1912 ** variable definition. Do the right thing.
@@ -1961,10 +1973,12 @@
1961 return nErr;
1962 }
1963 }else if( flags & PS_Method ){
1964 /* Methods are declared by their class. Don't declare separately. */
1965 return nErr;
 
 
1966 }
1967 isVar = (flags & (PS_Typedef|PS_Method))==0 && isVariableDef(pFirst,pEnd);
1968 if( isVar && (flags & (PS_Interface|PS_Export|PS_Local))!=0
1969 && (flags & PS_Extern)==0 ){
1970 fprintf(stderr,"%s:%d: Can't define a variable in this context\n",
1971
--- src/makeheaders.c
+++ src/makeheaders.c
@@ -1903,10 +1903,22 @@
1903 pFirst = pFirst->pNext;
1904 }
1905 return 1;
1906 }
1907
1908 /*
1909 ** Return TRUE if pFirst is the first token of a static assert.
1910 */
1911 static int isStaticAssert(Token *pFirst){
1912 if( (pFirst->nText==13 && strncmp(pFirst->zText, "static_assert", 13)==0)
1913 || (pFirst->nText==14 && strncmp(pFirst->zText, "_Static_assert", 14)==0)
1914 ){
1915 return 1;
1916 }else{
1917 return 0;
1918 }
1919 }
1920
1921 /*
1922 ** This routine is called whenever we encounter a ";" or "=". The stuff
1923 ** between pFirst and pLast constitutes either a typedef or a global
1924 ** variable definition. Do the right thing.
@@ -1961,10 +1973,12 @@
1973 return nErr;
1974 }
1975 }else if( flags & PS_Method ){
1976 /* Methods are declared by their class. Don't declare separately. */
1977 return nErr;
1978 }else if( isStaticAssert(pFirst) ){
1979 return 0;
1980 }
1981 isVar = (flags & (PS_Typedef|PS_Method))==0 && isVariableDef(pFirst,pEnd);
1982 if( isVar && (flags & (PS_Interface|PS_Export|PS_Local))!=0
1983 && (flags & PS_Extern)==0 ){
1984 fprintf(stderr,"%s:%d: Can't define a variable in this context\n",
1985
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -114,10 +114,11 @@
114114
printf
115115
publish
116116
purge
117117
rebuild
118118
regexp
119
+ repolist
119120
report
120121
rss
121122
schema
122123
search
123124
security_audit
@@ -192,11 +193,10 @@
192193
-DSQLITE_USE_ALLOCA
193194
-DSQLITE_ENABLE_LOCKING_STYLE=0
194195
-DSQLITE_DEFAULT_FILE_FORMAT=4
195196
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
196197
-DSQLITE_ENABLE_FTS4
197
- -DSQLITE_ENABLE_FTS3_PARENTHESIS
198198
-DSQLITE_ENABLE_DBSTAT_VTAB
199199
-DSQLITE_ENABLE_JSON1
200200
-DSQLITE_ENABLE_FTS5
201201
-DSQLITE_ENABLE_STMTVTAB
202202
-DSQLITE_HAVE_ZLIB
@@ -710,11 +710,11 @@
710710
#### The directories where the OpenSSL include and library files are located.
711711
# The recommended usage here is to use the Sysinternals junction tool
712712
# to create a hard link between an "openssl-1.x" sub-directory of the
713713
# Fossil source code directory and the target OpenSSL source directory.
714714
#
715
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
715
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
716716
OPENSSLINCDIR = $(OPENSSLDIR)/include
717717
OPENSSLLIBDIR = $(OPENSSLDIR)
718718
719719
#### Either the directory where the Tcl library is installed or the Tcl
720720
# source code directory resides (depending on the value of the macro
@@ -1566,11 +1566,11 @@
15661566
!ifndef USE_SEE
15671567
USE_SEE = 0
15681568
!endif
15691569
15701570
!if $(FOSSIL_ENABLE_SSL)!=0
1571
-SSLDIR = $(B)\compat\openssl-1.1.1
1571
+SSLDIR = $(B)\compat\openssl-1.1.1a
15721572
SSLINCDIR = $(SSLDIR)\include
15731573
!if $(FOSSIL_DYNAMIC_BUILD)!=0
15741574
SSLLIBDIR = $(SSLDIR)
15751575
!else
15761576
SSLLIBDIR = $(SSLDIR)
@@ -1816,11 +1816,15 @@
18161816
@echo Building OpenSSL from "$(SSLDIR)"...
18171817
!if "$(PERLDIR)" != ""
18181818
@set PATH=$(PERLDIR);$(PATH)
18191819
!endif
18201820
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1821
+!if $(FOSSIL_ENABLE_WINXP)!=0
1822
+ @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1823
+!else
18211824
@pushd "$(SSLDIR)" && $(MAKE) && popd
1825
+!endif
18221826
!endif
18231827
18241828
!if $(FOSSIL_ENABLE_MINIZ)==0
18251829
!if $(FOSSIL_BUILD_ZLIB)!=0
18261830
APPTARGETS = $(APPTARGETS) zlib
18271831
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -114,10 +114,11 @@
114 printf
115 publish
116 purge
117 rebuild
118 regexp
 
119 report
120 rss
121 schema
122 search
123 security_audit
@@ -192,11 +193,10 @@
192 -DSQLITE_USE_ALLOCA
193 -DSQLITE_ENABLE_LOCKING_STYLE=0
194 -DSQLITE_DEFAULT_FILE_FORMAT=4
195 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
196 -DSQLITE_ENABLE_FTS4
197 -DSQLITE_ENABLE_FTS3_PARENTHESIS
198 -DSQLITE_ENABLE_DBSTAT_VTAB
199 -DSQLITE_ENABLE_JSON1
200 -DSQLITE_ENABLE_FTS5
201 -DSQLITE_ENABLE_STMTVTAB
202 -DSQLITE_HAVE_ZLIB
@@ -710,11 +710,11 @@
710 #### The directories where the OpenSSL include and library files are located.
711 # The recommended usage here is to use the Sysinternals junction tool
712 # to create a hard link between an "openssl-1.x" sub-directory of the
713 # Fossil source code directory and the target OpenSSL source directory.
714 #
715 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
716 OPENSSLINCDIR = $(OPENSSLDIR)/include
717 OPENSSLLIBDIR = $(OPENSSLDIR)
718
719 #### Either the directory where the Tcl library is installed or the Tcl
720 # source code directory resides (depending on the value of the macro
@@ -1566,11 +1566,11 @@
1566 !ifndef USE_SEE
1567 USE_SEE = 0
1568 !endif
1569
1570 !if $(FOSSIL_ENABLE_SSL)!=0
1571 SSLDIR = $(B)\compat\openssl-1.1.1
1572 SSLINCDIR = $(SSLDIR)\include
1573 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1574 SSLLIBDIR = $(SSLDIR)
1575 !else
1576 SSLLIBDIR = $(SSLDIR)
@@ -1816,11 +1816,15 @@
1816 @echo Building OpenSSL from "$(SSLDIR)"...
1817 !if "$(PERLDIR)" != ""
1818 @set PATH=$(PERLDIR);$(PATH)
1819 !endif
1820 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
 
 
 
1821 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
1822 !endif
1823
1824 !if $(FOSSIL_ENABLE_MINIZ)==0
1825 !if $(FOSSIL_BUILD_ZLIB)!=0
1826 APPTARGETS = $(APPTARGETS) zlib
1827
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -114,10 +114,11 @@
114 printf
115 publish
116 purge
117 rebuild
118 regexp
119 repolist
120 report
121 rss
122 schema
123 search
124 security_audit
@@ -192,11 +193,10 @@
193 -DSQLITE_USE_ALLOCA
194 -DSQLITE_ENABLE_LOCKING_STYLE=0
195 -DSQLITE_DEFAULT_FILE_FORMAT=4
196 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
197 -DSQLITE_ENABLE_FTS4
 
198 -DSQLITE_ENABLE_DBSTAT_VTAB
199 -DSQLITE_ENABLE_JSON1
200 -DSQLITE_ENABLE_FTS5
201 -DSQLITE_ENABLE_STMTVTAB
202 -DSQLITE_HAVE_ZLIB
@@ -710,11 +710,11 @@
710 #### The directories where the OpenSSL include and library files are located.
711 # The recommended usage here is to use the Sysinternals junction tool
712 # to create a hard link between an "openssl-1.x" sub-directory of the
713 # Fossil source code directory and the target OpenSSL source directory.
714 #
715 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
716 OPENSSLINCDIR = $(OPENSSLDIR)/include
717 OPENSSLLIBDIR = $(OPENSSLDIR)
718
719 #### Either the directory where the Tcl library is installed or the Tcl
720 # source code directory resides (depending on the value of the macro
@@ -1566,11 +1566,11 @@
1566 !ifndef USE_SEE
1567 USE_SEE = 0
1568 !endif
1569
1570 !if $(FOSSIL_ENABLE_SSL)!=0
1571 SSLDIR = $(B)\compat\openssl-1.1.1a
1572 SSLINCDIR = $(SSLDIR)\include
1573 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1574 SSLLIBDIR = $(SSLDIR)
1575 !else
1576 SSLLIBDIR = $(SSLDIR)
@@ -1816,11 +1816,15 @@
1816 @echo Building OpenSSL from "$(SSLDIR)"...
1817 !if "$(PERLDIR)" != ""
1818 @set PATH=$(PERLDIR);$(PATH)
1819 !endif
1820 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1821 !if $(FOSSIL_ENABLE_WINXP)!=0
1822 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1823 !else
1824 @pushd "$(SSLDIR)" && $(MAKE) && popd
1825 !endif
1826 !endif
1827
1828 !if $(FOSSIL_ENABLE_MINIZ)==0
1829 !if $(FOSSIL_BUILD_ZLIB)!=0
1830 APPTARGETS = $(APPTARGETS) zlib
1831
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -114,10 +114,11 @@
114114
printf
115115
publish
116116
purge
117117
rebuild
118118
regexp
119
+ repolist
119120
report
120121
rss
121122
schema
122123
search
123124
security_audit
@@ -192,11 +193,10 @@
192193
-DSQLITE_USE_ALLOCA
193194
-DSQLITE_ENABLE_LOCKING_STYLE=0
194195
-DSQLITE_DEFAULT_FILE_FORMAT=4
195196
-DSQLITE_ENABLE_EXPLAIN_COMMENTS
196197
-DSQLITE_ENABLE_FTS4
197
- -DSQLITE_ENABLE_FTS3_PARENTHESIS
198198
-DSQLITE_ENABLE_DBSTAT_VTAB
199199
-DSQLITE_ENABLE_JSON1
200200
-DSQLITE_ENABLE_FTS5
201201
-DSQLITE_ENABLE_STMTVTAB
202202
-DSQLITE_HAVE_ZLIB
@@ -710,11 +710,11 @@
710710
#### The directories where the OpenSSL include and library files are located.
711711
# The recommended usage here is to use the Sysinternals junction tool
712712
# to create a hard link between an "openssl-1.x" sub-directory of the
713713
# Fossil source code directory and the target OpenSSL source directory.
714714
#
715
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
715
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
716716
OPENSSLINCDIR = $(OPENSSLDIR)/include
717717
OPENSSLLIBDIR = $(OPENSSLDIR)
718718
719719
#### Either the directory where the Tcl library is installed or the Tcl
720720
# source code directory resides (depending on the value of the macro
@@ -1566,11 +1566,11 @@
15661566
!ifndef USE_SEE
15671567
USE_SEE = 0
15681568
!endif
15691569
15701570
!if $(FOSSIL_ENABLE_SSL)!=0
1571
-SSLDIR = $(B)\compat\openssl-1.1.1
1571
+SSLDIR = $(B)\compat\openssl-1.1.1a
15721572
SSLINCDIR = $(SSLDIR)\include
15731573
!if $(FOSSIL_DYNAMIC_BUILD)!=0
15741574
SSLLIBDIR = $(SSLDIR)
15751575
!else
15761576
SSLLIBDIR = $(SSLDIR)
@@ -1816,11 +1816,15 @@
18161816
@echo Building OpenSSL from "$(SSLDIR)"...
18171817
!if "$(PERLDIR)" != ""
18181818
@set PATH=$(PERLDIR);$(PATH)
18191819
!endif
18201820
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1821
+!if $(FOSSIL_ENABLE_WINXP)!=0
1822
+ @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1823
+!else
18211824
@pushd "$(SSLDIR)" && $(MAKE) && popd
1825
+!endif
18221826
!endif
18231827
18241828
!if $(FOSSIL_ENABLE_MINIZ)==0
18251829
!if $(FOSSIL_BUILD_ZLIB)!=0
18261830
APPTARGETS = $(APPTARGETS) zlib
18271831
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -114,10 +114,11 @@
114 printf
115 publish
116 purge
117 rebuild
118 regexp
 
119 report
120 rss
121 schema
122 search
123 security_audit
@@ -192,11 +193,10 @@
192 -DSQLITE_USE_ALLOCA
193 -DSQLITE_ENABLE_LOCKING_STYLE=0
194 -DSQLITE_DEFAULT_FILE_FORMAT=4
195 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
196 -DSQLITE_ENABLE_FTS4
197 -DSQLITE_ENABLE_FTS3_PARENTHESIS
198 -DSQLITE_ENABLE_DBSTAT_VTAB
199 -DSQLITE_ENABLE_JSON1
200 -DSQLITE_ENABLE_FTS5
201 -DSQLITE_ENABLE_STMTVTAB
202 -DSQLITE_HAVE_ZLIB
@@ -710,11 +710,11 @@
710 #### The directories where the OpenSSL include and library files are located.
711 # The recommended usage here is to use the Sysinternals junction tool
712 # to create a hard link between an "openssl-1.x" sub-directory of the
713 # Fossil source code directory and the target OpenSSL source directory.
714 #
715 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
716 OPENSSLINCDIR = $(OPENSSLDIR)/include
717 OPENSSLLIBDIR = $(OPENSSLDIR)
718
719 #### Either the directory where the Tcl library is installed or the Tcl
720 # source code directory resides (depending on the value of the macro
@@ -1566,11 +1566,11 @@
1566 !ifndef USE_SEE
1567 USE_SEE = 0
1568 !endif
1569
1570 !if $(FOSSIL_ENABLE_SSL)!=0
1571 SSLDIR = $(B)\compat\openssl-1.1.1
1572 SSLINCDIR = $(SSLDIR)\include
1573 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1574 SSLLIBDIR = $(SSLDIR)
1575 !else
1576 SSLLIBDIR = $(SSLDIR)
@@ -1816,11 +1816,15 @@
1816 @echo Building OpenSSL from "$(SSLDIR)"...
1817 !if "$(PERLDIR)" != ""
1818 @set PATH=$(PERLDIR);$(PATH)
1819 !endif
1820 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
 
 
 
1821 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
1822 !endif
1823
1824 !if $(FOSSIL_ENABLE_MINIZ)==0
1825 !if $(FOSSIL_BUILD_ZLIB)!=0
1826 APPTARGETS = $(APPTARGETS) zlib
1827
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -114,10 +114,11 @@
114 printf
115 publish
116 purge
117 rebuild
118 regexp
119 repolist
120 report
121 rss
122 schema
123 search
124 security_audit
@@ -192,11 +193,10 @@
193 -DSQLITE_USE_ALLOCA
194 -DSQLITE_ENABLE_LOCKING_STYLE=0
195 -DSQLITE_DEFAULT_FILE_FORMAT=4
196 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
197 -DSQLITE_ENABLE_FTS4
 
198 -DSQLITE_ENABLE_DBSTAT_VTAB
199 -DSQLITE_ENABLE_JSON1
200 -DSQLITE_ENABLE_FTS5
201 -DSQLITE_ENABLE_STMTVTAB
202 -DSQLITE_HAVE_ZLIB
@@ -710,11 +710,11 @@
710 #### The directories where the OpenSSL include and library files are located.
711 # The recommended usage here is to use the Sysinternals junction tool
712 # to create a hard link between an "openssl-1.x" sub-directory of the
713 # Fossil source code directory and the target OpenSSL source directory.
714 #
715 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
716 OPENSSLINCDIR = $(OPENSSLDIR)/include
717 OPENSSLLIBDIR = $(OPENSSLDIR)
718
719 #### Either the directory where the Tcl library is installed or the Tcl
720 # source code directory resides (depending on the value of the macro
@@ -1566,11 +1566,11 @@
1566 !ifndef USE_SEE
1567 USE_SEE = 0
1568 !endif
1569
1570 !if $(FOSSIL_ENABLE_SSL)!=0
1571 SSLDIR = $(B)\compat\openssl-1.1.1a
1572 SSLINCDIR = $(SSLDIR)\include
1573 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1574 SSLLIBDIR = $(SSLDIR)
1575 !else
1576 SSLLIBDIR = $(SSLDIR)
@@ -1816,11 +1816,15 @@
1816 @echo Building OpenSSL from "$(SSLDIR)"...
1817 !if "$(PERLDIR)" != ""
1818 @set PATH=$(PERLDIR);$(PATH)
1819 !endif
1820 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1821 !if $(FOSSIL_ENABLE_WINXP)!=0
1822 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1823 !else
1824 @pushd "$(SSLDIR)" && $(MAKE) && popd
1825 !endif
1826 !endif
1827
1828 !if $(FOSSIL_ENABLE_MINIZ)==0
1829 !if $(FOSSIL_BUILD_ZLIB)!=0
1830 APPTARGETS = $(APPTARGETS) zlib
1831
+1 -1
--- src/manifest.c
+++ src/manifest.c
@@ -2529,11 +2529,11 @@
25292529
schema_forum();
25302530
froot = p->zThreadRoot ? uuid_to_rid(p->zThreadRoot, 1) : rid;
25312531
fprev = p->nParent ? uuid_to_rid(p->azParent[0],1) : 0;
25322532
firt = p->zInReplyTo ? uuid_to_rid(p->zInReplyTo,1) : 0;
25332533
db_multi_exec(
2534
- "INSERT INTO forumpost(fpid,froot,fprev,firt,fmtime)"
2534
+ "REPLACE INTO forumpost(fpid,froot,fprev,firt,fmtime)"
25352535
"VALUES(%d,%d,nullif(%d,0),nullif(%d,0),%.17g)",
25362536
p->rid, froot, fprev, firt, p->rDate
25372537
);
25382538
if( firt==0 ){
25392539
/* This is the start of a new thread, either the initial entry
25402540
--- src/manifest.c
+++ src/manifest.c
@@ -2529,11 +2529,11 @@
2529 schema_forum();
2530 froot = p->zThreadRoot ? uuid_to_rid(p->zThreadRoot, 1) : rid;
2531 fprev = p->nParent ? uuid_to_rid(p->azParent[0],1) : 0;
2532 firt = p->zInReplyTo ? uuid_to_rid(p->zInReplyTo,1) : 0;
2533 db_multi_exec(
2534 "INSERT INTO forumpost(fpid,froot,fprev,firt,fmtime)"
2535 "VALUES(%d,%d,nullif(%d,0),nullif(%d,0),%.17g)",
2536 p->rid, froot, fprev, firt, p->rDate
2537 );
2538 if( firt==0 ){
2539 /* This is the start of a new thread, either the initial entry
2540
--- src/manifest.c
+++ src/manifest.c
@@ -2529,11 +2529,11 @@
2529 schema_forum();
2530 froot = p->zThreadRoot ? uuid_to_rid(p->zThreadRoot, 1) : rid;
2531 fprev = p->nParent ? uuid_to_rid(p->azParent[0],1) : 0;
2532 firt = p->zInReplyTo ? uuid_to_rid(p->zInReplyTo,1) : 0;
2533 db_multi_exec(
2534 "REPLACE INTO forumpost(fpid,froot,fprev,firt,fmtime)"
2535 "VALUES(%d,%d,nullif(%d,0),nullif(%d,0),%.17g)",
2536 p->rid, froot, fprev, firt, p->rDate
2537 );
2538 if( firt==0 ){
2539 /* This is the start of a new thread, either the initial entry
2540
+3 -2
--- src/markdown.md
+++ src/markdown.md
@@ -25,14 +25,15 @@
2525
> 2. **\[display text\]\(URL "Title"\)**
2626
> 3. **\[display text\]\(URL 'Title'\)**
2727
> 4. **\<URL\>**
2828
> 5. **\[display text\]\[label\]**
2929
> 6. **\[display text\]\[\]**
30
+> 7. **\[display text\]**
3031
31
-> **URL** may optionally be written **\<URL\>**. With link formats 5 and 6
32
+> **URL** may optionally be written **\<URL\>**. With link formats 5, 6, and 7
3233
> ("reference links"), the URL is supplied elsewhere in the document, as shown
33
-> below. Link format 6 reuses the display text as the label. Labels are
34
+> below. Link formats 6 and 7 reuse the display text as the label. Labels are
3435
> case-insensitive. The title may be split onto the next line with optional
3536
> indenting.
3637
3738
> * **\[label\]:&nbsp;URL**
3839
> * **\[label\]:&nbsp;URL&nbsp;"Title"**
3940
--- src/markdown.md
+++ src/markdown.md
@@ -25,14 +25,15 @@
25 > 2. **\[display text\]\(URL "Title"\)**
26 > 3. **\[display text\]\(URL 'Title'\)**
27 > 4. **\<URL\>**
28 > 5. **\[display text\]\[label\]**
29 > 6. **\[display text\]\[\]**
 
30
31 > **URL** may optionally be written **\<URL\>**. With link formats 5 and 6
32 > ("reference links"), the URL is supplied elsewhere in the document, as shown
33 > below. Link format 6 reuses the display text as the label. Labels are
34 > case-insensitive. The title may be split onto the next line with optional
35 > indenting.
36
37 > * **\[label\]:&nbsp;URL**
38 > * **\[label\]:&nbsp;URL&nbsp;"Title"**
39
--- src/markdown.md
+++ src/markdown.md
@@ -25,14 +25,15 @@
25 > 2. **\[display text\]\(URL "Title"\)**
26 > 3. **\[display text\]\(URL 'Title'\)**
27 > 4. **\<URL\>**
28 > 5. **\[display text\]\[label\]**
29 > 6. **\[display text\]\[\]**
30 > 7. **\[display text\]**
31
32 > **URL** may optionally be written **\<URL\>**. With link formats 5, 6, and 7
33 > ("reference links"), the URL is supplied elsewhere in the document, as shown
34 > below. Link formats 6 and 7 reuse the display text as the label. Labels are
35 > case-insensitive. The title may be split onto the next line with optional
36 > indenting.
37
38 > * **\[label\]:&nbsp;URL**
39 > * **\[label\]:&nbsp;URL&nbsp;"Title"**
40
+10
--- src/path.c
+++ src/path.c
@@ -192,10 +192,20 @@
192192
int i;
193193
if( path.nStep<2 ) return 0;
194194
for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){}
195195
return p;
196196
}
197
+
198
+/*
199
+** Return an estimate of the number of comparisons remaining in order
200
+** to bisect path. This is based on the log2() of path.nStep.
201
+*/
202
+int path_search_depth(void){
203
+ int i, j;
204
+ for(i=0, j=1; j<path.nStep; i++, j+=j){}
205
+ return i;
206
+}
197207
198208
/*
199209
** Compute the shortest path between two check-ins and then transfer
200210
** that path into the "ancestor" table. This is a utility used by
201211
** both /annotate and /finfo. See also: compute_direct_ancestors().
202212
--- src/path.c
+++ src/path.c
@@ -192,10 +192,20 @@
192 int i;
193 if( path.nStep<2 ) return 0;
194 for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){}
195 return p;
196 }
 
 
 
 
 
 
 
 
 
 
197
198 /*
199 ** Compute the shortest path between two check-ins and then transfer
200 ** that path into the "ancestor" table. This is a utility used by
201 ** both /annotate and /finfo. See also: compute_direct_ancestors().
202
--- src/path.c
+++ src/path.c
@@ -192,10 +192,20 @@
192 int i;
193 if( path.nStep<2 ) return 0;
194 for(p=path.pEnd, i=0; p && i<path.nStep/2; p=p->pFrom, i++){}
195 return p;
196 }
197
198 /*
199 ** Return an estimate of the number of comparisons remaining in order
200 ** to bisect path. This is based on the log2() of path.nStep.
201 */
202 int path_search_depth(void){
203 int i, j;
204 for(i=0, j=1; j<path.nStep; i++, j+=j){}
205 return i;
206 }
207
208 /*
209 ** Compute the shortest path between two check-ins and then transfer
210 ** that path into the "ancestor" table. This is a utility used by
211 ** both /annotate and /finfo. See also: compute_direct_ancestors().
212
+1 -1
--- src/printf.c
+++ src/printf.c
@@ -1002,11 +1002,11 @@
10021002
if( out==0 ) return;
10031003
}
10041004
now = time(0);
10051005
pNow = gmtime(&now);
10061006
fprintf(out, "------------- %04d-%02d-%02d %02d:%02d:%02d UTC ------------\n",
1007
- pNow->tm_year+1900, pNow->tm_mon+1, pNow->tm_mday+1,
1007
+ pNow->tm_year+1900, pNow->tm_mon+1, pNow->tm_mday,
10081008
pNow->tm_hour, pNow->tm_min, pNow->tm_sec);
10091009
va_start(ap, zFormat);
10101010
vfprintf(out, zFormat, ap);
10111011
fprintf(out, "\n");
10121012
va_end(ap);
10131013
--- src/printf.c
+++ src/printf.c
@@ -1002,11 +1002,11 @@
1002 if( out==0 ) return;
1003 }
1004 now = time(0);
1005 pNow = gmtime(&now);
1006 fprintf(out, "------------- %04d-%02d-%02d %02d:%02d:%02d UTC ------------\n",
1007 pNow->tm_year+1900, pNow->tm_mon+1, pNow->tm_mday+1,
1008 pNow->tm_hour, pNow->tm_min, pNow->tm_sec);
1009 va_start(ap, zFormat);
1010 vfprintf(out, zFormat, ap);
1011 fprintf(out, "\n");
1012 va_end(ap);
1013
--- src/printf.c
+++ src/printf.c
@@ -1002,11 +1002,11 @@
1002 if( out==0 ) return;
1003 }
1004 now = time(0);
1005 pNow = gmtime(&now);
1006 fprintf(out, "------------- %04d-%02d-%02d %02d:%02d:%02d UTC ------------\n",
1007 pNow->tm_year+1900, pNow->tm_mon+1, pNow->tm_mday,
1008 pNow->tm_hour, pNow->tm_min, pNow->tm_sec);
1009 va_start(ap, zFormat);
1010 vfprintf(out, zFormat, ap);
1011 fprintf(out, "\n");
1012 va_end(ap);
1013
+6 -39
--- src/regexp.c
+++ src/regexp.c
@@ -16,46 +16,11 @@
1616
*******************************************************************************
1717
**
1818
** This file was adapted from the test_regexp.c file in SQLite3. That
1919
** file is in the public domain.
2020
**
21
-** The code in this file implements a compact but reasonably
22
-** efficient regular-expression matcher for posix extended regular
23
-** expressions against UTF8 text. The following syntax is supported:
24
-**
25
-** X* zero or more occurrences of X
26
-** X+ one or more occurrences of X
27
-** X? zero or one occurrences of X
28
-** X{p,q} between p and q occurrences of X
29
-** (X) match X
30
-** X|Y X or Y
31
-** ^X X occurring at the beginning of the string
32
-** X$ X occurring at the end of the string
33
-** . Match any single character
34
-** \c Character c where c is one of \{}()[]|*+?.
35
-** \c C-language escapes for c in afnrtv. ex: \t or \n
36
-** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX
37
-** \xXX Where XX is exactly 2 hex digits, unicode value XX
38
-** [abc] Any single character from the set abc
39
-** [^abc] Any single character not in the set abc
40
-** [a-z] Any single character in the range a-z
41
-** [^a-z] Any single character not in the range a-z
42
-** \b Word boundary
43
-** \w Word character. [A-Za-z0-9_]
44
-** \W Non-word character
45
-** \d Digit
46
-** \D Non-digit
47
-** \s Whitespace character
48
-** \S Non-whitespace character
49
-**
50
-** A nondeterministic finite automaton (NFA) is used for matching, so the
51
-** performance is bounded by O(N*M) where N is the size of the regular
52
-** expression and M is the size of the input string. The matcher never
53
-** exhibits exponential behavior. Note that the X{p,q} operator expands
54
-** to p copies of X following by q-p copies of X? and that the size of the
55
-** regular expression in the O(N*M) performance bound is computed after
56
-** this expansion.
21
+** See ../www/grep.md for details of the algorithm and RE dialect.
5722
*/
5823
#include "config.h"
5924
#include "regexp.h"
6025
6126
/* The end-of-input character */
@@ -827,16 +792,18 @@
827792
/*
828793
** COMMAND: grep
829794
**
830795
** Usage: %fossil grep [OPTIONS] PATTERN FILENAME
831796
**
832
-** Run grep over all historic version of FILENAME
797
+** Attempt to match the given POSIX extended regular expression PATTERN
798
+** over all historic versions of FILENAME. For details of the supported
799
+** RE dialect, see https://fossil-scm.org/fossil/doc/trunk/www/grep.md
833800
**
834801
** Options:
835802
**
836803
** -i|--ignore-case Ignore case
837
-** -l|--files-with-matches Print only filenames that match
804
+** -l|--files-with-matches List only checkin ID for versions that match
838805
** -v|--verbose Show each file as it is analyzed
839806
*/
840807
void re_grep_cmd(void){
841808
u32 flags = 0;
842809
int bVerbose = 0;
@@ -848,11 +815,11 @@
848815
if( find_option("ignore-case","i",0)!=0 ) ignoreCase = 1;
849816
if( find_option("files-with-matches","l",0)!=0 ) flags |= GREP_EXISTS;
850817
if( find_option("verbose","v",0)!=0 ) bVerbose = 1;
851818
db_find_and_open_repository(0, 0);
852819
verify_all_options();
853
- if( g.argc<3 ){
820
+ if( g.argc<4 ){
854821
usage("REGEXP FILENAME");
855822
}
856823
zErr = re_compile(&pRe, g.argv[2], ignoreCase);
857824
if( zErr ) fossil_fatal("%s", zErr);
858825
859826
860827
ADDED src/repolist.c
--- src/regexp.c
+++ src/regexp.c
@@ -16,46 +16,11 @@
16 *******************************************************************************
17 **
18 ** This file was adapted from the test_regexp.c file in SQLite3. That
19 ** file is in the public domain.
20 **
21 ** The code in this file implements a compact but reasonably
22 ** efficient regular-expression matcher for posix extended regular
23 ** expressions against UTF8 text. The following syntax is supported:
24 **
25 ** X* zero or more occurrences of X
26 ** X+ one or more occurrences of X
27 ** X? zero or one occurrences of X
28 ** X{p,q} between p and q occurrences of X
29 ** (X) match X
30 ** X|Y X or Y
31 ** ^X X occurring at the beginning of the string
32 ** X$ X occurring at the end of the string
33 ** . Match any single character
34 ** \c Character c where c is one of \{}()[]|*+?.
35 ** \c C-language escapes for c in afnrtv. ex: \t or \n
36 ** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX
37 ** \xXX Where XX is exactly 2 hex digits, unicode value XX
38 ** [abc] Any single character from the set abc
39 ** [^abc] Any single character not in the set abc
40 ** [a-z] Any single character in the range a-z
41 ** [^a-z] Any single character not in the range a-z
42 ** \b Word boundary
43 ** \w Word character. [A-Za-z0-9_]
44 ** \W Non-word character
45 ** \d Digit
46 ** \D Non-digit
47 ** \s Whitespace character
48 ** \S Non-whitespace character
49 **
50 ** A nondeterministic finite automaton (NFA) is used for matching, so the
51 ** performance is bounded by O(N*M) where N is the size of the regular
52 ** expression and M is the size of the input string. The matcher never
53 ** exhibits exponential behavior. Note that the X{p,q} operator expands
54 ** to p copies of X following by q-p copies of X? and that the size of the
55 ** regular expression in the O(N*M) performance bound is computed after
56 ** this expansion.
57 */
58 #include "config.h"
59 #include "regexp.h"
60
61 /* The end-of-input character */
@@ -827,16 +792,18 @@
827 /*
828 ** COMMAND: grep
829 **
830 ** Usage: %fossil grep [OPTIONS] PATTERN FILENAME
831 **
832 ** Run grep over all historic version of FILENAME
 
 
833 **
834 ** Options:
835 **
836 ** -i|--ignore-case Ignore case
837 ** -l|--files-with-matches Print only filenames that match
838 ** -v|--verbose Show each file as it is analyzed
839 */
840 void re_grep_cmd(void){
841 u32 flags = 0;
842 int bVerbose = 0;
@@ -848,11 +815,11 @@
848 if( find_option("ignore-case","i",0)!=0 ) ignoreCase = 1;
849 if( find_option("files-with-matches","l",0)!=0 ) flags |= GREP_EXISTS;
850 if( find_option("verbose","v",0)!=0 ) bVerbose = 1;
851 db_find_and_open_repository(0, 0);
852 verify_all_options();
853 if( g.argc<3 ){
854 usage("REGEXP FILENAME");
855 }
856 zErr = re_compile(&pRe, g.argv[2], ignoreCase);
857 if( zErr ) fossil_fatal("%s", zErr);
858
859
860 DDED src/repolist.c
--- src/regexp.c
+++ src/regexp.c
@@ -16,46 +16,11 @@
16 *******************************************************************************
17 **
18 ** This file was adapted from the test_regexp.c file in SQLite3. That
19 ** file is in the public domain.
20 **
21 ** See ../www/grep.md for details of the algorithm and RE dialect.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22 */
23 #include "config.h"
24 #include "regexp.h"
25
26 /* The end-of-input character */
@@ -827,16 +792,18 @@
792 /*
793 ** COMMAND: grep
794 **
795 ** Usage: %fossil grep [OPTIONS] PATTERN FILENAME
796 **
797 ** Attempt to match the given POSIX extended regular expression PATTERN
798 ** over all historic versions of FILENAME. For details of the supported
799 ** RE dialect, see https://fossil-scm.org/fossil/doc/trunk/www/grep.md
800 **
801 ** Options:
802 **
803 ** -i|--ignore-case Ignore case
804 ** -l|--files-with-matches List only checkin ID for versions that match
805 ** -v|--verbose Show each file as it is analyzed
806 */
807 void re_grep_cmd(void){
808 u32 flags = 0;
809 int bVerbose = 0;
@@ -848,11 +815,11 @@
815 if( find_option("ignore-case","i",0)!=0 ) ignoreCase = 1;
816 if( find_option("files-with-matches","l",0)!=0 ) flags |= GREP_EXISTS;
817 if( find_option("verbose","v",0)!=0 ) bVerbose = 1;
818 db_find_and_open_repository(0, 0);
819 verify_all_options();
820 if( g.argc<4 ){
821 usage("REGEXP FILENAME");
822 }
823 zErr = re_compile(&pRe, g.argv[2], ignoreCase);
824 if( zErr ) fossil_fatal("%s", zErr);
825
826
827 DDED src/repolist.c
--- a/src/repolist.c
+++ b/src/repolist.c
@@ -0,0 +1,39 @@
1
+/*
2
+** Copyright (c) 2018 D. Richard Hipp
3
+**
4
+** This program is free software; you can redistribute it and/or
5
+** modify it under the terms of thint/* Assert t_cmd
6
+**
7
+**
8
+**
9
+**
10
+** This is an expensive routine in that it has to open and close if(&& !pRepo->zRepoName);
11
+ }/*
12
+** Copyright (c) right (c) 2018 D. Richard Hipp
13
+**
14
+** This program is free software; you can redistribute it and/or
15
+** modify it under the terms of thint/* Assert t_cmd>0 )%R%Relse{
16
+"<h1>No Repositories Found</h1>\n"<style>
17
+ style_render_
18
+*/
19
+voidValid = 0;
20
+
21
+ int n = 0;
22
+ int allRepo;@ <html>
23
+ @ <head>
24
+@ </head>
25
+ @ <body><table border="0" class="sortable" data-init-sort="1" \
26
+ @ data-column-types="tntnk"><thead>
27
+ @ <tr><th>Filename<th width="20">\
28
+ @ "20">\
29
+ @ <th>Last Modified@ <tr><td valign="top">\@ %h(zName)idden repos */
30
+ @ <a href="%R/%T(zUrl)/home" tar@ <a href="%R/%T(zUrl)/home" ta@ <td></td>@ <td></td(iAge)'>%h(zAge)</tr>*
31
+** Copyright (c) 2018 D. Richard 018 D. Richard Hipp
32
+**
33
+** This pro
34
+ }
35
+@ </body>
36
+ @ </html>
37
+ cgi_reply()g.db);
38
+ g.db = 0(pRepo->zRepoName, &dbzAge = mprintf("...");
39
+iAge = 0}returnreturnsqlite3_close(db);1
--- a/src/repolist.c
+++ b/src/repolist.c
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/repolist.c
+++ b/src/repolist.c
@@ -0,0 +1,39 @@
1 /*
2 ** Copyright (c) 2018 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of thint/* Assert t_cmd
6 **
7 **
8 **
9 **
10 ** This is an expensive routine in that it has to open and close if(&& !pRepo->zRepoName);
11 }/*
12 ** Copyright (c) right (c) 2018 D. Richard Hipp
13 **
14 ** This program is free software; you can redistribute it and/or
15 ** modify it under the terms of thint/* Assert t_cmd>0 )%R%Relse{
16 "<h1>No Repositories Found</h1>\n"<style>
17 style_render_
18 */
19 voidValid = 0;
20
21 int n = 0;
22 int allRepo;@ <html>
23 @ <head>
24 @ </head>
25 @ <body><table border="0" class="sortable" data-init-sort="1" \
26 @ data-column-types="tntnk"><thead>
27 @ <tr><th>Filename<th width="20">\
28 @ "20">\
29 @ <th>Last Modified@ <tr><td valign="top">\@ %h(zName)idden repos */
30 @ <a href="%R/%T(zUrl)/home" tar@ <a href="%R/%T(zUrl)/home" ta@ <td></td>@ <td></td(iAge)'>%h(zAge)</tr>*
31 ** Copyright (c) 2018 D. Richard 018 D. Richard Hipp
32 **
33 ** This pro
34 }
35 @ </body>
36 @ </html>
37 cgi_reply()g.db);
38 g.db = 0(pRepo->zRepoName, &dbzAge = mprintf("...");
39 iAge = 0}returnreturnsqlite3_close(db);1
--- src/security_audit.c
+++ src/security_audit.c
@@ -42,15 +42,16 @@
4242
** This page requires administrator access
4343
*/
4444
void secaudit0_page(void){
4545
const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
4646
const char *zPubPages; /* GLOB pattern for public pages */
47
+ const char *zSelfCap; /* Capabilities of self-registered users */
4748
char *z;
4849
int n;
4950
5051
login_check_credentials();
51
- if( !g.perm.Setup && !g.perm.Admin ){
52
+ if( !g.perm.Admin ){
5253
login_needed(0);
5354
return;
5455
}
5556
style_header("Security Audit");
5657
@ <ol>
@@ -60,43 +61,71 @@
6061
** "Private" repos require (non-anonymous) login to access all content,
6162
** though some content may be accessible anonymously.
6263
*/
6364
zAnonCap = db_text("", "SELECT fullcap(NULL)");
6465
zPubPages = db_get("public-pages",0);
66
+ if( db_get_boolean("self-register",0) ){
67
+ CapabilityString *pCap;
68
+ pCap = capability_add(0, db_get("default-perms",""));
69
+ capability_expand(pCap);
70
+ zSelfCap = capability_string(pCap);
71
+ capability_free(pCap);
72
+ }else{
73
+ zSelfCap = fossil_strdup("");
74
+ }
6575
if( hasAnyCap(zAnonCap,"as") ){
6676
@ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
6777
@ it grants administrator privileges to anonymous users. You
6878
@ should <a href="takeitprivate">take this repository private</a>
6979
@ immediately! Or, at least remove the Setup and Admin privileges
7080
@ for users "anonymous" and "login" on the
7181
@ <a href="setup_ulist">User Configuration</a> page.
82
+ }else if( hasAnyCap(zSelfCap,"as") ){
83
+ @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
84
+ @ it grants administrator privileges to self-registered users. You
85
+ @ should <a href="takeitprivate">take this repository private</a>
86
+ @ and/or disable self-registration
87
+ @ immediately! Or, at least remove the Setup and Admin privileges
88
+ @ from the default permissions for new users.
7289
}else if( hasAnyCap(zAnonCap,"y") ){
7390
@ <li><p>This repository is <big><b>INSECURE</b></big> because
7491
@ it allows anonymous users to push unversioned files.
7592
@ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
7693
@ or by removing the "y" permission from users "anonymous" and
7794
@ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
95
+ }else if( hasAnyCap(zSelfCap,"y") ){
96
+ @ <li><p>This repository is <big><b>INSECURE</b></big> because
97
+ @ it allows self-registered users to push unversioned files.
98
+ @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
99
+ @ or by removing the "y" permission from the default permissions or
100
+ @ by disabling self-registration.
78101
}else if( hasAnyCap(zAnonCap,"goz") ){
79102
@ <li><p>This repository is <big><b>PUBLIC</b></big>. All
80103
@ checked-in content can be accessed by anonymous users.
81104
@ <a href="takeitprivate">Take it private</a>.<p>
105
+ }else if( hasAnyCap(zSelfCap,"goz") ){
106
+ @ <li><p>This repository is <big><b>PUBLIC</b></big> because all
107
+ @ checked-in content can be accessed by self-registered users.
108
+ @ This repostory would be private if you disabled self-registration.</p>
82109
}else if( !hasAnyCap(zAnonCap, "jrwy234567")
110
+ && !hasAnyCap(zSelfCap, "jrwy234567")
83111
&& (zPubPages==0 || zPubPages[0]==0) ){
84112
@ <li><p>This repository is <big><b>Completely PRIVATE</b></big>.
85113
@ A valid login and password is required to access any content.
86114
}else{
87115
@ <li><p>This repository is <big><b>Mostly PRIVATE</b></big>.
88116
@ A valid login and password is usually required, however some
89
- @ content can be accessed anonymously:
117
+ @ content can be accessed either anonymously or by self-registered
118
+ @ users:
90119
@ <ul>
91
- if( hasAnyCap(zAnonCap,"j") ){
120
+ if( hasAnyCap(zAnonCap,"j") || hasAnyCap(zSelfCap,"j") ){
92121
@ <li> Wiki pages
93122
}
94
- if( hasAnyCap(zAnonCap,"r") ){
123
+ if( hasAnyCap(zAnonCap,"r") || hasAnyCap(zSelfCap,"r") ){
95124
@ <li> Tickets
96125
}
97
- if( hasAnyCap(zAnonCap,"234567") ){
126
+ if( hasAnyCap(zAnonCap,"234567") || hasAnyCap(zSelfCap,"234567") ){
98127
@ <li> Forum posts
99128
}
100129
if( zPubPages && zPubPages[0] ){
101130
Glob *pGlob = glob_create(zPubPages);
102131
int i;
@@ -410,11 +439,11 @@
410439
**
411440
** Disable anonymous access to this website
412441
*/
413442
void takeitprivate_page(void){
414443
login_check_credentials();
415
- if( !g.perm.Setup && !g.perm.Admin ){
444
+ if( !g.perm.Admin ){
416445
login_needed(0);
417446
return;
418447
}
419448
if( P("cancel") ){
420449
/* User pressed the cancel button. Go back */
@@ -424,10 +453,11 @@
424453
db_multi_exec(
425454
"UPDATE user SET cap=''"
426455
" WHERE login IN ('nobody','anonymous');"
427456
"DELETE FROM config WHERE name='public-pages';"
428457
);
458
+ db_set("self-register","0",0);
429459
cgi_redirect("secaudit0");
430460
}
431461
style_header("Make This Website Private");
432462
@ <p>Click the "Make It Private" button below to disable all
433463
@ anonymous access to this repository. A valid login and password
@@ -458,11 +488,11 @@
458488
void errorlog_page(void){
459489
i64 szFile;
460490
FILE *in;
461491
char z[10000];
462492
login_check_credentials();
463
- if( !g.perm.Setup && !g.perm.Admin ){
493
+ if( !g.perm.Admin ){
464494
login_needed(0);
465495
return;
466496
}
467497
style_header("Server Error Log");
468498
style_submenu_element("Test", "%R/test-warning");
469499
--- src/security_audit.c
+++ src/security_audit.c
@@ -42,15 +42,16 @@
42 ** This page requires administrator access
43 */
44 void secaudit0_page(void){
45 const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
46 const char *zPubPages; /* GLOB pattern for public pages */
 
47 char *z;
48 int n;
49
50 login_check_credentials();
51 if( !g.perm.Setup && !g.perm.Admin ){
52 login_needed(0);
53 return;
54 }
55 style_header("Security Audit");
56 @ <ol>
@@ -60,43 +61,71 @@
60 ** "Private" repos require (non-anonymous) login to access all content,
61 ** though some content may be accessible anonymously.
62 */
63 zAnonCap = db_text("", "SELECT fullcap(NULL)");
64 zPubPages = db_get("public-pages",0);
 
 
 
 
 
 
 
 
 
65 if( hasAnyCap(zAnonCap,"as") ){
66 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
67 @ it grants administrator privileges to anonymous users. You
68 @ should <a href="takeitprivate">take this repository private</a>
69 @ immediately! Or, at least remove the Setup and Admin privileges
70 @ for users "anonymous" and "login" on the
71 @ <a href="setup_ulist">User Configuration</a> page.
 
 
 
 
 
 
 
72 }else if( hasAnyCap(zAnonCap,"y") ){
73 @ <li><p>This repository is <big><b>INSECURE</b></big> because
74 @ it allows anonymous users to push unversioned files.
75 @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
76 @ or by removing the "y" permission from users "anonymous" and
77 @ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
 
 
 
 
 
 
78 }else if( hasAnyCap(zAnonCap,"goz") ){
79 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
80 @ checked-in content can be accessed by anonymous users.
81 @ <a href="takeitprivate">Take it private</a>.<p>
 
 
 
 
82 }else if( !hasAnyCap(zAnonCap, "jrwy234567")
 
83 && (zPubPages==0 || zPubPages[0]==0) ){
84 @ <li><p>This repository is <big><b>Completely PRIVATE</b></big>.
85 @ A valid login and password is required to access any content.
86 }else{
87 @ <li><p>This repository is <big><b>Mostly PRIVATE</b></big>.
88 @ A valid login and password is usually required, however some
89 @ content can be accessed anonymously:
 
90 @ <ul>
91 if( hasAnyCap(zAnonCap,"j") ){
92 @ <li> Wiki pages
93 }
94 if( hasAnyCap(zAnonCap,"r") ){
95 @ <li> Tickets
96 }
97 if( hasAnyCap(zAnonCap,"234567") ){
98 @ <li> Forum posts
99 }
100 if( zPubPages && zPubPages[0] ){
101 Glob *pGlob = glob_create(zPubPages);
102 int i;
@@ -410,11 +439,11 @@
410 **
411 ** Disable anonymous access to this website
412 */
413 void takeitprivate_page(void){
414 login_check_credentials();
415 if( !g.perm.Setup && !g.perm.Admin ){
416 login_needed(0);
417 return;
418 }
419 if( P("cancel") ){
420 /* User pressed the cancel button. Go back */
@@ -424,10 +453,11 @@
424 db_multi_exec(
425 "UPDATE user SET cap=''"
426 " WHERE login IN ('nobody','anonymous');"
427 "DELETE FROM config WHERE name='public-pages';"
428 );
 
429 cgi_redirect("secaudit0");
430 }
431 style_header("Make This Website Private");
432 @ <p>Click the "Make It Private" button below to disable all
433 @ anonymous access to this repository. A valid login and password
@@ -458,11 +488,11 @@
458 void errorlog_page(void){
459 i64 szFile;
460 FILE *in;
461 char z[10000];
462 login_check_credentials();
463 if( !g.perm.Setup && !g.perm.Admin ){
464 login_needed(0);
465 return;
466 }
467 style_header("Server Error Log");
468 style_submenu_element("Test", "%R/test-warning");
469
--- src/security_audit.c
+++ src/security_audit.c
@@ -42,15 +42,16 @@
42 ** This page requires administrator access
43 */
44 void secaudit0_page(void){
45 const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
46 const char *zPubPages; /* GLOB pattern for public pages */
47 const char *zSelfCap; /* Capabilities of self-registered users */
48 char *z;
49 int n;
50
51 login_check_credentials();
52 if( !g.perm.Admin ){
53 login_needed(0);
54 return;
55 }
56 style_header("Security Audit");
57 @ <ol>
@@ -60,43 +61,71 @@
61 ** "Private" repos require (non-anonymous) login to access all content,
62 ** though some content may be accessible anonymously.
63 */
64 zAnonCap = db_text("", "SELECT fullcap(NULL)");
65 zPubPages = db_get("public-pages",0);
66 if( db_get_boolean("self-register",0) ){
67 CapabilityString *pCap;
68 pCap = capability_add(0, db_get("default-perms",""));
69 capability_expand(pCap);
70 zSelfCap = capability_string(pCap);
71 capability_free(pCap);
72 }else{
73 zSelfCap = fossil_strdup("");
74 }
75 if( hasAnyCap(zAnonCap,"as") ){
76 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
77 @ it grants administrator privileges to anonymous users. You
78 @ should <a href="takeitprivate">take this repository private</a>
79 @ immediately! Or, at least remove the Setup and Admin privileges
80 @ for users "anonymous" and "login" on the
81 @ <a href="setup_ulist">User Configuration</a> page.
82 }else if( hasAnyCap(zSelfCap,"as") ){
83 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
84 @ it grants administrator privileges to self-registered users. You
85 @ should <a href="takeitprivate">take this repository private</a>
86 @ and/or disable self-registration
87 @ immediately! Or, at least remove the Setup and Admin privileges
88 @ from the default permissions for new users.
89 }else if( hasAnyCap(zAnonCap,"y") ){
90 @ <li><p>This repository is <big><b>INSECURE</b></big> because
91 @ it allows anonymous users to push unversioned files.
92 @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
93 @ or by removing the "y" permission from users "anonymous" and
94 @ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
95 }else if( hasAnyCap(zSelfCap,"y") ){
96 @ <li><p>This repository is <big><b>INSECURE</b></big> because
97 @ it allows self-registered users to push unversioned files.
98 @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
99 @ or by removing the "y" permission from the default permissions or
100 @ by disabling self-registration.
101 }else if( hasAnyCap(zAnonCap,"goz") ){
102 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
103 @ checked-in content can be accessed by anonymous users.
104 @ <a href="takeitprivate">Take it private</a>.<p>
105 }else if( hasAnyCap(zSelfCap,"goz") ){
106 @ <li><p>This repository is <big><b>PUBLIC</b></big> because all
107 @ checked-in content can be accessed by self-registered users.
108 @ This repostory would be private if you disabled self-registration.</p>
109 }else if( !hasAnyCap(zAnonCap, "jrwy234567")
110 && !hasAnyCap(zSelfCap, "jrwy234567")
111 && (zPubPages==0 || zPubPages[0]==0) ){
112 @ <li><p>This repository is <big><b>Completely PRIVATE</b></big>.
113 @ A valid login and password is required to access any content.
114 }else{
115 @ <li><p>This repository is <big><b>Mostly PRIVATE</b></big>.
116 @ A valid login and password is usually required, however some
117 @ content can be accessed either anonymously or by self-registered
118 @ users:
119 @ <ul>
120 if( hasAnyCap(zAnonCap,"j") || hasAnyCap(zSelfCap,"j") ){
121 @ <li> Wiki pages
122 }
123 if( hasAnyCap(zAnonCap,"r") || hasAnyCap(zSelfCap,"r") ){
124 @ <li> Tickets
125 }
126 if( hasAnyCap(zAnonCap,"234567") || hasAnyCap(zSelfCap,"234567") ){
127 @ <li> Forum posts
128 }
129 if( zPubPages && zPubPages[0] ){
130 Glob *pGlob = glob_create(zPubPages);
131 int i;
@@ -410,11 +439,11 @@
439 **
440 ** Disable anonymous access to this website
441 */
442 void takeitprivate_page(void){
443 login_check_credentials();
444 if( !g.perm.Admin ){
445 login_needed(0);
446 return;
447 }
448 if( P("cancel") ){
449 /* User pressed the cancel button. Go back */
@@ -424,10 +453,11 @@
453 db_multi_exec(
454 "UPDATE user SET cap=''"
455 " WHERE login IN ('nobody','anonymous');"
456 "DELETE FROM config WHERE name='public-pages';"
457 );
458 db_set("self-register","0",0);
459 cgi_redirect("secaudit0");
460 }
461 style_header("Make This Website Private");
462 @ <p>Click the "Make It Private" button below to disable all
463 @ anonymous access to this repository. A valid login and password
@@ -458,11 +488,11 @@
488 void errorlog_page(void){
489 i64 szFile;
490 FILE *in;
491 char z[10000];
492 login_check_credentials();
493 if( !g.perm.Admin ){
494 login_needed(0);
495 return;
496 }
497 style_header("Server Error Log");
498 style_submenu_element("Test", "%R/test-warning");
499
+52 -36
--- src/setup.c
+++ src/setup.c
@@ -59,17 +59,21 @@
5959
6060
6161
/*
6262
** WEBPAGE: setup
6363
**
64
-** Main menu for the administrative pages. Requires Admin privileges.
64
+** Main menu for the administrative pages. Requires Admin or Setup
65
+** privileges. Links to sub-pages only usable by Setup users are
66
+** shown only to Setup users.
6567
*/
6668
void setup_page(void){
69
+ int setup_user = 0;
6770
login_check_credentials();
68
- if( !g.perm.Setup ){
71
+ if( !g.perm.Admin ){
6972
login_needed(0);
7073
}
74
+ setup_user = g.perm.Setup;
7175
7276
style_header("Server Administration");
7377
7478
/* Make sure the header contains <base href="...">. Issue a warning
7579
** if it does not. */
@@ -95,46 +99,56 @@
9599
#endif
96100
97101
@ <table border="0" cellspacing="3">
98102
setup_menu_entry("Users", "setup_ulist",
99103
"Grant privileges to individual users.");
100
- setup_menu_entry("Access", "setup_access",
101
- "Control access settings.");
102
- setup_menu_entry("Configuration", "setup_config",
103
- "Configure the WWW components of the repository");
104
+ if( setup_user ){
105
+ setup_menu_entry("Access", "setup_access",
106
+ "Control access settings.");
107
+ setup_menu_entry("Configuration", "setup_config",
108
+ "Configure the WWW components of the repository");
109
+ }
104110
setup_menu_entry("Security-Audit", "secaudit0",
105111
"Analyze the current configuration for security problems");
106
- setup_menu_entry("Settings", "setup_settings",
107
- "Web interface to the \"fossil settings\" command");
112
+ if( setup_user ){
113
+ setup_menu_entry("Settings", "setup_settings",
114
+ "Web interface to the \"fossil settings\" command");
115
+ }
108116
setup_menu_entry("Timeline", "setup_timeline",
109117
"Timeline display preferences");
110
- setup_menu_entry("Login-Group", "setup_login_group",
111
- "Manage single sign-on between this repository and others"
112
- " on the same server");
113
- setup_menu_entry("Tickets", "tktsetup",
114
- "Configure the trouble-ticketing system for this repository");
118
+ if( setup_user ){
119
+ setup_menu_entry("Login-Group", "setup_login_group",
120
+ "Manage single sign-on between this repository and others"
121
+ " on the same server");
122
+ setup_menu_entry("Tickets", "tktsetup",
123
+ "Configure the trouble-ticketing system for this repository");
124
+ }
115125
setup_menu_entry("Search","srchsetup",
116126
"Configure the built-in search engine");
117127
setup_menu_entry("URL Aliases", "waliassetup",
118128
"Configure URL aliases");
119
- setup_menu_entry("Notification", "setup_notification",
120
- "Automatic notifications of changes via outbound email");
121
- setup_menu_entry("Email-Server", "setup_smtp",
122
- "Activate and configure the built-in email server");
123
- setup_menu_entry("Transfers", "xfersetup",
124
- "Configure the transfer system for this repository");
129
+ if( setup_user ){
130
+ setup_menu_entry("Notification", "setup_notification",
131
+ "Automatic notifications of changes via outbound email");
132
+ setup_menu_entry("Email-Server", "setup_smtp",
133
+ "Activate and configure the built-in email server");
134
+ setup_menu_entry("Transfers", "xfersetup",
135
+ "Configure the transfer system for this repository");
136
+ }
125137
setup_menu_entry("Skins", "setup_skin",
126138
"Select and/or modify the web interface \"skins\"");
127139
setup_menu_entry("Moderation", "setup_modreq",
128140
"Enable/Disable requiring moderator approval of Wiki and/or Ticket"
129141
" changes and attachments.");
130142
setup_menu_entry("Ad-Unit", "setup_adunit",
131143
"Edit HTML text for an ad unit inserted after the menu bar");
132144
setup_menu_entry("URLs & Checkouts", "urllist",
133145
"Show URLs used to access this repo and known check-outs");
134
- setup_menu_entry("Web-Cache", "cachestat",
135
- "View the status of the expensive-page cache");
146
+ if( setup_user ){
147
+ setup_menu_entry("Web-Cache", "cachestat",
148
+ "View the status of the expensive-page cache");
149
+ }
136150
setup_menu_entry("Logo", "setup_logo",
137151
"Change the logo and background images for the server");
138152
setup_menu_entry("Shunned", "shun",
139153
"Show artifacts that are shunned by this repository");
140154
setup_menu_entry("Artifact Receipts Log", "rcvfromlist",
@@ -149,14 +163,16 @@
149163
"Show all unversioned files held");
150164
setup_menu_entry("Stats", "stat",
151165
"Repository Status Reports");
152166
setup_menu_entry("Sitemap", "sitemap",
153167
"Links to miscellaneous pages");
154
- setup_menu_entry("SQL", "admin_sql",
155
- "Enter raw SQL commands");
156
- setup_menu_entry("TH1", "admin_th1",
157
- "Enter raw TH1 commands");
168
+ if( setup_user ){
169
+ setup_menu_entry("SQL", "admin_sql",
170
+ "Enter raw SQL commands");
171
+ setup_menu_entry("TH1", "admin_th1",
172
+ "Enter raw TH1 commands");
173
+ }
158174
@ </table>
159175
160176
style_footer();
161177
}
162178
@@ -291,11 +307,11 @@
291307
292308
293309
/*
294310
** WEBPAGE: setup_access
295311
**
296
-** The access-control settings page. Requires Admin privileges.
312
+** The access-control settings page. Requires Setup privileges.
297313
*/
298314
void setup_access(void){
299315
login_check_credentials();
300316
if( !g.perm.Setup ){
301317
login_needed(0);
@@ -647,11 +663,11 @@
647663
"2", "YYYY-MM-DD HH:MM",
648664
"3", "YYMMDD HH:MM",
649665
"4", "(off)"
650666
};
651667
login_check_credentials();
652
- if( !g.perm.Setup ){
668
+ if( !g.perm.Admin ){
653669
login_needed(0);
654670
return;
655671
}
656672
657673
style_header("Timeline Display Preferences");
@@ -726,11 +742,11 @@
726742
727743
/*
728744
** WEBPAGE: setup_settings
729745
**
730746
** Change or view miscellaneous settings. Part of the
731
-** Admin pages requiring Admin privileges.
747
+** /setup pages requiring Setup privileges.
732748
*/
733749
void setup_settings(void){
734750
int nSetting;
735751
int i;
736752
Setting const *pSet;
@@ -813,11 +829,11 @@
813829
}
814830
815831
/*
816832
** WEBPAGE: setup_config
817833
**
818
-** The "Admin/Configuration" page. Requires Admin privilege.
834
+** The "Admin/Configuration" page. Requires Setup privilege.
819835
*/
820836
void setup_config(void){
821837
login_check_credentials();
822838
if( !g.perm.Setup ){
823839
login_needed(0);
@@ -935,11 +951,11 @@
935951
**
936952
** Admin page for setting up moderation of tickets and wiki.
937953
*/
938954
void setup_modreq(void){
939955
login_check_credentials();
940
- if( !g.perm.Setup ){
956
+ if( !g.perm.Admin ){
941957
login_needed(0);
942958
return;
943959
}
944960
945961
style_header("Moderator For Wiki And Tickets");
@@ -983,11 +999,11 @@
983999
** Administrative page for configuring and controlling ad units
9841000
** and how they are displayed.
9851001
*/
9861002
void setup_adunit(void){
9871003
login_check_credentials();
988
- if( !g.perm.Setup ){
1004
+ if( !g.perm.Admin ){
9891005
login_needed(0);
9901006
return;
9911007
}
9921008
db_begin_transaction();
9931009
if( P("clear")!=0 && cgi_csrf_safe(1) ){
@@ -1073,11 +1089,11 @@
10731089
}
10741090
if( szBgImg>0 ){
10751091
zBgMime = PD("bgim:mimetype","image/gif");
10761092
}
10771093
login_check_credentials();
1078
- if( !g.perm.Setup ){
1094
+ if( !g.perm.Admin ){
10791095
login_needed(0);
10801096
return;
10811097
}
10821098
db_begin_transaction();
10831099
if( !cgi_csrf_safe(1) ){
@@ -1214,11 +1230,11 @@
12141230
12151231
/*
12161232
** WEBPAGE: admin_sql
12171233
**
12181234
** Run raw SQL commands against the database file using the web interface.
1219
-** Requires Admin privileges.
1235
+** Requires Setup privileges.
12201236
*/
12211237
void sql_page(void){
12221238
const char *zQ;
12231239
int go = P("go")!=0;
12241240
login_check_credentials();
@@ -1405,11 +1421,11 @@
14051421
int limit; /* How many entries to show */
14061422
int ofst; /* Offset to the first entry */
14071423
int fLogEnabled;
14081424
int counter = 0;
14091425
login_check_credentials();
1410
- if( !g.perm.Setup && !g.perm.Admin ){
1426
+ if( !g.perm.Admin ){
14111427
login_needed(0);
14121428
return;
14131429
}
14141430
style_header("Admin Log");
14151431
create_admin_log_table();
@@ -1465,11 +1481,11 @@
14651481
**
14661482
** Configure the search engine. Requires Admin privilege.
14671483
*/
14681484
void page_srchsetup(){
14691485
login_check_credentials();
1470
- if( !g.perm.Setup && !g.perm.Admin ){
1486
+ if( !g.perm.Admin ){
14711487
login_needed(0);
14721488
return;
14731489
}
14741490
style_header("Search Configuration");
14751491
@ <form action="%s(g.zTop)/srchsetup" method="post"><div>
@@ -1589,11 +1605,11 @@
15891605
void page_waliassetup(){
15901606
Stmt q;
15911607
int cnt = 0;
15921608
Blob namelist;
15931609
login_check_credentials();
1594
- if( !g.perm.Setup && !g.perm.Admin ){
1610
+ if( !g.perm.Admin ){
15951611
login_needed(0);
15961612
return;
15971613
}
15981614
style_header("URL Alias Configuration");
15991615
if( P("submit")!=0 ){
16001616
--- src/setup.c
+++ src/setup.c
@@ -59,17 +59,21 @@
59
60
61 /*
62 ** WEBPAGE: setup
63 **
64 ** Main menu for the administrative pages. Requires Admin privileges.
 
 
65 */
66 void setup_page(void){
 
67 login_check_credentials();
68 if( !g.perm.Setup ){
69 login_needed(0);
70 }
 
71
72 style_header("Server Administration");
73
74 /* Make sure the header contains <base href="...">. Issue a warning
75 ** if it does not. */
@@ -95,46 +99,56 @@
95 #endif
96
97 @ <table border="0" cellspacing="3">
98 setup_menu_entry("Users", "setup_ulist",
99 "Grant privileges to individual users.");
100 setup_menu_entry("Access", "setup_access",
101 "Control access settings.");
102 setup_menu_entry("Configuration", "setup_config",
103 "Configure the WWW components of the repository");
 
 
104 setup_menu_entry("Security-Audit", "secaudit0",
105 "Analyze the current configuration for security problems");
106 setup_menu_entry("Settings", "setup_settings",
107 "Web interface to the \"fossil settings\" command");
 
 
108 setup_menu_entry("Timeline", "setup_timeline",
109 "Timeline display preferences");
110 setup_menu_entry("Login-Group", "setup_login_group",
111 "Manage single sign-on between this repository and others"
112 " on the same server");
113 setup_menu_entry("Tickets", "tktsetup",
114 "Configure the trouble-ticketing system for this repository");
 
 
115 setup_menu_entry("Search","srchsetup",
116 "Configure the built-in search engine");
117 setup_menu_entry("URL Aliases", "waliassetup",
118 "Configure URL aliases");
119 setup_menu_entry("Notification", "setup_notification",
120 "Automatic notifications of changes via outbound email");
121 setup_menu_entry("Email-Server", "setup_smtp",
122 "Activate and configure the built-in email server");
123 setup_menu_entry("Transfers", "xfersetup",
124 "Configure the transfer system for this repository");
 
 
125 setup_menu_entry("Skins", "setup_skin",
126 "Select and/or modify the web interface \"skins\"");
127 setup_menu_entry("Moderation", "setup_modreq",
128 "Enable/Disable requiring moderator approval of Wiki and/or Ticket"
129 " changes and attachments.");
130 setup_menu_entry("Ad-Unit", "setup_adunit",
131 "Edit HTML text for an ad unit inserted after the menu bar");
132 setup_menu_entry("URLs & Checkouts", "urllist",
133 "Show URLs used to access this repo and known check-outs");
134 setup_menu_entry("Web-Cache", "cachestat",
135 "View the status of the expensive-page cache");
 
 
136 setup_menu_entry("Logo", "setup_logo",
137 "Change the logo and background images for the server");
138 setup_menu_entry("Shunned", "shun",
139 "Show artifacts that are shunned by this repository");
140 setup_menu_entry("Artifact Receipts Log", "rcvfromlist",
@@ -149,14 +163,16 @@
149 "Show all unversioned files held");
150 setup_menu_entry("Stats", "stat",
151 "Repository Status Reports");
152 setup_menu_entry("Sitemap", "sitemap",
153 "Links to miscellaneous pages");
154 setup_menu_entry("SQL", "admin_sql",
155 "Enter raw SQL commands");
156 setup_menu_entry("TH1", "admin_th1",
157 "Enter raw TH1 commands");
 
 
158 @ </table>
159
160 style_footer();
161 }
162
@@ -291,11 +307,11 @@
291
292
293 /*
294 ** WEBPAGE: setup_access
295 **
296 ** The access-control settings page. Requires Admin privileges.
297 */
298 void setup_access(void){
299 login_check_credentials();
300 if( !g.perm.Setup ){
301 login_needed(0);
@@ -647,11 +663,11 @@
647 "2", "YYYY-MM-DD HH:MM",
648 "3", "YYMMDD HH:MM",
649 "4", "(off)"
650 };
651 login_check_credentials();
652 if( !g.perm.Setup ){
653 login_needed(0);
654 return;
655 }
656
657 style_header("Timeline Display Preferences");
@@ -726,11 +742,11 @@
726
727 /*
728 ** WEBPAGE: setup_settings
729 **
730 ** Change or view miscellaneous settings. Part of the
731 ** Admin pages requiring Admin privileges.
732 */
733 void setup_settings(void){
734 int nSetting;
735 int i;
736 Setting const *pSet;
@@ -813,11 +829,11 @@
813 }
814
815 /*
816 ** WEBPAGE: setup_config
817 **
818 ** The "Admin/Configuration" page. Requires Admin privilege.
819 */
820 void setup_config(void){
821 login_check_credentials();
822 if( !g.perm.Setup ){
823 login_needed(0);
@@ -935,11 +951,11 @@
935 **
936 ** Admin page for setting up moderation of tickets and wiki.
937 */
938 void setup_modreq(void){
939 login_check_credentials();
940 if( !g.perm.Setup ){
941 login_needed(0);
942 return;
943 }
944
945 style_header("Moderator For Wiki And Tickets");
@@ -983,11 +999,11 @@
983 ** Administrative page for configuring and controlling ad units
984 ** and how they are displayed.
985 */
986 void setup_adunit(void){
987 login_check_credentials();
988 if( !g.perm.Setup ){
989 login_needed(0);
990 return;
991 }
992 db_begin_transaction();
993 if( P("clear")!=0 && cgi_csrf_safe(1) ){
@@ -1073,11 +1089,11 @@
1073 }
1074 if( szBgImg>0 ){
1075 zBgMime = PD("bgim:mimetype","image/gif");
1076 }
1077 login_check_credentials();
1078 if( !g.perm.Setup ){
1079 login_needed(0);
1080 return;
1081 }
1082 db_begin_transaction();
1083 if( !cgi_csrf_safe(1) ){
@@ -1214,11 +1230,11 @@
1214
1215 /*
1216 ** WEBPAGE: admin_sql
1217 **
1218 ** Run raw SQL commands against the database file using the web interface.
1219 ** Requires Admin privileges.
1220 */
1221 void sql_page(void){
1222 const char *zQ;
1223 int go = P("go")!=0;
1224 login_check_credentials();
@@ -1405,11 +1421,11 @@
1405 int limit; /* How many entries to show */
1406 int ofst; /* Offset to the first entry */
1407 int fLogEnabled;
1408 int counter = 0;
1409 login_check_credentials();
1410 if( !g.perm.Setup && !g.perm.Admin ){
1411 login_needed(0);
1412 return;
1413 }
1414 style_header("Admin Log");
1415 create_admin_log_table();
@@ -1465,11 +1481,11 @@
1465 **
1466 ** Configure the search engine. Requires Admin privilege.
1467 */
1468 void page_srchsetup(){
1469 login_check_credentials();
1470 if( !g.perm.Setup && !g.perm.Admin ){
1471 login_needed(0);
1472 return;
1473 }
1474 style_header("Search Configuration");
1475 @ <form action="%s(g.zTop)/srchsetup" method="post"><div>
@@ -1589,11 +1605,11 @@
1589 void page_waliassetup(){
1590 Stmt q;
1591 int cnt = 0;
1592 Blob namelist;
1593 login_check_credentials();
1594 if( !g.perm.Setup && !g.perm.Admin ){
1595 login_needed(0);
1596 return;
1597 }
1598 style_header("URL Alias Configuration");
1599 if( P("submit")!=0 ){
1600
--- src/setup.c
+++ src/setup.c
@@ -59,17 +59,21 @@
59
60
61 /*
62 ** WEBPAGE: setup
63 **
64 ** Main menu for the administrative pages. Requires Admin or Setup
65 ** privileges. Links to sub-pages only usable by Setup users are
66 ** shown only to Setup users.
67 */
68 void setup_page(void){
69 int setup_user = 0;
70 login_check_credentials();
71 if( !g.perm.Admin ){
72 login_needed(0);
73 }
74 setup_user = g.perm.Setup;
75
76 style_header("Server Administration");
77
78 /* Make sure the header contains <base href="...">. Issue a warning
79 ** if it does not. */
@@ -95,46 +99,56 @@
99 #endif
100
101 @ <table border="0" cellspacing="3">
102 setup_menu_entry("Users", "setup_ulist",
103 "Grant privileges to individual users.");
104 if( setup_user ){
105 setup_menu_entry("Access", "setup_access",
106 "Control access settings.");
107 setup_menu_entry("Configuration", "setup_config",
108 "Configure the WWW components of the repository");
109 }
110 setup_menu_entry("Security-Audit", "secaudit0",
111 "Analyze the current configuration for security problems");
112 if( setup_user ){
113 setup_menu_entry("Settings", "setup_settings",
114 "Web interface to the \"fossil settings\" command");
115 }
116 setup_menu_entry("Timeline", "setup_timeline",
117 "Timeline display preferences");
118 if( setup_user ){
119 setup_menu_entry("Login-Group", "setup_login_group",
120 "Manage single sign-on between this repository and others"
121 " on the same server");
122 setup_menu_entry("Tickets", "tktsetup",
123 "Configure the trouble-ticketing system for this repository");
124 }
125 setup_menu_entry("Search","srchsetup",
126 "Configure the built-in search engine");
127 setup_menu_entry("URL Aliases", "waliassetup",
128 "Configure URL aliases");
129 if( setup_user ){
130 setup_menu_entry("Notification", "setup_notification",
131 "Automatic notifications of changes via outbound email");
132 setup_menu_entry("Email-Server", "setup_smtp",
133 "Activate and configure the built-in email server");
134 setup_menu_entry("Transfers", "xfersetup",
135 "Configure the transfer system for this repository");
136 }
137 setup_menu_entry("Skins", "setup_skin",
138 "Select and/or modify the web interface \"skins\"");
139 setup_menu_entry("Moderation", "setup_modreq",
140 "Enable/Disable requiring moderator approval of Wiki and/or Ticket"
141 " changes and attachments.");
142 setup_menu_entry("Ad-Unit", "setup_adunit",
143 "Edit HTML text for an ad unit inserted after the menu bar");
144 setup_menu_entry("URLs & Checkouts", "urllist",
145 "Show URLs used to access this repo and known check-outs");
146 if( setup_user ){
147 setup_menu_entry("Web-Cache", "cachestat",
148 "View the status of the expensive-page cache");
149 }
150 setup_menu_entry("Logo", "setup_logo",
151 "Change the logo and background images for the server");
152 setup_menu_entry("Shunned", "shun",
153 "Show artifacts that are shunned by this repository");
154 setup_menu_entry("Artifact Receipts Log", "rcvfromlist",
@@ -149,14 +163,16 @@
163 "Show all unversioned files held");
164 setup_menu_entry("Stats", "stat",
165 "Repository Status Reports");
166 setup_menu_entry("Sitemap", "sitemap",
167 "Links to miscellaneous pages");
168 if( setup_user ){
169 setup_menu_entry("SQL", "admin_sql",
170 "Enter raw SQL commands");
171 setup_menu_entry("TH1", "admin_th1",
172 "Enter raw TH1 commands");
173 }
174 @ </table>
175
176 style_footer();
177 }
178
@@ -291,11 +307,11 @@
307
308
309 /*
310 ** WEBPAGE: setup_access
311 **
312 ** The access-control settings page. Requires Setup privileges.
313 */
314 void setup_access(void){
315 login_check_credentials();
316 if( !g.perm.Setup ){
317 login_needed(0);
@@ -647,11 +663,11 @@
663 "2", "YYYY-MM-DD HH:MM",
664 "3", "YYMMDD HH:MM",
665 "4", "(off)"
666 };
667 login_check_credentials();
668 if( !g.perm.Admin ){
669 login_needed(0);
670 return;
671 }
672
673 style_header("Timeline Display Preferences");
@@ -726,11 +742,11 @@
742
743 /*
744 ** WEBPAGE: setup_settings
745 **
746 ** Change or view miscellaneous settings. Part of the
747 ** /setup pages requiring Setup privileges.
748 */
749 void setup_settings(void){
750 int nSetting;
751 int i;
752 Setting const *pSet;
@@ -813,11 +829,11 @@
829 }
830
831 /*
832 ** WEBPAGE: setup_config
833 **
834 ** The "Admin/Configuration" page. Requires Setup privilege.
835 */
836 void setup_config(void){
837 login_check_credentials();
838 if( !g.perm.Setup ){
839 login_needed(0);
@@ -935,11 +951,11 @@
951 **
952 ** Admin page for setting up moderation of tickets and wiki.
953 */
954 void setup_modreq(void){
955 login_check_credentials();
956 if( !g.perm.Admin ){
957 login_needed(0);
958 return;
959 }
960
961 style_header("Moderator For Wiki And Tickets");
@@ -983,11 +999,11 @@
999 ** Administrative page for configuring and controlling ad units
1000 ** and how they are displayed.
1001 */
1002 void setup_adunit(void){
1003 login_check_credentials();
1004 if( !g.perm.Admin ){
1005 login_needed(0);
1006 return;
1007 }
1008 db_begin_transaction();
1009 if( P("clear")!=0 && cgi_csrf_safe(1) ){
@@ -1073,11 +1089,11 @@
1089 }
1090 if( szBgImg>0 ){
1091 zBgMime = PD("bgim:mimetype","image/gif");
1092 }
1093 login_check_credentials();
1094 if( !g.perm.Admin ){
1095 login_needed(0);
1096 return;
1097 }
1098 db_begin_transaction();
1099 if( !cgi_csrf_safe(1) ){
@@ -1214,11 +1230,11 @@
1230
1231 /*
1232 ** WEBPAGE: admin_sql
1233 **
1234 ** Run raw SQL commands against the database file using the web interface.
1235 ** Requires Setup privileges.
1236 */
1237 void sql_page(void){
1238 const char *zQ;
1239 int go = P("go")!=0;
1240 login_check_credentials();
@@ -1405,11 +1421,11 @@
1421 int limit; /* How many entries to show */
1422 int ofst; /* Offset to the first entry */
1423 int fLogEnabled;
1424 int counter = 0;
1425 login_check_credentials();
1426 if( !g.perm.Admin ){
1427 login_needed(0);
1428 return;
1429 }
1430 style_header("Admin Log");
1431 create_admin_log_table();
@@ -1465,11 +1481,11 @@
1481 **
1482 ** Configure the search engine. Requires Admin privilege.
1483 */
1484 void page_srchsetup(){
1485 login_check_credentials();
1486 if( !g.perm.Admin ){
1487 login_needed(0);
1488 return;
1489 }
1490 style_header("Search Configuration");
1491 @ <form action="%s(g.zTop)/srchsetup" method="post"><div>
@@ -1589,11 +1605,11 @@
1605 void page_waliassetup(){
1606 Stmt q;
1607 int cnt = 0;
1608 Blob namelist;
1609 login_check_credentials();
1610 if( !g.perm.Admin ){
1611 login_needed(0);
1612 return;
1613 }
1614 style_header("URL Alias Configuration");
1615 if( P("submit")!=0 ){
1616
+12 -7
--- src/setupuser.c
+++ src/setupuser.c
@@ -42,15 +42,15 @@
4242
if( !g.perm.Admin ){
4343
login_needed(0);
4444
return;
4545
}
4646
47
+ style_submenu_element("Add", "setup_uedit");
48
+ style_submenu_element("Log", "access_log");
49
+ style_submenu_element("Help", "setup_ulist_notes");
50
+ style_header("User List");
4751
if( zWith==0 || zWith[0]==0 ){
48
- style_submenu_element("Add", "setup_uedit");
49
- style_submenu_element("Log", "access_log");
50
- style_submenu_element("Help", "setup_ulist_notes");
51
- style_header("User List");
5252
@ <table border=1 cellpadding=2 cellspacing=0 class='userTable'>
5353
@ <thead><tr>
5454
@ <th>Category
5555
@ <th>Capabilities (<a href='%R/setup_ucap_list'>key</a>)
5656
@ <th>Info <th>Last Change</tr></thead>
@@ -87,15 +87,20 @@
8787
@ <td>
8888
}
8989
@ </tr>
9090
}
9191
db_finalize(&s);
92
+ @ </tbody></table>
93
+ @ <div class='section'>Users</div>
9294
}else{
93
- style_header("Users With Capabilities \"%h\"", zWith);
95
+ style_submenu_element("All Users", "setup_ulist");
96
+ if( zWith[1]==0 ){
97
+ @ <div class='section'>Users with capability "%h(zWith)"</div>
98
+ }else{
99
+ @ <div class='section'>Users with any capability in "%h(zWith)"</div>
100
+ }
94101
}
95
- @ </tbody></table>
96
- @ <div class='section'>Users</div>
97102
@ <table border=1 cellpadding=2 cellspacing=0 class='userTable sortable' \
98103
@ data-column-types='ktxTTK' data-init-sort='2'>
99104
@ <thead><tr>
100105
@ <th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login</tr></thead>
101106
@ <tbody>
102107
--- src/setupuser.c
+++ src/setupuser.c
@@ -42,15 +42,15 @@
42 if( !g.perm.Admin ){
43 login_needed(0);
44 return;
45 }
46
 
 
 
 
47 if( zWith==0 || zWith[0]==0 ){
48 style_submenu_element("Add", "setup_uedit");
49 style_submenu_element("Log", "access_log");
50 style_submenu_element("Help", "setup_ulist_notes");
51 style_header("User List");
52 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable'>
53 @ <thead><tr>
54 @ <th>Category
55 @ <th>Capabilities (<a href='%R/setup_ucap_list'>key</a>)
56 @ <th>Info <th>Last Change</tr></thead>
@@ -87,15 +87,20 @@
87 @ <td>
88 }
89 @ </tr>
90 }
91 db_finalize(&s);
 
 
92 }else{
93 style_header("Users With Capabilities \"%h\"", zWith);
 
 
 
 
 
94 }
95 @ </tbody></table>
96 @ <div class='section'>Users</div>
97 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable sortable' \
98 @ data-column-types='ktxTTK' data-init-sort='2'>
99 @ <thead><tr>
100 @ <th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login</tr></thead>
101 @ <tbody>
102
--- src/setupuser.c
+++ src/setupuser.c
@@ -42,15 +42,15 @@
42 if( !g.perm.Admin ){
43 login_needed(0);
44 return;
45 }
46
47 style_submenu_element("Add", "setup_uedit");
48 style_submenu_element("Log", "access_log");
49 style_submenu_element("Help", "setup_ulist_notes");
50 style_header("User List");
51 if( zWith==0 || zWith[0]==0 ){
 
 
 
 
52 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable'>
53 @ <thead><tr>
54 @ <th>Category
55 @ <th>Capabilities (<a href='%R/setup_ucap_list'>key</a>)
56 @ <th>Info <th>Last Change</tr></thead>
@@ -87,15 +87,20 @@
87 @ <td>
88 }
89 @ </tr>
90 }
91 db_finalize(&s);
92 @ </tbody></table>
93 @ <div class='section'>Users</div>
94 }else{
95 style_submenu_element("All Users", "setup_ulist");
96 if( zWith[1]==0 ){
97 @ <div class='section'>Users with capability "%h(zWith)"</div>
98 }else{
99 @ <div class='section'>Users with any capability in "%h(zWith)"</div>
100 }
101 }
 
 
102 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable sortable' \
103 @ data-column-types='ktxTTK' data-init-sort='2'>
104 @ <thead><tr>
105 @ <th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login</tr></thead>
106 @ <tbody>
107
+373 -199
--- src/shell.c
+++ src/shell.c
@@ -1315,11 +1315,11 @@
13151315
** May you find forgiveness for yourself and forgive others.
13161316
** May you share freely, never taking more than you give.
13171317
**
13181318
******************************************************************************
13191319
**
1320
-** This SQLite extension implements a functions that compute SHA1 hashes.
1320
+** This SQLite extension implements functions that compute SHA3 hashes.
13211321
** Two SQL functions are implemented:
13221322
**
13231323
** sha3(X,SIZE)
13241324
** sha3_query(Y,SIZE)
13251325
**
@@ -2126,11 +2126,22 @@
21262126
#endif
21272127
#include <time.h>
21282128
#include <errno.h>
21292129
21302130
2131
+/*
2132
+** Structure of the fsdir() table-valued function
2133
+*/
2134
+ /* 0 1 2 3 4 5 */
21312135
#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
2136
+#define FSDIR_COLUMN_NAME 0 /* Name of the file */
2137
+#define FSDIR_COLUMN_MODE 1 /* Access mode */
2138
+#define FSDIR_COLUMN_MTIME 2 /* Last modification time */
2139
+#define FSDIR_COLUMN_DATA 3 /* File content */
2140
+#define FSDIR_COLUMN_PATH 4 /* Path to top of search */
2141
+#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
2142
+
21322143
21332144
/*
21342145
** Set the result stored by context ctx to a blob containing the
21352146
** contents of file zName.
21362147
*/
@@ -2715,24 +2726,24 @@
27152726
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
27162727
int i /* Which column to return */
27172728
){
27182729
fsdir_cursor *pCur = (fsdir_cursor*)cur;
27192730
switch( i ){
2720
- case 0: { /* name */
2731
+ case FSDIR_COLUMN_NAME: {
27212732
sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
27222733
break;
27232734
}
27242735
2725
- case 1: /* mode */
2736
+ case FSDIR_COLUMN_MODE:
27262737
sqlite3_result_int64(ctx, pCur->sStat.st_mode);
27272738
break;
27282739
2729
- case 2: /* mtime */
2740
+ case FSDIR_COLUMN_MTIME:
27302741
sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
27312742
break;
27322743
2733
- case 3: { /* data */
2744
+ case FSDIR_COLUMN_DATA: {
27342745
mode_t m = pCur->sStat.st_mode;
27352746
if( S_ISDIR(m) ){
27362747
sqlite3_result_null(ctx);
27372748
#if !defined(_WIN32) && !defined(WIN32)
27382749
}else if( S_ISLNK(m) ){
@@ -2758,10 +2769,16 @@
27582769
#endif
27592770
}else{
27602771
readFileContents(ctx, pCur->zPath);
27612772
}
27622773
}
2774
+ case FSDIR_COLUMN_PATH:
2775
+ default: {
2776
+ /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
2777
+ ** always return their values as NULL */
2778
+ break;
2779
+ }
27632780
}
27642781
return SQLITE_OK;
27652782
}
27662783
27672784
/*
@@ -2784,10 +2801,13 @@
27842801
return (pCur->zPath==0);
27852802
}
27862803
27872804
/*
27882805
** xFilter callback.
2806
+**
2807
+** idxNum==1 PATH parameter only
2808
+** idxNum==2 Both PATH and DIR supplied
27892809
*/
27902810
static int fsdirFilter(
27912811
sqlite3_vtab_cursor *cur,
27922812
int idxNum, const char *idxStr,
27932813
int argc, sqlite3_value **argv
@@ -2836,44 +2856,67 @@
28362856
** plan.
28372857
**
28382858
** In this implementation idxNum is used to represent the
28392859
** query plan. idxStr is unused.
28402860
**
2841
-** The query plan is represented by bits in idxNum:
2861
+** The query plan is represented by values of idxNum:
28422862
**
2843
-** (1) start = $value -- constraint exists
2844
-** (2) stop = $value -- constraint exists
2845
-** (4) step = $value -- constraint exists
2846
-** (8) output in descending order
2863
+** (1) The path value is supplied by argv[0]
2864
+** (2) Path is in argv[0] and dir is in argv[1]
28472865
*/
28482866
static int fsdirBestIndex(
28492867
sqlite3_vtab *tab,
28502868
sqlite3_index_info *pIdxInfo
28512869
){
28522870
int i; /* Loop over constraints */
2853
- int idx4 = -1;
2854
- int idx5 = -1;
2871
+ int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
2872
+ int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
2873
+ int seenPath = 0; /* True if an unusable PATH= constraint is seen */
2874
+ int seenDir = 0; /* True if an unusable DIR= constraint is seen */
28552875
const struct sqlite3_index_constraint *pConstraint;
28562876
28572877
(void)tab;
28582878
pConstraint = pIdxInfo->aConstraint;
28592879
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
2860
- if( pConstraint->usable==0 ) continue;
28612880
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
2862
- if( pConstraint->iColumn==4 ) idx4 = i;
2863
- if( pConstraint->iColumn==5 ) idx5 = i;
2881
+ switch( pConstraint->iColumn ){
2882
+ case FSDIR_COLUMN_PATH: {
2883
+ if( pConstraint->usable ){
2884
+ idxPath = i;
2885
+ seenPath = 0;
2886
+ }else if( idxPath<0 ){
2887
+ seenPath = 1;
2888
+ }
2889
+ break;
2890
+ }
2891
+ case FSDIR_COLUMN_DIR: {
2892
+ if( pConstraint->usable ){
2893
+ idxDir = i;
2894
+ seenDir = 0;
2895
+ }else if( idxDir<0 ){
2896
+ seenDir = 1;
2897
+ }
2898
+ break;
2899
+ }
2900
+ }
2901
+ }
2902
+ if( seenPath || seenDir ){
2903
+ /* If input parameters are unusable, disallow this plan */
2904
+ return SQLITE_CONSTRAINT;
28642905
}
28652906
2866
- if( idx4<0 ){
2907
+ if( idxPath<0 ){
28672908
pIdxInfo->idxNum = 0;
2868
- pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
2909
+ /* The pIdxInfo->estimatedCost should have been initialized to a huge
2910
+ ** number. Leave it unchanged. */
2911
+ pIdxInfo->estimatedRows = 0x7fffffff;
28692912
}else{
2870
- pIdxInfo->aConstraintUsage[idx4].omit = 1;
2871
- pIdxInfo->aConstraintUsage[idx4].argvIndex = 1;
2872
- if( idx5>=0 ){
2873
- pIdxInfo->aConstraintUsage[idx5].omit = 1;
2874
- pIdxInfo->aConstraintUsage[idx5].argvIndex = 2;
2913
+ pIdxInfo->aConstraintUsage[idxPath].omit = 1;
2914
+ pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
2915
+ if( idxDir>=0 ){
2916
+ pIdxInfo->aConstraintUsage[idxDir].omit = 1;
2917
+ pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
28752918
pIdxInfo->idxNum = 2;
28762919
pIdxInfo->estimatedCost = 10.0;
28772920
}else{
28782921
pIdxInfo->idxNum = 1;
28792922
pIdxInfo->estimatedCost = 100.0;
@@ -2908,11 +2951,12 @@
29082951
0, /* xRollback */
29092952
0, /* xFindMethod */
29102953
0, /* xRename */
29112954
0, /* xSavepoint */
29122955
0, /* xRelease */
2913
- 0 /* xRollbackTo */
2956
+ 0, /* xRollbackTo */
2957
+ 0, /* xShadowName */
29142958
};
29152959
29162960
int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
29172961
return rc;
29182962
}
@@ -3416,11 +3460,12 @@
34163460
0, /* xRollback */
34173461
0, /* xFindMethod */
34183462
0, /* xRename */
34193463
0, /* xSavepoint */
34203464
0, /* xRelease */
3421
- 0 /* xRollbackTo */
3465
+ 0, /* xRollbackTo */
3466
+ 0 /* xShadowName */
34223467
};
34233468
34243469
#endif /* SQLITE_OMIT_VIRTUALTABLE */
34253470
34263471
int sqlite3CompletionVtabInit(sqlite3 *db){
@@ -5313,29 +5358,30 @@
53135358
static int zipfileBestIndex(
53145359
sqlite3_vtab *tab,
53155360
sqlite3_index_info *pIdxInfo
53165361
){
53175362
int i;
5363
+ int idx = -1;
5364
+ int unusable = 0;
53185365
53195366
for(i=0; i<pIdxInfo->nConstraint; i++){
53205367
const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
5321
- if( pCons->usable==0 ) continue;
5322
- if( pCons->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
53235368
if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
5324
- break;
5369
+ if( pCons->usable==0 ){
5370
+ unusable = 1;
5371
+ }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
5372
+ idx = i;
5373
+ }
53255374
}
5326
-
5327
- if( i<pIdxInfo->nConstraint ){
5328
- pIdxInfo->aConstraintUsage[i].argvIndex = 1;
5329
- pIdxInfo->aConstraintUsage[i].omit = 1;
5375
+ if( idx>=0 ){
5376
+ pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
5377
+ pIdxInfo->aConstraintUsage[idx].omit = 1;
53305378
pIdxInfo->estimatedCost = 1000.0;
53315379
pIdxInfo->idxNum = 1;
5332
- }else{
5333
- pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
5334
- pIdxInfo->idxNum = 0;
5380
+ }else if( unusable ){
5381
+ return SQLITE_CONSTRAINT;
53355382
}
5336
-
53375383
return SQLITE_OK;
53385384
}
53395385
53405386
static ZipfileEntry *zipfileNewEntry(const char *zPath){
53415387
ZipfileEntry *pNew;
@@ -7134,10 +7180,11 @@
71347180
0, /* xFindFunction - function overloading */
71357181
0, /* xRename - rename the table */
71367182
0, /* xSavepoint */
71377183
0, /* xRelease */
71387184
0, /* xRollbackTo */
7185
+ 0, /* xShadowName */
71397186
};
71407187
71417188
return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
71427189
}
71437190
/*
@@ -8558,15 +8605,16 @@
85588605
#define AUTOEQP_trigger 2 /* On and also show plans for triggers */
85598606
#define AUTOEQP_full 3 /* Show full EXPLAIN */
85608607
85618608
/* Allowed values for ShellState.openMode
85628609
*/
8563
-#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
8564
-#define SHELL_OPEN_NORMAL 1 /* Normal database file */
8565
-#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
8566
-#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
8567
-#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
8610
+#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
8611
+#define SHELL_OPEN_NORMAL 1 /* Normal database file */
8612
+#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
8613
+#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
8614
+#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
8615
+#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
85688616
85698617
/*
85708618
** These are the allowed shellFlgs values
85718619
*/
85728620
#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
@@ -8772,11 +8820,11 @@
87728820
goto edit_func_end;
87738821
}
87748822
if( bBin ){
87758823
sqlite3_result_blob64(context, p, sz, sqlite3_free);
87768824
}else{
8777
- int i, j;
8825
+ sqlite3_int64 i, j;
87788826
if( hasCRNL ){
87798827
/* If the original contains \r\n then do no conversions back to \n */
87808828
j = sz;
87818829
}else{
87828830
/* If the file did not originally contain \r\n then convert any new
@@ -10834,141 +10882,242 @@
1083410882
}
1083510883
return rc;
1083610884
}
1083710885
1083810886
/*
10839
-** Text of a help message
10887
+** Text of help messages.
10888
+**
10889
+** The help text for each individual command begins with a line that starts
10890
+** with ".". Subsequent lines are supplimental information.
10891
+**
10892
+** There must be two or more spaces between the end of the command and the
10893
+** start of the description of what that command does.
1084010894
*/
10841
-static char zHelp[] =
10895
+static const char *(azHelp[]) = {
1084210896
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
10843
- ".archive ... Manage SQL archives: \".archive --help\" for details\n"
10897
+ ".archive ... Manage SQL archives",
10898
+ " Each command must have exactly one of the following options:",
10899
+ " -c, --create Create a new archive",
10900
+ " -u, --update Update or add files to an existing archive",
10901
+ " -t, --list List contents of archive",
10902
+ " -x, --extract Extract files from archive",
10903
+ " Optional arguments:",
10904
+ " -v, --verbose Print each filename as it is processed",
10905
+ " -f FILE, --file FILE Operate on archive FILE (default is current db)",
10906
+ " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS",
10907
+ " -C DIR, --directory DIR Change to directory DIR to read/extract files",
10908
+ " -n, --dryrun Show the SQL that would have occurred",
10909
+ " Examples:",
10910
+ " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar",
10911
+ " .ar -tf archive.sar # List members of archive.sar",
10912
+ " .ar -xvf archive.sar # Verbosely extract files from archive.sar",
10913
+ " See also:",
10914
+ " http://sqlite.org/cli.html#sqlar_archive_support",
1084410915
#endif
1084510916
#ifndef SQLITE_OMIT_AUTHORIZATION
10846
- ".auth ON|OFF Show authorizer callbacks\n"
10917
+ ".auth ON|OFF Show authorizer callbacks",
1084710918
#endif
10848
- ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
10849
- " Add \"--append\" to open using appendvfs.\n"
10850
- ".bail on|off Stop after hitting an error. Default OFF\n"
10851
- ".binary on|off Turn binary output on or off. Default OFF\n"
10852
- ".cd DIRECTORY Change the working directory to DIRECTORY\n"
10853
- ".changes on|off Show number of rows changed by SQL\n"
10854
- ".check GLOB Fail if output since .testcase does not match\n"
10855
- ".clone NEWDB Clone data into NEWDB from the existing database\n"
10856
- ".databases List names and files of attached databases\n"
10857
- ".dbconfig ?op? ?val? List or change sqlite3_db_config() options\n"
10858
- ".dbinfo ?DB? Show status information about the database\n"
10859
- ".dump ?TABLE? ... Dump the database in an SQL text format\n"
10860
- " If TABLE specified, only dump tables matching\n"
10861
- " LIKE pattern TABLE.\n"
10862
- ".echo on|off Turn command echo on or off\n"
10863
- ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
10864
- ".excel Display the output of next command in a spreadsheet\n"
10865
- ".exit Exit this program\n"
10866
- ".expert EXPERIMENTAL. Suggest indexes for specified queries\n"
10919
+ ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
10920
+ " --append Use the appendvfs",
10921
+ ".bail on|off Stop after hitting an error. Default OFF",
10922
+ ".binary on|off Turn binary output on or off. Default OFF",
10923
+ ".cd DIRECTORY Change the working directory to DIRECTORY",
10924
+ ".changes on|off Show number of rows changed by SQL",
10925
+ ".check GLOB Fail if output since .testcase does not match",
10926
+ ".clone NEWDB Clone data into NEWDB from the existing database",
10927
+ ".databases List names and files of attached databases",
10928
+ ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
10929
+ ".dbinfo ?DB? Show status information about the database",
10930
+ ".dump ?TABLE? ... Render all database content as SQL",
10931
+ " Options:",
10932
+ " --preserve-rowids Include ROWID values in the output",
10933
+ " --newlines Allow unescaped newline characters in output",
10934
+ " TABLE is LIKE pattern for the tables to dump",
10935
+ ".echo on|off Turn command echo on or off",
10936
+ ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN",
10937
+ ".excel Display the output of next command in a spreadsheet",
10938
+ ".exit ?CODE? Exit this program with return-code CODE",
10939
+ ".expert EXPERIMENTAL. Suggest indexes for specified queries",
1086710940
/* Because explain mode comes on automatically now, the ".explain" mode
1086810941
** is removed from the help screen. It is still supported for legacy, however */
10869
-/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/
10870
- ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
10871
- ".headers on|off Turn display of headers on or off\n"
10872
- ".help Show this message\n"
10873
- ".import FILE TABLE Import data from FILE into TABLE\n"
10874
-#ifndef SQLITE_OMIT_TEST_CONTROL
10875
- ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
10876
-#endif
10877
- ".indexes ?TABLE? Show names of all indexes\n"
10878
- " If TABLE specified, only show indexes for tables\n"
10879
- " matching LIKE pattern TABLE.\n"
10880
-#ifdef SQLITE_ENABLE_IOTRACE
10881
- ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
10882
-#endif
10883
- ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
10884
- ".lint OPTIONS Report potential schema issues. Options:\n"
10885
- " fkey-indexes Find missing foreign key indexes\n"
10886
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
10887
- ".load FILE ?ENTRY? Load an extension library\n"
10888
-#endif
10889
- ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
10890
- ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
10891
- " ascii Columns/rows delimited by 0x1F and 0x1E\n"
10892
- " csv Comma-separated values\n"
10893
- " column Left-aligned columns. (See .width)\n"
10894
- " html HTML <table> code\n"
10895
- " insert SQL insert statements for TABLE\n"
10896
- " line One value per line\n"
10897
- " list Values delimited by \"|\"\n"
10898
- " quote Escape answers as for SQL\n"
10899
- " tabs Tab-separated values\n"
10900
- " tcl TCL list elements\n"
10901
- ".nullvalue STRING Use STRING in place of NULL values\n"
10902
- ".once (-e|-x|FILE) Output for the next SQL command only to FILE\n"
10903
- " or invoke system text editor (-e) or spreadsheet (-x)\n"
10904
- " on the output.\n"
10905
- ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
10906
- " The --new option starts with an empty file\n"
10907
- " Other options: --readonly --append --zip\n"
10908
- ".output ?FILE? Send output to FILE or stdout\n"
10909
- ".print STRING... Print literal STRING\n"
10910
- ".prompt MAIN CONTINUE Replace the standard prompts\n"
10911
- ".quit Exit this program\n"
10912
- ".read FILENAME Execute SQL in FILENAME\n"
10913
- ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
10914
- ".save FILE Write in-memory database into FILE\n"
10915
- ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
10916
- ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
10917
- " Add --indent for pretty-printing\n"
10918
- ".selftest ?--init? Run tests defined in the SELFTEST table\n"
10919
- ".separator COL ?ROW? Change the column separator and optionally the row\n"
10920
- " separator for both the output mode and .import\n"
10921
-#if defined(SQLITE_ENABLE_SESSION)
10922
- ".session CMD ... Create or control sessions\n"
10923
-#endif
10924
- ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n"
10925
-#ifndef SQLITE_NOHAVE_SYSTEM
10926
- ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
10927
-#endif
10928
- ".show Show the current values for various settings\n"
10929
- ".stats ?on|off? Show stats or turn stats on or off\n"
10930
-#ifndef SQLITE_NOHAVE_SYSTEM
10931
- ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
10932
-#endif
10933
- ".tables ?TABLE? List names of tables\n"
10934
- " If TABLE specified, only list tables matching\n"
10935
- " LIKE pattern TABLE.\n"
10936
- ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
10937
- ".timeout MS Try opening locked tables for MS milliseconds\n"
10938
- ".timer on|off Turn SQL timer on or off\n"
10939
- ".trace FILE|off Output each SQL statement as it is run\n"
10940
- ".vfsinfo ?AUX? Information about the top-level VFS\n"
10941
- ".vfslist List all available VFSes\n"
10942
- ".vfsname ?AUX? Print the name of the VFS stack\n"
10943
- ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
10944
- " Negative values right-justify\n"
10945
-;
10946
-
10947
-#if defined(SQLITE_ENABLE_SESSION)
10948
-/*
10949
-** Print help information for the ".sessions" command
10950
-*/
10951
-void session_help(ShellState *p){
10952
- raw_printf(p->out,
10953
- ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
10954
- "If ?NAME? is omitted, the first defined session is used.\n"
10955
- "Subcommands:\n"
10956
- " attach TABLE Attach TABLE\n"
10957
- " changeset FILE Write a changeset into FILE\n"
10958
- " close Close one session\n"
10959
- " enable ?BOOLEAN? Set or query the enable bit\n"
10960
- " filter GLOB... Reject tables matching GLOBs\n"
10961
- " indirect ?BOOLEAN? Mark or query the indirect status\n"
10962
- " isempty Query whether the session is empty\n"
10963
- " list List currently open session names\n"
10964
- " open DB NAME Open a new session on DB\n"
10965
- " patchset FILE Write a patchset into FILE\n"
10966
- );
10967
-}
10968
-#endif
10969
-
10942
+/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/
10943
+ ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
10944
+ ".headers on|off Turn display of headers on or off",
10945
+ ".help ?-all? ?PATTERN? Show help text for PATTERN",
10946
+ ".import FILE TABLE Import data from FILE into TABLE",
10947
+#ifndef SQLITE_OMIT_TEST_CONTROL
10948
+ ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
10949
+#endif
10950
+ ".indexes ?TABLE? Show names of indexes",
10951
+ " If TABLE is specified, only show indexes for",
10952
+ " tables matching TABLE using the LIKE operator.",
10953
+#ifdef SQLITE_ENABLE_IOTRACE
10954
+ ".iotrace FILE Enable I/O diagnostic logging to FILE",
10955
+#endif
10956
+ ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
10957
+ ".lint OPTIONS Report potential schema issues.",
10958
+ " Options:",
10959
+ " fkey-indexes Find missing foreign key indexes",
10960
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
10961
+ ".load FILE ?ENTRY? Load an extension library",
10962
+#endif
10963
+ ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
10964
+ ".mode MODE ?TABLE? Set output mode",
10965
+ " MODE is one of:",
10966
+ " ascii Columns/rows delimited by 0x1F and 0x1E",
10967
+ " csv Comma-separated values",
10968
+ " column Left-aligned columns. (See .width)",
10969
+ " html HTML <table> code",
10970
+ " insert SQL insert statements for TABLE",
10971
+ " line One value per line",
10972
+ " list Values delimited by \"|\"",
10973
+ " quote Escape answers as for SQL",
10974
+ " tabs Tab-separated values",
10975
+ " tcl TCL list elements",
10976
+ ".nullvalue STRING Use STRING in place of NULL values",
10977
+ ".once (-e|-x|FILE) Output for the next SQL command only to FILE",
10978
+ " If FILE begins with '|' then open as a pipe",
10979
+ " Other options:",
10980
+ " -e Invoke system text editor",
10981
+ " -x Open in a spreadsheet",
10982
+ ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
10983
+ " Options:",
10984
+ " --append Use appendvfs to append database to the end of FILE",
10985
+#ifdef SQLITE_ENABLE_DESERIALIZE
10986
+ " --deserialize Load into memory useing sqlite3_deserialize()",
10987
+#endif
10988
+ " --new Initialize FILE to an empty database",
10989
+ " --readonly Open FILE readonly",
10990
+ " --zip FILE is a ZIP archive",
10991
+ ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
10992
+ " If FILE begins with '|' then open it as a pipe.",
10993
+ ".print STRING... Print literal STRING",
10994
+ ".prompt MAIN CONTINUE Replace the standard prompts",
10995
+ ".quit Exit this program",
10996
+ ".read FILE Read input from FILE",
10997
+ ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
10998
+ ".save FILE Write in-memory database into FILE",
10999
+ ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
11000
+ ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
11001
+ " Options:",
11002
+ " --indent Try to pretty-print the schema",
11003
+ ".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
11004
+ " Options:",
11005
+ " --init Create a new SELFTEST table",
11006
+ " -v Verbose output",
11007
+ ".separator COL ?ROW? Change the column and row separators",
11008
+#if defined(SQLITE_ENABLE_SESSION)
11009
+ ".session ?NAME? CMD ... Create or control sessions",
11010
+ " Subcommands:",
11011
+ " attach TABLE Attach TABLE",
11012
+ " changeset FILE Write a changeset into FILE",
11013
+ " close Close one session",
11014
+ " enable ?BOOLEAN? Set or query the enable bit",
11015
+ " filter GLOB... Reject tables matching GLOBs",
11016
+ " indirect ?BOOLEAN? Mark or query the indirect status",
11017
+ " isempty Query whether the session is empty",
11018
+ " list List currently open session names",
11019
+ " open DB NAME Open a new session on DB",
11020
+ " patchset FILE Write a patchset into FILE",
11021
+ " If ?NAME? is omitted, the first defined session is used.",
11022
+#endif
11023
+ ".sha3sum ... Compute a SHA3 hash of database content",
11024
+ " Options:",
11025
+ " --schema Also hash the sqlite_master table",
11026
+ " --sha3-224 Use the sha3-224 algorithm",
11027
+ " --sha3-256 Use the sha3-256 algorithm. This is the default.",
11028
+ " --sha3-384 Use the sha3-384 algorithm",
11029
+ " --sha3-512 Use the sha3-512 algorithm",
11030
+ " Any other argument is a LIKE pattern for tables to hash",
11031
+#ifndef SQLITE_NOHAVE_SYSTEM
11032
+ ".shell CMD ARGS... Run CMD ARGS... in a system shell",
11033
+#endif
11034
+ ".show Show the current values for various settings",
11035
+ ".stats ?on|off? Show stats or turn stats on or off",
11036
+#ifndef SQLITE_NOHAVE_SYSTEM
11037
+ ".system CMD ARGS... Run CMD ARGS... in a system shell",
11038
+#endif
11039
+ ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
11040
+ ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
11041
+ ".timeout MS Try opening locked tables for MS milliseconds",
11042
+ ".timer on|off Turn SQL timer on or off",
11043
+ ".trace FILE|off Output each SQL statement as it is run",
11044
+ ".vfsinfo ?AUX? Information about the top-level VFS",
11045
+ ".vfslist List all available VFSes",
11046
+ ".vfsname ?AUX? Print the name of the VFS stack",
11047
+ ".width NUM1 NUM2 ... Set column widths for \"column\" mode",
11048
+ " Negative values right-justify",
11049
+};
11050
+
11051
+/*
11052
+** Output help text.
11053
+**
11054
+** zPattern describes the set of commands for which help text is provided.
11055
+** If zPattern is NULL, then show all commands, but only give a one-line
11056
+** description of each.
11057
+**
11058
+** Return the number of matches.
11059
+*/
11060
+static int showHelp(FILE *out, const char *zPattern){
11061
+ int i = 0;
11062
+ int j = 0;
11063
+ int n = 0;
11064
+ char *zPat;
11065
+ if( zPattern==0
11066
+ || zPattern[0]=='0'
11067
+ || strcmp(zPattern,"-a")==0
11068
+ || strcmp(zPattern,"-all")==0
11069
+ ){
11070
+ /* Show all commands, but only one line per command */
11071
+ if( zPattern==0 ) zPattern = "";
11072
+ for(i=0; i<ArraySize(azHelp); i++){
11073
+ if( azHelp[i][0]=='.' || zPattern[0] ){
11074
+ utf8_printf(out, "%s\n", azHelp[i]);
11075
+ n++;
11076
+ }
11077
+ }
11078
+ }else{
11079
+ /* Look for commands that for which zPattern is an exact prefix */
11080
+ zPat = sqlite3_mprintf(".%s*", zPattern);
11081
+ for(i=0; i<ArraySize(azHelp); i++){
11082
+ if( sqlite3_strglob(zPat, azHelp[i])==0 ){
11083
+ utf8_printf(out, "%s\n", azHelp[i]);
11084
+ j = i+1;
11085
+ n++;
11086
+ }
11087
+ }
11088
+ sqlite3_free(zPat);
11089
+ if( n ){
11090
+ if( n==1 ){
11091
+ /* when zPattern is a prefix of exactly one command, then include the
11092
+ ** details of that command, which should begin at offset j */
11093
+ while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
11094
+ utf8_printf(out, "%s\n", azHelp[j]);
11095
+ j++;
11096
+ }
11097
+ }
11098
+ return n;
11099
+ }
11100
+ /* Look for commands that contain zPattern anywhere. Show the complete
11101
+ ** text of all commands that match. */
11102
+ zPat = sqlite3_mprintf("%%%s%%", zPattern);
11103
+ for(i=0; i<ArraySize(azHelp); i++){
11104
+ if( azHelp[i][0]=='.' ) j = i;
11105
+ if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
11106
+ utf8_printf(out, "%s\n", azHelp[j]);
11107
+ while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
11108
+ j++;
11109
+ utf8_printf(out, "%s\n", azHelp[j]);
11110
+ }
11111
+ i = j;
11112
+ n++;
11113
+ }
11114
+ }
11115
+ sqlite3_free(zPat);
11116
+ }
11117
+ return n;
11118
+}
1097011119
1097111120
/* Forward reference */
1097211121
static int process_input(ShellState *p, FILE *in);
1097311122
1097411123
/*
@@ -10994,11 +11143,11 @@
1099411143
if( in==0 ) return 0;
1099511144
fseek(in, 0, SEEK_END);
1099611145
nIn = ftell(in);
1099711146
rewind(in);
1099811147
pBuf = sqlite3_malloc64( nIn+1 );
10999
- if( pBuf==0 ) return 0;
11148
+ if( pBuf==0 ){ fclose(in); return 0; }
1100011149
nRead = fread(pBuf, nIn, 1, in);
1100111150
fclose(in);
1100211151
if( nRead!=1 ){
1100311152
sqlite3_free(pBuf);
1100411153
return 0;
@@ -11074,10 +11223,15 @@
1107411223
return SHELL_OPEN_ZIPFILE;
1107511224
}else{
1107611225
return SHELL_OPEN_NORMAL;
1107711226
}
1107811227
}
11228
+ n = fread(zBuf, 16, 1, f);
11229
+ if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
11230
+ fclose(f);
11231
+ return SHELL_OPEN_NORMAL;
11232
+ }
1107911233
fseek(f, -25, SEEK_END);
1108011234
n = fread(zBuf, 25, 1, f);
1108111235
if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
1108211236
rc = SHELL_OPEN_APPENDVFS;
1108311237
}else{
@@ -11124,10 +11278,14 @@
1112411278
switch( p->openMode ){
1112511279
case SHELL_OPEN_APPENDVFS: {
1112611280
sqlite3_open_v2(p->zDbFilename, &p->db,
1112711281
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
1112811282
break;
11283
+ }
11284
+ case SHELL_OPEN_DESERIALIZE: {
11285
+ sqlite3_open(0, &p->db);
11286
+ break;
1112911287
}
1113011288
case SHELL_OPEN_ZIPFILE: {
1113111289
sqlite3_open(":memory:", &p->db);
1113211290
break;
1113311291
}
@@ -11174,10 +11332,22 @@
1117411332
char *zSql = sqlite3_mprintf(
1117511333
"CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
1117611334
sqlite3_exec(p->db, zSql, 0, 0, 0);
1117711335
sqlite3_free(zSql);
1117811336
}
11337
+#ifdef SQLITE_ENABLE_DESERIALIZE
11338
+ else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
11339
+ int nData = 0;
11340
+ unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
11341
+ int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
11342
+ SQLITE_DESERIALIZE_RESIZEABLE |
11343
+ SQLITE_DESERIALIZE_FREEONCLOSE);
11344
+ if( rc ){
11345
+ utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
11346
+ }
11347
+ }
11348
+#endif
1117911349
}
1118011350
}
1118111351
1118211352
/*
1118311353
** Attempt to close the databaes connection. Report errors.
@@ -12378,10 +12548,11 @@
1237812548
if( *pRc==SQLITE_OK ){
1237912549
va_list ap;
1238012550
char *z;
1238112551
va_start(ap, zFmt);
1238212552
z = sqlite3_vmprintf(zFmt, ap);
12553
+ va_end(ap);
1238312554
if( z==0 ){
1238412555
*pRc = SQLITE_NOMEM;
1238512556
}else{
1238612557
shellPrepare(db, pRc, z, ppStmt);
1238712558
sqlite3_free(z);
@@ -12440,36 +12611,11 @@
1244012611
1244112612
/*
1244212613
** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
1244312614
*/
1244412615
static int arUsage(FILE *f){
12445
- raw_printf(f,
12446
-"\n"
12447
-"Usage: .ar [OPTION...] [FILE...]\n"
12448
-"The .ar command manages sqlar archives.\n"
12449
-"\n"
12450
-"Examples:\n"
12451
-" .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar\n"
12452
-" .ar -tf archive.sar # List members of archive.sar\n"
12453
-" .ar -xvf archive.sar # Verbosely extract files from archive.sar\n"
12454
-"\n"
12455
-"Each command line must feature exactly one command option:\n"
12456
-" -c, --create Create a new archive\n"
12457
-" -u, --update Update or add files to an existing archive\n"
12458
-" -t, --list List contents of archive\n"
12459
-" -x, --extract Extract files from archive\n"
12460
-"\n"
12461
-"And zero or more optional options:\n"
12462
-" -v, --verbose Print each filename as it is processed\n"
12463
-" -f FILE, --file FILE Operate on archive FILE (default is current db)\n"
12464
-" -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS\n"
12465
-" -C DIR, --directory DIR Change to directory DIR to read/extract files\n"
12466
-" -n, --dryrun Show the SQL that would have occurred\n"
12467
-"\n"
12468
-"See also: http://sqlite.org/cli.html#sqlar_archive_support\n"
12469
-"\n"
12470
-);
12616
+ showHelp(f,"archive");
1247112617
return SQLITE_ERROR;
1247212618
}
1247312619
1247412620
/*
1247512621
** Print an error message for the .ar command to stderr and return
@@ -12572,10 +12718,11 @@
1257212718
};
1257312719
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
1257412720
struct ArSwitch *pEnd = &aSwitch[nSwitch];
1257512721
1257612722
if( nArg<=1 ){
12723
+ utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
1257712724
return arUsage(stderr);
1257812725
}else{
1257912726
char *z = azArg[1];
1258012727
if( z[0]!='-' ){
1258112728
/* Traditional style [tar] invocation */
@@ -13343,19 +13490,23 @@
1334313490
rc = 1;
1334413491
}
1334513492
}else
1334613493
1334713494
if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
13348
- static const struct DbConfigChoices {const char *zName; int op;} aDbConfig[] = {
13495
+ static const struct DbConfigChoices {
13496
+ const char *zName;
13497
+ int op;
13498
+ } aDbConfig[] = {
1334913499
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
1335013500
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
1335113501
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
1335213502
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
1335313503
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
1335413504
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
1335513505
{ "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
1335613506
{ "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
13507
+ { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
1335713508
};
1335813509
int ii, v;
1335913510
open_db(p, 0);
1336013511
for(ii=0; ii<ArraySize(aDbConfig); ii++){
1336113512
if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
@@ -13590,11 +13741,18 @@
1359013741
rc = 1;
1359113742
}
1359213743
}else
1359313744
1359413745
if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
13595
- utf8_printf(p->out, "%s", zHelp);
13746
+ if( nArg>=2 ){
13747
+ n = showHelp(p->out, azArg[1]);
13748
+ if( n==0 ){
13749
+ utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
13750
+ }
13751
+ }else{
13752
+ showHelp(p->out, 0);
13753
+ }
1359613754
}else
1359713755
1359813756
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
1359913757
char *zTable; /* Insert data into this table */
1360013758
char *zFile; /* Name of file to extra content from */
@@ -14067,10 +14225,14 @@
1406714225
#endif
1406814226
}else if( optionMatch(z, "append") ){
1406914227
p->openMode = SHELL_OPEN_APPENDVFS;
1407014228
}else if( optionMatch(z, "readonly") ){
1407114229
p->openMode = SHELL_OPEN_READONLY;
14230
+#ifdef SQLITE_ENABLE_DESERIALIZE
14231
+ }else if( optionMatch(z, "deserialize") ){
14232
+ p->openMode = SHELL_OPEN_DESERIALIZE;
14233
+#endif
1407214234
}else if( z[0]=='-' ){
1407314235
utf8_printf(stderr, "unknown option: %s\n", z);
1407414236
rc = 1;
1407514237
goto meta_command_exit;
1407614238
}
@@ -14594,11 +14756,11 @@
1459414756
p->nSession++;
1459514757
pSession->zName = sqlite3_mprintf("%s", zName);
1459614758
}else
1459714759
/* If no command name matches, show a syntax error */
1459814760
session_syntax_error:
14599
- session_help(p);
14761
+ showHelp(p->out, "session");
1460014762
}else
1460114763
#endif
1460214764
1460314765
#ifdef SQLITE_DEBUG
1460414766
/* Undocumented commands for internal testing. Subject to change
@@ -15061,10 +15223,11 @@
1506115223
/*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
1506215224
/*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
1506315225
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
1506415226
/*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */
1506515227
{ "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
15228
+ { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
1506615229
{ "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
1506715230
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
1506815231
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
1506915232
#ifdef YYCOVERAGE
1507015233
{ "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
@@ -15155,10 +15318,11 @@
1515515318
break;
1515615319
1515715320
/* sqlite3_test_control(int, int) */
1515815321
case SQLITE_TESTCTRL_ASSERT:
1515915322
case SQLITE_TESTCTRL_ALWAYS:
15323
+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
1516015324
if( nArg==3 ){
1516115325
int opt = booleanValue(azArg[2]);
1516215326
rc2 = sqlite3_test_control(testctrl, opt);
1516315327
isOk = 1;
1516415328
}
@@ -15449,11 +15613,11 @@
1544915613
** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
1545015614
** any arbitrary text is a complete SQL statement. This is not very
1545115615
** user-friendly, but it does seem to work.
1545215616
*/
1545315617
#ifdef SQLITE_OMIT_COMPLETE
15454
-int sqlite3_complete(const char *zSql){ return 1; }
15618
+#define sqlite3_complete(x) 1
1545515619
#endif
1545615620
1545715621
/*
1545815622
** Return true if zSql is a complete SQL statement. Return false if it
1545915623
** ends in the middle of a string literal or C-style comment.
@@ -16035,10 +16199,14 @@
1603516199
}else if( strcmp(z,"-zip")==0 ){
1603616200
data.openMode = SHELL_OPEN_ZIPFILE;
1603716201
#endif
1603816202
}else if( strcmp(z,"-append")==0 ){
1603916203
data.openMode = SHELL_OPEN_APPENDVFS;
16204
+#ifdef SQLITE_ENABLE_DESERIALIZE
16205
+ }else if( strcmp(z,"-deserialize")==0 ){
16206
+ data.openMode = SHELL_OPEN_DESERIALIZE;
16207
+#endif
1604016208
}else if( strcmp(z,"-readonly")==0 ){
1604116209
data.openMode = SHELL_OPEN_READONLY;
1604216210
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
1604316211
}else if( strncmp(z, "-A",2)==0 ){
1604416212
/* All remaining command-line arguments are passed to the ".archive"
@@ -16130,10 +16298,14 @@
1613016298
}else if( strcmp(z,"-zip")==0 ){
1613116299
data.openMode = SHELL_OPEN_ZIPFILE;
1613216300
#endif
1613316301
}else if( strcmp(z,"-append")==0 ){
1613416302
data.openMode = SHELL_OPEN_APPENDVFS;
16303
+#ifdef SQLITE_ENABLE_DESERIALIZE
16304
+ }else if( strcmp(z,"-deserialize")==0 ){
16305
+ data.openMode = SHELL_OPEN_DESERIALIZE;
16306
+#endif
1613516307
}else if( strcmp(z,"-readonly")==0 ){
1613616308
data.openMode = SHELL_OPEN_READONLY;
1613716309
}else if( strcmp(z,"-ascii")==0 ){
1613816310
data.mode = MODE_Ascii;
1613916311
sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
@@ -16274,11 +16446,11 @@
1627416446
}else{
1627516447
/* Run commands received from standard input
1627616448
*/
1627716449
if( stdin_is_interactive ){
1627816450
char *zHome;
16279
- char *zHistory = 0;
16451
+ char *zHistory;
1628016452
int nHistory;
1628116453
printf(
1628216454
"SQLite version %s %.19s\n" /*extra-version-info*/
1628316455
"Enter \".help\" for usage hints.\n",
1628416456
sqlite3_libversion(), sqlite3_sourceid()
@@ -16287,12 +16459,14 @@
1628716459
printf("Connected to a ");
1628816460
printBold("transient in-memory database");
1628916461
printf(".\nUse \".open FILENAME\" to reopen on a "
1629016462
"persistent database.\n");
1629116463
}
16292
- zHome = find_home_dir(0);
16293
- if( zHome ){
16464
+ zHistory = getenv("SQLITE_HISTORY");
16465
+ if( zHistory ){
16466
+ zHistory = strdup(zHistory);
16467
+ }else if( (zHome = find_home_dir(0))!=0 ){
1629416468
nHistory = strlen30(zHome) + 20;
1629516469
if( (zHistory = malloc(nHistory))!=0 ){
1629616470
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
1629716471
}
1629816472
}
1629916473
--- src/shell.c
+++ src/shell.c
@@ -1315,11 +1315,11 @@
1315 ** May you find forgiveness for yourself and forgive others.
1316 ** May you share freely, never taking more than you give.
1317 **
1318 ******************************************************************************
1319 **
1320 ** This SQLite extension implements a functions that compute SHA1 hashes.
1321 ** Two SQL functions are implemented:
1322 **
1323 ** sha3(X,SIZE)
1324 ** sha3_query(Y,SIZE)
1325 **
@@ -2126,11 +2126,22 @@
2126 #endif
2127 #include <time.h>
2128 #include <errno.h>
2129
2130
 
 
 
 
2131 #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
 
 
 
 
 
 
 
2132
2133 /*
2134 ** Set the result stored by context ctx to a blob containing the
2135 ** contents of file zName.
2136 */
@@ -2715,24 +2726,24 @@
2715 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
2716 int i /* Which column to return */
2717 ){
2718 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2719 switch( i ){
2720 case 0: { /* name */
2721 sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
2722 break;
2723 }
2724
2725 case 1: /* mode */
2726 sqlite3_result_int64(ctx, pCur->sStat.st_mode);
2727 break;
2728
2729 case 2: /* mtime */
2730 sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
2731 break;
2732
2733 case 3: { /* data */
2734 mode_t m = pCur->sStat.st_mode;
2735 if( S_ISDIR(m) ){
2736 sqlite3_result_null(ctx);
2737 #if !defined(_WIN32) && !defined(WIN32)
2738 }else if( S_ISLNK(m) ){
@@ -2758,10 +2769,16 @@
2758 #endif
2759 }else{
2760 readFileContents(ctx, pCur->zPath);
2761 }
2762 }
 
 
 
 
 
 
2763 }
2764 return SQLITE_OK;
2765 }
2766
2767 /*
@@ -2784,10 +2801,13 @@
2784 return (pCur->zPath==0);
2785 }
2786
2787 /*
2788 ** xFilter callback.
 
 
 
2789 */
2790 static int fsdirFilter(
2791 sqlite3_vtab_cursor *cur,
2792 int idxNum, const char *idxStr,
2793 int argc, sqlite3_value **argv
@@ -2836,44 +2856,67 @@
2836 ** plan.
2837 **
2838 ** In this implementation idxNum is used to represent the
2839 ** query plan. idxStr is unused.
2840 **
2841 ** The query plan is represented by bits in idxNum:
2842 **
2843 ** (1) start = $value -- constraint exists
2844 ** (2) stop = $value -- constraint exists
2845 ** (4) step = $value -- constraint exists
2846 ** (8) output in descending order
2847 */
2848 static int fsdirBestIndex(
2849 sqlite3_vtab *tab,
2850 sqlite3_index_info *pIdxInfo
2851 ){
2852 int i; /* Loop over constraints */
2853 int idx4 = -1;
2854 int idx5 = -1;
 
 
2855 const struct sqlite3_index_constraint *pConstraint;
2856
2857 (void)tab;
2858 pConstraint = pIdxInfo->aConstraint;
2859 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
2860 if( pConstraint->usable==0 ) continue;
2861 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
2862 if( pConstraint->iColumn==4 ) idx4 = i;
2863 if( pConstraint->iColumn==5 ) idx5 = i;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2864 }
2865
2866 if( idx4<0 ){
2867 pIdxInfo->idxNum = 0;
2868 pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
 
 
2869 }else{
2870 pIdxInfo->aConstraintUsage[idx4].omit = 1;
2871 pIdxInfo->aConstraintUsage[idx4].argvIndex = 1;
2872 if( idx5>=0 ){
2873 pIdxInfo->aConstraintUsage[idx5].omit = 1;
2874 pIdxInfo->aConstraintUsage[idx5].argvIndex = 2;
2875 pIdxInfo->idxNum = 2;
2876 pIdxInfo->estimatedCost = 10.0;
2877 }else{
2878 pIdxInfo->idxNum = 1;
2879 pIdxInfo->estimatedCost = 100.0;
@@ -2908,11 +2951,12 @@
2908 0, /* xRollback */
2909 0, /* xFindMethod */
2910 0, /* xRename */
2911 0, /* xSavepoint */
2912 0, /* xRelease */
2913 0 /* xRollbackTo */
 
2914 };
2915
2916 int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
2917 return rc;
2918 }
@@ -3416,11 +3460,12 @@
3416 0, /* xRollback */
3417 0, /* xFindMethod */
3418 0, /* xRename */
3419 0, /* xSavepoint */
3420 0, /* xRelease */
3421 0 /* xRollbackTo */
 
3422 };
3423
3424 #endif /* SQLITE_OMIT_VIRTUALTABLE */
3425
3426 int sqlite3CompletionVtabInit(sqlite3 *db){
@@ -5313,29 +5358,30 @@
5313 static int zipfileBestIndex(
5314 sqlite3_vtab *tab,
5315 sqlite3_index_info *pIdxInfo
5316 ){
5317 int i;
 
 
5318
5319 for(i=0; i<pIdxInfo->nConstraint; i++){
5320 const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
5321 if( pCons->usable==0 ) continue;
5322 if( pCons->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
5323 if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
5324 break;
 
 
 
 
5325 }
5326
5327 if( i<pIdxInfo->nConstraint ){
5328 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
5329 pIdxInfo->aConstraintUsage[i].omit = 1;
5330 pIdxInfo->estimatedCost = 1000.0;
5331 pIdxInfo->idxNum = 1;
5332 }else{
5333 pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
5334 pIdxInfo->idxNum = 0;
5335 }
5336
5337 return SQLITE_OK;
5338 }
5339
5340 static ZipfileEntry *zipfileNewEntry(const char *zPath){
5341 ZipfileEntry *pNew;
@@ -7134,10 +7180,11 @@
7134 0, /* xFindFunction - function overloading */
7135 0, /* xRename - rename the table */
7136 0, /* xSavepoint */
7137 0, /* xRelease */
7138 0, /* xRollbackTo */
 
7139 };
7140
7141 return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
7142 }
7143 /*
@@ -8558,15 +8605,16 @@
8558 #define AUTOEQP_trigger 2 /* On and also show plans for triggers */
8559 #define AUTOEQP_full 3 /* Show full EXPLAIN */
8560
8561 /* Allowed values for ShellState.openMode
8562 */
8563 #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
8564 #define SHELL_OPEN_NORMAL 1 /* Normal database file */
8565 #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
8566 #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
8567 #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
 
8568
8569 /*
8570 ** These are the allowed shellFlgs values
8571 */
8572 #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
@@ -8772,11 +8820,11 @@
8772 goto edit_func_end;
8773 }
8774 if( bBin ){
8775 sqlite3_result_blob64(context, p, sz, sqlite3_free);
8776 }else{
8777 int i, j;
8778 if( hasCRNL ){
8779 /* If the original contains \r\n then do no conversions back to \n */
8780 j = sz;
8781 }else{
8782 /* If the file did not originally contain \r\n then convert any new
@@ -10834,141 +10882,242 @@
10834 }
10835 return rc;
10836 }
10837
10838 /*
10839 ** Text of a help message
 
 
 
 
 
 
10840 */
10841 static char zHelp[] =
10842 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
10843 ".archive ... Manage SQL archives: \".archive --help\" for details\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10844 #endif
10845 #ifndef SQLITE_OMIT_AUTHORIZATION
10846 ".auth ON|OFF Show authorizer callbacks\n"
10847 #endif
10848 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
10849 " Add \"--append\" to open using appendvfs.\n"
10850 ".bail on|off Stop after hitting an error. Default OFF\n"
10851 ".binary on|off Turn binary output on or off. Default OFF\n"
10852 ".cd DIRECTORY Change the working directory to DIRECTORY\n"
10853 ".changes on|off Show number of rows changed by SQL\n"
10854 ".check GLOB Fail if output since .testcase does not match\n"
10855 ".clone NEWDB Clone data into NEWDB from the existing database\n"
10856 ".databases List names and files of attached databases\n"
10857 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options\n"
10858 ".dbinfo ?DB? Show status information about the database\n"
10859 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
10860 " If TABLE specified, only dump tables matching\n"
10861 " LIKE pattern TABLE.\n"
10862 ".echo on|off Turn command echo on or off\n"
10863 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
10864 ".excel Display the output of next command in a spreadsheet\n"
10865 ".exit Exit this program\n"
10866 ".expert EXPERIMENTAL. Suggest indexes for specified queries\n"
 
 
10867 /* Because explain mode comes on automatically now, the ".explain" mode
10868 ** is removed from the help screen. It is still supported for legacy, however */
10869 /*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/
10870 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
10871 ".headers on|off Turn display of headers on or off\n"
10872 ".help Show this message\n"
10873 ".import FILE TABLE Import data from FILE into TABLE\n"
10874 #ifndef SQLITE_OMIT_TEST_CONTROL
10875 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
10876 #endif
10877 ".indexes ?TABLE? Show names of all indexes\n"
10878 " If TABLE specified, only show indexes for tables\n"
10879 " matching LIKE pattern TABLE.\n"
10880 #ifdef SQLITE_ENABLE_IOTRACE
10881 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
10882 #endif
10883 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
10884 ".lint OPTIONS Report potential schema issues. Options:\n"
10885 " fkey-indexes Find missing foreign key indexes\n"
10886 #ifndef SQLITE_OMIT_LOAD_EXTENSION
10887 ".load FILE ?ENTRY? Load an extension library\n"
10888 #endif
10889 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
10890 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
10891 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
10892 " csv Comma-separated values\n"
10893 " column Left-aligned columns. (See .width)\n"
10894 " html HTML <table> code\n"
10895 " insert SQL insert statements for TABLE\n"
10896 " line One value per line\n"
10897 " list Values delimited by \"|\"\n"
10898 " quote Escape answers as for SQL\n"
10899 " tabs Tab-separated values\n"
10900 " tcl TCL list elements\n"
10901 ".nullvalue STRING Use STRING in place of NULL values\n"
10902 ".once (-e|-x|FILE) Output for the next SQL command only to FILE\n"
10903 " or invoke system text editor (-e) or spreadsheet (-x)\n"
10904 " on the output.\n"
10905 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
10906 " The --new option starts with an empty file\n"
10907 " Other options: --readonly --append --zip\n"
10908 ".output ?FILE? Send output to FILE or stdout\n"
10909 ".print STRING... Print literal STRING\n"
10910 ".prompt MAIN CONTINUE Replace the standard prompts\n"
10911 ".quit Exit this program\n"
10912 ".read FILENAME Execute SQL in FILENAME\n"
10913 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
10914 ".save FILE Write in-memory database into FILE\n"
10915 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
10916 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
10917 " Add --indent for pretty-printing\n"
10918 ".selftest ?--init? Run tests defined in the SELFTEST table\n"
10919 ".separator COL ?ROW? Change the column separator and optionally the row\n"
10920 " separator for both the output mode and .import\n"
10921 #if defined(SQLITE_ENABLE_SESSION)
10922 ".session CMD ... Create or control sessions\n"
10923 #endif
10924 ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n"
10925 #ifndef SQLITE_NOHAVE_SYSTEM
10926 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
10927 #endif
10928 ".show Show the current values for various settings\n"
10929 ".stats ?on|off? Show stats or turn stats on or off\n"
10930 #ifndef SQLITE_NOHAVE_SYSTEM
10931 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
10932 #endif
10933 ".tables ?TABLE? List names of tables\n"
10934 " If TABLE specified, only list tables matching\n"
10935 " LIKE pattern TABLE.\n"
10936 ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
10937 ".timeout MS Try opening locked tables for MS milliseconds\n"
10938 ".timer on|off Turn SQL timer on or off\n"
10939 ".trace FILE|off Output each SQL statement as it is run\n"
10940 ".vfsinfo ?AUX? Information about the top-level VFS\n"
10941 ".vfslist List all available VFSes\n"
10942 ".vfsname ?AUX? Print the name of the VFS stack\n"
10943 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
10944 " Negative values right-justify\n"
10945 ;
10946
10947 #if defined(SQLITE_ENABLE_SESSION)
10948 /*
10949 ** Print help information for the ".sessions" command
10950 */
10951 void session_help(ShellState *p){
10952 raw_printf(p->out,
10953 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
10954 "If ?NAME? is omitted, the first defined session is used.\n"
10955 "Subcommands:\n"
10956 " attach TABLE Attach TABLE\n"
10957 " changeset FILE Write a changeset into FILE\n"
10958 " close Close one session\n"
10959 " enable ?BOOLEAN? Set or query the enable bit\n"
10960 " filter GLOB... Reject tables matching GLOBs\n"
10961 " indirect ?BOOLEAN? Mark or query the indirect status\n"
10962 " isempty Query whether the session is empty\n"
10963 " list List currently open session names\n"
10964 " open DB NAME Open a new session on DB\n"
10965 " patchset FILE Write a patchset into FILE\n"
10966 );
10967 }
10968 #endif
10969
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10970
10971 /* Forward reference */
10972 static int process_input(ShellState *p, FILE *in);
10973
10974 /*
@@ -10994,11 +11143,11 @@
10994 if( in==0 ) return 0;
10995 fseek(in, 0, SEEK_END);
10996 nIn = ftell(in);
10997 rewind(in);
10998 pBuf = sqlite3_malloc64( nIn+1 );
10999 if( pBuf==0 ) return 0;
11000 nRead = fread(pBuf, nIn, 1, in);
11001 fclose(in);
11002 if( nRead!=1 ){
11003 sqlite3_free(pBuf);
11004 return 0;
@@ -11074,10 +11223,15 @@
11074 return SHELL_OPEN_ZIPFILE;
11075 }else{
11076 return SHELL_OPEN_NORMAL;
11077 }
11078 }
 
 
 
 
 
11079 fseek(f, -25, SEEK_END);
11080 n = fread(zBuf, 25, 1, f);
11081 if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
11082 rc = SHELL_OPEN_APPENDVFS;
11083 }else{
@@ -11124,10 +11278,14 @@
11124 switch( p->openMode ){
11125 case SHELL_OPEN_APPENDVFS: {
11126 sqlite3_open_v2(p->zDbFilename, &p->db,
11127 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
11128 break;
 
 
 
 
11129 }
11130 case SHELL_OPEN_ZIPFILE: {
11131 sqlite3_open(":memory:", &p->db);
11132 break;
11133 }
@@ -11174,10 +11332,22 @@
11174 char *zSql = sqlite3_mprintf(
11175 "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
11176 sqlite3_exec(p->db, zSql, 0, 0, 0);
11177 sqlite3_free(zSql);
11178 }
 
 
 
 
 
 
 
 
 
 
 
 
11179 }
11180 }
11181
11182 /*
11183 ** Attempt to close the databaes connection. Report errors.
@@ -12378,10 +12548,11 @@
12378 if( *pRc==SQLITE_OK ){
12379 va_list ap;
12380 char *z;
12381 va_start(ap, zFmt);
12382 z = sqlite3_vmprintf(zFmt, ap);
 
12383 if( z==0 ){
12384 *pRc = SQLITE_NOMEM;
12385 }else{
12386 shellPrepare(db, pRc, z, ppStmt);
12387 sqlite3_free(z);
@@ -12440,36 +12611,11 @@
12440
12441 /*
12442 ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
12443 */
12444 static int arUsage(FILE *f){
12445 raw_printf(f,
12446 "\n"
12447 "Usage: .ar [OPTION...] [FILE...]\n"
12448 "The .ar command manages sqlar archives.\n"
12449 "\n"
12450 "Examples:\n"
12451 " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar\n"
12452 " .ar -tf archive.sar # List members of archive.sar\n"
12453 " .ar -xvf archive.sar # Verbosely extract files from archive.sar\n"
12454 "\n"
12455 "Each command line must feature exactly one command option:\n"
12456 " -c, --create Create a new archive\n"
12457 " -u, --update Update or add files to an existing archive\n"
12458 " -t, --list List contents of archive\n"
12459 " -x, --extract Extract files from archive\n"
12460 "\n"
12461 "And zero or more optional options:\n"
12462 " -v, --verbose Print each filename as it is processed\n"
12463 " -f FILE, --file FILE Operate on archive FILE (default is current db)\n"
12464 " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS\n"
12465 " -C DIR, --directory DIR Change to directory DIR to read/extract files\n"
12466 " -n, --dryrun Show the SQL that would have occurred\n"
12467 "\n"
12468 "See also: http://sqlite.org/cli.html#sqlar_archive_support\n"
12469 "\n"
12470 );
12471 return SQLITE_ERROR;
12472 }
12473
12474 /*
12475 ** Print an error message for the .ar command to stderr and return
@@ -12572,10 +12718,11 @@
12572 };
12573 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
12574 struct ArSwitch *pEnd = &aSwitch[nSwitch];
12575
12576 if( nArg<=1 ){
 
12577 return arUsage(stderr);
12578 }else{
12579 char *z = azArg[1];
12580 if( z[0]!='-' ){
12581 /* Traditional style [tar] invocation */
@@ -13343,19 +13490,23 @@
13343 rc = 1;
13344 }
13345 }else
13346
13347 if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
13348 static const struct DbConfigChoices {const char *zName; int op;} aDbConfig[] = {
 
 
 
13349 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
13350 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
13351 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
13352 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
13353 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
13354 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
13355 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
13356 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
 
13357 };
13358 int ii, v;
13359 open_db(p, 0);
13360 for(ii=0; ii<ArraySize(aDbConfig); ii++){
13361 if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
@@ -13590,11 +13741,18 @@
13590 rc = 1;
13591 }
13592 }else
13593
13594 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
13595 utf8_printf(p->out, "%s", zHelp);
 
 
 
 
 
 
 
13596 }else
13597
13598 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
13599 char *zTable; /* Insert data into this table */
13600 char *zFile; /* Name of file to extra content from */
@@ -14067,10 +14225,14 @@
14067 #endif
14068 }else if( optionMatch(z, "append") ){
14069 p->openMode = SHELL_OPEN_APPENDVFS;
14070 }else if( optionMatch(z, "readonly") ){
14071 p->openMode = SHELL_OPEN_READONLY;
 
 
 
 
14072 }else if( z[0]=='-' ){
14073 utf8_printf(stderr, "unknown option: %s\n", z);
14074 rc = 1;
14075 goto meta_command_exit;
14076 }
@@ -14594,11 +14756,11 @@
14594 p->nSession++;
14595 pSession->zName = sqlite3_mprintf("%s", zName);
14596 }else
14597 /* If no command name matches, show a syntax error */
14598 session_syntax_error:
14599 session_help(p);
14600 }else
14601 #endif
14602
14603 #ifdef SQLITE_DEBUG
14604 /* Undocumented commands for internal testing. Subject to change
@@ -15061,10 +15223,11 @@
15061 /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
15062 /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
15063 { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
15064 /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */
15065 { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
 
15066 { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
15067 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
15068 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
15069 #ifdef YYCOVERAGE
15070 { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
@@ -15155,10 +15318,11 @@
15155 break;
15156
15157 /* sqlite3_test_control(int, int) */
15158 case SQLITE_TESTCTRL_ASSERT:
15159 case SQLITE_TESTCTRL_ALWAYS:
 
15160 if( nArg==3 ){
15161 int opt = booleanValue(azArg[2]);
15162 rc2 = sqlite3_test_control(testctrl, opt);
15163 isOk = 1;
15164 }
@@ -15449,11 +15613,11 @@
15449 ** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
15450 ** any arbitrary text is a complete SQL statement. This is not very
15451 ** user-friendly, but it does seem to work.
15452 */
15453 #ifdef SQLITE_OMIT_COMPLETE
15454 int sqlite3_complete(const char *zSql){ return 1; }
15455 #endif
15456
15457 /*
15458 ** Return true if zSql is a complete SQL statement. Return false if it
15459 ** ends in the middle of a string literal or C-style comment.
@@ -16035,10 +16199,14 @@
16035 }else if( strcmp(z,"-zip")==0 ){
16036 data.openMode = SHELL_OPEN_ZIPFILE;
16037 #endif
16038 }else if( strcmp(z,"-append")==0 ){
16039 data.openMode = SHELL_OPEN_APPENDVFS;
 
 
 
 
16040 }else if( strcmp(z,"-readonly")==0 ){
16041 data.openMode = SHELL_OPEN_READONLY;
16042 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
16043 }else if( strncmp(z, "-A",2)==0 ){
16044 /* All remaining command-line arguments are passed to the ".archive"
@@ -16130,10 +16298,14 @@
16130 }else if( strcmp(z,"-zip")==0 ){
16131 data.openMode = SHELL_OPEN_ZIPFILE;
16132 #endif
16133 }else if( strcmp(z,"-append")==0 ){
16134 data.openMode = SHELL_OPEN_APPENDVFS;
 
 
 
 
16135 }else if( strcmp(z,"-readonly")==0 ){
16136 data.openMode = SHELL_OPEN_READONLY;
16137 }else if( strcmp(z,"-ascii")==0 ){
16138 data.mode = MODE_Ascii;
16139 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
@@ -16274,11 +16446,11 @@
16274 }else{
16275 /* Run commands received from standard input
16276 */
16277 if( stdin_is_interactive ){
16278 char *zHome;
16279 char *zHistory = 0;
16280 int nHistory;
16281 printf(
16282 "SQLite version %s %.19s\n" /*extra-version-info*/
16283 "Enter \".help\" for usage hints.\n",
16284 sqlite3_libversion(), sqlite3_sourceid()
@@ -16287,12 +16459,14 @@
16287 printf("Connected to a ");
16288 printBold("transient in-memory database");
16289 printf(".\nUse \".open FILENAME\" to reopen on a "
16290 "persistent database.\n");
16291 }
16292 zHome = find_home_dir(0);
16293 if( zHome ){
 
 
16294 nHistory = strlen30(zHome) + 20;
16295 if( (zHistory = malloc(nHistory))!=0 ){
16296 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
16297 }
16298 }
16299
--- src/shell.c
+++ src/shell.c
@@ -1315,11 +1315,11 @@
1315 ** May you find forgiveness for yourself and forgive others.
1316 ** May you share freely, never taking more than you give.
1317 **
1318 ******************************************************************************
1319 **
1320 ** This SQLite extension implements functions that compute SHA3 hashes.
1321 ** Two SQL functions are implemented:
1322 **
1323 ** sha3(X,SIZE)
1324 ** sha3_query(Y,SIZE)
1325 **
@@ -2126,11 +2126,22 @@
2126 #endif
2127 #include <time.h>
2128 #include <errno.h>
2129
2130
2131 /*
2132 ** Structure of the fsdir() table-valued function
2133 */
2134 /* 0 1 2 3 4 5 */
2135 #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
2136 #define FSDIR_COLUMN_NAME 0 /* Name of the file */
2137 #define FSDIR_COLUMN_MODE 1 /* Access mode */
2138 #define FSDIR_COLUMN_MTIME 2 /* Last modification time */
2139 #define FSDIR_COLUMN_DATA 3 /* File content */
2140 #define FSDIR_COLUMN_PATH 4 /* Path to top of search */
2141 #define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
2142
2143
2144 /*
2145 ** Set the result stored by context ctx to a blob containing the
2146 ** contents of file zName.
2147 */
@@ -2715,24 +2726,24 @@
2726 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
2727 int i /* Which column to return */
2728 ){
2729 fsdir_cursor *pCur = (fsdir_cursor*)cur;
2730 switch( i ){
2731 case FSDIR_COLUMN_NAME: {
2732 sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
2733 break;
2734 }
2735
2736 case FSDIR_COLUMN_MODE:
2737 sqlite3_result_int64(ctx, pCur->sStat.st_mode);
2738 break;
2739
2740 case FSDIR_COLUMN_MTIME:
2741 sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
2742 break;
2743
2744 case FSDIR_COLUMN_DATA: {
2745 mode_t m = pCur->sStat.st_mode;
2746 if( S_ISDIR(m) ){
2747 sqlite3_result_null(ctx);
2748 #if !defined(_WIN32) && !defined(WIN32)
2749 }else if( S_ISLNK(m) ){
@@ -2758,10 +2769,16 @@
2769 #endif
2770 }else{
2771 readFileContents(ctx, pCur->zPath);
2772 }
2773 }
2774 case FSDIR_COLUMN_PATH:
2775 default: {
2776 /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
2777 ** always return their values as NULL */
2778 break;
2779 }
2780 }
2781 return SQLITE_OK;
2782 }
2783
2784 /*
@@ -2784,10 +2801,13 @@
2801 return (pCur->zPath==0);
2802 }
2803
2804 /*
2805 ** xFilter callback.
2806 **
2807 ** idxNum==1 PATH parameter only
2808 ** idxNum==2 Both PATH and DIR supplied
2809 */
2810 static int fsdirFilter(
2811 sqlite3_vtab_cursor *cur,
2812 int idxNum, const char *idxStr,
2813 int argc, sqlite3_value **argv
@@ -2836,44 +2856,67 @@
2856 ** plan.
2857 **
2858 ** In this implementation idxNum is used to represent the
2859 ** query plan. idxStr is unused.
2860 **
2861 ** The query plan is represented by values of idxNum:
2862 **
2863 ** (1) The path value is supplied by argv[0]
2864 ** (2) Path is in argv[0] and dir is in argv[1]
 
 
2865 */
2866 static int fsdirBestIndex(
2867 sqlite3_vtab *tab,
2868 sqlite3_index_info *pIdxInfo
2869 ){
2870 int i; /* Loop over constraints */
2871 int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
2872 int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
2873 int seenPath = 0; /* True if an unusable PATH= constraint is seen */
2874 int seenDir = 0; /* True if an unusable DIR= constraint is seen */
2875 const struct sqlite3_index_constraint *pConstraint;
2876
2877 (void)tab;
2878 pConstraint = pIdxInfo->aConstraint;
2879 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
 
2880 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
2881 switch( pConstraint->iColumn ){
2882 case FSDIR_COLUMN_PATH: {
2883 if( pConstraint->usable ){
2884 idxPath = i;
2885 seenPath = 0;
2886 }else if( idxPath<0 ){
2887 seenPath = 1;
2888 }
2889 break;
2890 }
2891 case FSDIR_COLUMN_DIR: {
2892 if( pConstraint->usable ){
2893 idxDir = i;
2894 seenDir = 0;
2895 }else if( idxDir<0 ){
2896 seenDir = 1;
2897 }
2898 break;
2899 }
2900 }
2901 }
2902 if( seenPath || seenDir ){
2903 /* If input parameters are unusable, disallow this plan */
2904 return SQLITE_CONSTRAINT;
2905 }
2906
2907 if( idxPath<0 ){
2908 pIdxInfo->idxNum = 0;
2909 /* The pIdxInfo->estimatedCost should have been initialized to a huge
2910 ** number. Leave it unchanged. */
2911 pIdxInfo->estimatedRows = 0x7fffffff;
2912 }else{
2913 pIdxInfo->aConstraintUsage[idxPath].omit = 1;
2914 pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
2915 if( idxDir>=0 ){
2916 pIdxInfo->aConstraintUsage[idxDir].omit = 1;
2917 pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
2918 pIdxInfo->idxNum = 2;
2919 pIdxInfo->estimatedCost = 10.0;
2920 }else{
2921 pIdxInfo->idxNum = 1;
2922 pIdxInfo->estimatedCost = 100.0;
@@ -2908,11 +2951,12 @@
2951 0, /* xRollback */
2952 0, /* xFindMethod */
2953 0, /* xRename */
2954 0, /* xSavepoint */
2955 0, /* xRelease */
2956 0, /* xRollbackTo */
2957 0, /* xShadowName */
2958 };
2959
2960 int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
2961 return rc;
2962 }
@@ -3416,11 +3460,12 @@
3460 0, /* xRollback */
3461 0, /* xFindMethod */
3462 0, /* xRename */
3463 0, /* xSavepoint */
3464 0, /* xRelease */
3465 0, /* xRollbackTo */
3466 0 /* xShadowName */
3467 };
3468
3469 #endif /* SQLITE_OMIT_VIRTUALTABLE */
3470
3471 int sqlite3CompletionVtabInit(sqlite3 *db){
@@ -5313,29 +5358,30 @@
5358 static int zipfileBestIndex(
5359 sqlite3_vtab *tab,
5360 sqlite3_index_info *pIdxInfo
5361 ){
5362 int i;
5363 int idx = -1;
5364 int unusable = 0;
5365
5366 for(i=0; i<pIdxInfo->nConstraint; i++){
5367 const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
 
 
5368 if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
5369 if( pCons->usable==0 ){
5370 unusable = 1;
5371 }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
5372 idx = i;
5373 }
5374 }
5375 if( idx>=0 ){
5376 pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
5377 pIdxInfo->aConstraintUsage[idx].omit = 1;
 
5378 pIdxInfo->estimatedCost = 1000.0;
5379 pIdxInfo->idxNum = 1;
5380 }else if( unusable ){
5381 return SQLITE_CONSTRAINT;
 
5382 }
 
5383 return SQLITE_OK;
5384 }
5385
5386 static ZipfileEntry *zipfileNewEntry(const char *zPath){
5387 ZipfileEntry *pNew;
@@ -7134,10 +7180,11 @@
7180 0, /* xFindFunction - function overloading */
7181 0, /* xRename - rename the table */
7182 0, /* xSavepoint */
7183 0, /* xRelease */
7184 0, /* xRollbackTo */
7185 0, /* xShadowName */
7186 };
7187
7188 return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
7189 }
7190 /*
@@ -8558,15 +8605,16 @@
8605 #define AUTOEQP_trigger 2 /* On and also show plans for triggers */
8606 #define AUTOEQP_full 3 /* Show full EXPLAIN */
8607
8608 /* Allowed values for ShellState.openMode
8609 */
8610 #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
8611 #define SHELL_OPEN_NORMAL 1 /* Normal database file */
8612 #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
8613 #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
8614 #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
8615 #define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
8616
8617 /*
8618 ** These are the allowed shellFlgs values
8619 */
8620 #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
@@ -8772,11 +8820,11 @@
8820 goto edit_func_end;
8821 }
8822 if( bBin ){
8823 sqlite3_result_blob64(context, p, sz, sqlite3_free);
8824 }else{
8825 sqlite3_int64 i, j;
8826 if( hasCRNL ){
8827 /* If the original contains \r\n then do no conversions back to \n */
8828 j = sz;
8829 }else{
8830 /* If the file did not originally contain \r\n then convert any new
@@ -10834,141 +10882,242 @@
10882 }
10883 return rc;
10884 }
10885
10886 /*
10887 ** Text of help messages.
10888 **
10889 ** The help text for each individual command begins with a line that starts
10890 ** with ".". Subsequent lines are supplimental information.
10891 **
10892 ** There must be two or more spaces between the end of the command and the
10893 ** start of the description of what that command does.
10894 */
10895 static const char *(azHelp[]) = {
10896 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
10897 ".archive ... Manage SQL archives",
10898 " Each command must have exactly one of the following options:",
10899 " -c, --create Create a new archive",
10900 " -u, --update Update or add files to an existing archive",
10901 " -t, --list List contents of archive",
10902 " -x, --extract Extract files from archive",
10903 " Optional arguments:",
10904 " -v, --verbose Print each filename as it is processed",
10905 " -f FILE, --file FILE Operate on archive FILE (default is current db)",
10906 " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS",
10907 " -C DIR, --directory DIR Change to directory DIR to read/extract files",
10908 " -n, --dryrun Show the SQL that would have occurred",
10909 " Examples:",
10910 " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar",
10911 " .ar -tf archive.sar # List members of archive.sar",
10912 " .ar -xvf archive.sar # Verbosely extract files from archive.sar",
10913 " See also:",
10914 " http://sqlite.org/cli.html#sqlar_archive_support",
10915 #endif
10916 #ifndef SQLITE_OMIT_AUTHORIZATION
10917 ".auth ON|OFF Show authorizer callbacks",
10918 #endif
10919 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
10920 " --append Use the appendvfs",
10921 ".bail on|off Stop after hitting an error. Default OFF",
10922 ".binary on|off Turn binary output on or off. Default OFF",
10923 ".cd DIRECTORY Change the working directory to DIRECTORY",
10924 ".changes on|off Show number of rows changed by SQL",
10925 ".check GLOB Fail if output since .testcase does not match",
10926 ".clone NEWDB Clone data into NEWDB from the existing database",
10927 ".databases List names and files of attached databases",
10928 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
10929 ".dbinfo ?DB? Show status information about the database",
10930 ".dump ?TABLE? ... Render all database content as SQL",
10931 " Options:",
10932 " --preserve-rowids Include ROWID values in the output",
10933 " --newlines Allow unescaped newline characters in output",
10934 " TABLE is LIKE pattern for the tables to dump",
10935 ".echo on|off Turn command echo on or off",
10936 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN",
10937 ".excel Display the output of next command in a spreadsheet",
10938 ".exit ?CODE? Exit this program with return-code CODE",
10939 ".expert EXPERIMENTAL. Suggest indexes for specified queries",
10940 /* Because explain mode comes on automatically now, the ".explain" mode
10941 ** is removed from the help screen. It is still supported for legacy, however */
10942 /*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/
10943 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
10944 ".headers on|off Turn display of headers on or off",
10945 ".help ?-all? ?PATTERN? Show help text for PATTERN",
10946 ".import FILE TABLE Import data from FILE into TABLE",
10947 #ifndef SQLITE_OMIT_TEST_CONTROL
10948 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
10949 #endif
10950 ".indexes ?TABLE? Show names of indexes",
10951 " If TABLE is specified, only show indexes for",
10952 " tables matching TABLE using the LIKE operator.",
10953 #ifdef SQLITE_ENABLE_IOTRACE
10954 ".iotrace FILE Enable I/O diagnostic logging to FILE",
10955 #endif
10956 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
10957 ".lint OPTIONS Report potential schema issues.",
10958 " Options:",
10959 " fkey-indexes Find missing foreign key indexes",
10960 #ifndef SQLITE_OMIT_LOAD_EXTENSION
10961 ".load FILE ?ENTRY? Load an extension library",
10962 #endif
10963 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
10964 ".mode MODE ?TABLE? Set output mode",
10965 " MODE is one of:",
10966 " ascii Columns/rows delimited by 0x1F and 0x1E",
10967 " csv Comma-separated values",
10968 " column Left-aligned columns. (See .width)",
10969 " html HTML <table> code",
10970 " insert SQL insert statements for TABLE",
10971 " line One value per line",
10972 " list Values delimited by \"|\"",
10973 " quote Escape answers as for SQL",
10974 " tabs Tab-separated values",
10975 " tcl TCL list elements",
10976 ".nullvalue STRING Use STRING in place of NULL values",
10977 ".once (-e|-x|FILE) Output for the next SQL command only to FILE",
10978 " If FILE begins with '|' then open as a pipe",
10979 " Other options:",
10980 " -e Invoke system text editor",
10981 " -x Open in a spreadsheet",
10982 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
10983 " Options:",
10984 " --append Use appendvfs to append database to the end of FILE",
10985 #ifdef SQLITE_ENABLE_DESERIALIZE
10986 " --deserialize Load into memory useing sqlite3_deserialize()",
10987 #endif
10988 " --new Initialize FILE to an empty database",
10989 " --readonly Open FILE readonly",
10990 " --zip FILE is a ZIP archive",
10991 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
10992 " If FILE begins with '|' then open it as a pipe.",
10993 ".print STRING... Print literal STRING",
10994 ".prompt MAIN CONTINUE Replace the standard prompts",
10995 ".quit Exit this program",
10996 ".read FILE Read input from FILE",
10997 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
10998 ".save FILE Write in-memory database into FILE",
10999 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
11000 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
11001 " Options:",
11002 " --indent Try to pretty-print the schema",
11003 ".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
11004 " Options:",
11005 " --init Create a new SELFTEST table",
11006 " -v Verbose output",
11007 ".separator COL ?ROW? Change the column and row separators",
11008 #if defined(SQLITE_ENABLE_SESSION)
11009 ".session ?NAME? CMD ... Create or control sessions",
11010 " Subcommands:",
11011 " attach TABLE Attach TABLE",
11012 " changeset FILE Write a changeset into FILE",
11013 " close Close one session",
11014 " enable ?BOOLEAN? Set or query the enable bit",
11015 " filter GLOB... Reject tables matching GLOBs",
11016 " indirect ?BOOLEAN? Mark or query the indirect status",
11017 " isempty Query whether the session is empty",
11018 " list List currently open session names",
11019 " open DB NAME Open a new session on DB",
11020 " patchset FILE Write a patchset into FILE",
11021 " If ?NAME? is omitted, the first defined session is used.",
11022 #endif
11023 ".sha3sum ... Compute a SHA3 hash of database content",
11024 " Options:",
11025 " --schema Also hash the sqlite_master table",
11026 " --sha3-224 Use the sha3-224 algorithm",
11027 " --sha3-256 Use the sha3-256 algorithm. This is the default.",
11028 " --sha3-384 Use the sha3-384 algorithm",
11029 " --sha3-512 Use the sha3-512 algorithm",
11030 " Any other argument is a LIKE pattern for tables to hash",
11031 #ifndef SQLITE_NOHAVE_SYSTEM
11032 ".shell CMD ARGS... Run CMD ARGS... in a system shell",
11033 #endif
11034 ".show Show the current values for various settings",
11035 ".stats ?on|off? Show stats or turn stats on or off",
11036 #ifndef SQLITE_NOHAVE_SYSTEM
11037 ".system CMD ARGS... Run CMD ARGS... in a system shell",
11038 #endif
11039 ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
11040 ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
11041 ".timeout MS Try opening locked tables for MS milliseconds",
11042 ".timer on|off Turn SQL timer on or off",
11043 ".trace FILE|off Output each SQL statement as it is run",
11044 ".vfsinfo ?AUX? Information about the top-level VFS",
11045 ".vfslist List all available VFSes",
11046 ".vfsname ?AUX? Print the name of the VFS stack",
11047 ".width NUM1 NUM2 ... Set column widths for \"column\" mode",
11048 " Negative values right-justify",
11049 };
11050
11051 /*
11052 ** Output help text.
11053 **
11054 ** zPattern describes the set of commands for which help text is provided.
11055 ** If zPattern is NULL, then show all commands, but only give a one-line
11056 ** description of each.
11057 **
11058 ** Return the number of matches.
11059 */
11060 static int showHelp(FILE *out, const char *zPattern){
11061 int i = 0;
11062 int j = 0;
11063 int n = 0;
11064 char *zPat;
11065 if( zPattern==0
11066 || zPattern[0]=='0'
11067 || strcmp(zPattern,"-a")==0
11068 || strcmp(zPattern,"-all")==0
11069 ){
11070 /* Show all commands, but only one line per command */
11071 if( zPattern==0 ) zPattern = "";
11072 for(i=0; i<ArraySize(azHelp); i++){
11073 if( azHelp[i][0]=='.' || zPattern[0] ){
11074 utf8_printf(out, "%s\n", azHelp[i]);
11075 n++;
11076 }
11077 }
11078 }else{
11079 /* Look for commands that for which zPattern is an exact prefix */
11080 zPat = sqlite3_mprintf(".%s*", zPattern);
11081 for(i=0; i<ArraySize(azHelp); i++){
11082 if( sqlite3_strglob(zPat, azHelp[i])==0 ){
11083 utf8_printf(out, "%s\n", azHelp[i]);
11084 j = i+1;
11085 n++;
11086 }
11087 }
11088 sqlite3_free(zPat);
11089 if( n ){
11090 if( n==1 ){
11091 /* when zPattern is a prefix of exactly one command, then include the
11092 ** details of that command, which should begin at offset j */
11093 while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
11094 utf8_printf(out, "%s\n", azHelp[j]);
11095 j++;
11096 }
11097 }
11098 return n;
11099 }
11100 /* Look for commands that contain zPattern anywhere. Show the complete
11101 ** text of all commands that match. */
11102 zPat = sqlite3_mprintf("%%%s%%", zPattern);
11103 for(i=0; i<ArraySize(azHelp); i++){
11104 if( azHelp[i][0]=='.' ) j = i;
11105 if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
11106 utf8_printf(out, "%s\n", azHelp[j]);
11107 while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
11108 j++;
11109 utf8_printf(out, "%s\n", azHelp[j]);
11110 }
11111 i = j;
11112 n++;
11113 }
11114 }
11115 sqlite3_free(zPat);
11116 }
11117 return n;
11118 }
11119
11120 /* Forward reference */
11121 static int process_input(ShellState *p, FILE *in);
11122
11123 /*
@@ -10994,11 +11143,11 @@
11143 if( in==0 ) return 0;
11144 fseek(in, 0, SEEK_END);
11145 nIn = ftell(in);
11146 rewind(in);
11147 pBuf = sqlite3_malloc64( nIn+1 );
11148 if( pBuf==0 ){ fclose(in); return 0; }
11149 nRead = fread(pBuf, nIn, 1, in);
11150 fclose(in);
11151 if( nRead!=1 ){
11152 sqlite3_free(pBuf);
11153 return 0;
@@ -11074,10 +11223,15 @@
11223 return SHELL_OPEN_ZIPFILE;
11224 }else{
11225 return SHELL_OPEN_NORMAL;
11226 }
11227 }
11228 n = fread(zBuf, 16, 1, f);
11229 if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
11230 fclose(f);
11231 return SHELL_OPEN_NORMAL;
11232 }
11233 fseek(f, -25, SEEK_END);
11234 n = fread(zBuf, 25, 1, f);
11235 if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
11236 rc = SHELL_OPEN_APPENDVFS;
11237 }else{
@@ -11124,10 +11278,14 @@
11278 switch( p->openMode ){
11279 case SHELL_OPEN_APPENDVFS: {
11280 sqlite3_open_v2(p->zDbFilename, &p->db,
11281 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
11282 break;
11283 }
11284 case SHELL_OPEN_DESERIALIZE: {
11285 sqlite3_open(0, &p->db);
11286 break;
11287 }
11288 case SHELL_OPEN_ZIPFILE: {
11289 sqlite3_open(":memory:", &p->db);
11290 break;
11291 }
@@ -11174,10 +11332,22 @@
11332 char *zSql = sqlite3_mprintf(
11333 "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
11334 sqlite3_exec(p->db, zSql, 0, 0, 0);
11335 sqlite3_free(zSql);
11336 }
11337 #ifdef SQLITE_ENABLE_DESERIALIZE
11338 else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
11339 int nData = 0;
11340 unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
11341 int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
11342 SQLITE_DESERIALIZE_RESIZEABLE |
11343 SQLITE_DESERIALIZE_FREEONCLOSE);
11344 if( rc ){
11345 utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
11346 }
11347 }
11348 #endif
11349 }
11350 }
11351
11352 /*
11353 ** Attempt to close the databaes connection. Report errors.
@@ -12378,10 +12548,11 @@
12548 if( *pRc==SQLITE_OK ){
12549 va_list ap;
12550 char *z;
12551 va_start(ap, zFmt);
12552 z = sqlite3_vmprintf(zFmt, ap);
12553 va_end(ap);
12554 if( z==0 ){
12555 *pRc = SQLITE_NOMEM;
12556 }else{
12557 shellPrepare(db, pRc, z, ppStmt);
12558 sqlite3_free(z);
@@ -12440,36 +12611,11 @@
12611
12612 /*
12613 ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
12614 */
12615 static int arUsage(FILE *f){
12616 showHelp(f,"archive");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12617 return SQLITE_ERROR;
12618 }
12619
12620 /*
12621 ** Print an error message for the .ar command to stderr and return
@@ -12572,10 +12718,11 @@
12718 };
12719 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
12720 struct ArSwitch *pEnd = &aSwitch[nSwitch];
12721
12722 if( nArg<=1 ){
12723 utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
12724 return arUsage(stderr);
12725 }else{
12726 char *z = azArg[1];
12727 if( z[0]!='-' ){
12728 /* Traditional style [tar] invocation */
@@ -13343,19 +13490,23 @@
13490 rc = 1;
13491 }
13492 }else
13493
13494 if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
13495 static const struct DbConfigChoices {
13496 const char *zName;
13497 int op;
13498 } aDbConfig[] = {
13499 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
13500 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
13501 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
13502 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
13503 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
13504 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
13505 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
13506 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
13507 { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
13508 };
13509 int ii, v;
13510 open_db(p, 0);
13511 for(ii=0; ii<ArraySize(aDbConfig); ii++){
13512 if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
@@ -13590,11 +13741,18 @@
13741 rc = 1;
13742 }
13743 }else
13744
13745 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
13746 if( nArg>=2 ){
13747 n = showHelp(p->out, azArg[1]);
13748 if( n==0 ){
13749 utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
13750 }
13751 }else{
13752 showHelp(p->out, 0);
13753 }
13754 }else
13755
13756 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
13757 char *zTable; /* Insert data into this table */
13758 char *zFile; /* Name of file to extra content from */
@@ -14067,10 +14225,14 @@
14225 #endif
14226 }else if( optionMatch(z, "append") ){
14227 p->openMode = SHELL_OPEN_APPENDVFS;
14228 }else if( optionMatch(z, "readonly") ){
14229 p->openMode = SHELL_OPEN_READONLY;
14230 #ifdef SQLITE_ENABLE_DESERIALIZE
14231 }else if( optionMatch(z, "deserialize") ){
14232 p->openMode = SHELL_OPEN_DESERIALIZE;
14233 #endif
14234 }else if( z[0]=='-' ){
14235 utf8_printf(stderr, "unknown option: %s\n", z);
14236 rc = 1;
14237 goto meta_command_exit;
14238 }
@@ -14594,11 +14756,11 @@
14756 p->nSession++;
14757 pSession->zName = sqlite3_mprintf("%s", zName);
14758 }else
14759 /* If no command name matches, show a syntax error */
14760 session_syntax_error:
14761 showHelp(p->out, "session");
14762 }else
14763 #endif
14764
14765 #ifdef SQLITE_DEBUG
14766 /* Undocumented commands for internal testing. Subject to change
@@ -15061,10 +15223,11 @@
15223 /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
15224 /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
15225 { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
15226 /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */
15227 { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
15228 { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
15229 { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
15230 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
15231 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
15232 #ifdef YYCOVERAGE
15233 { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
@@ -15155,10 +15318,11 @@
15318 break;
15319
15320 /* sqlite3_test_control(int, int) */
15321 case SQLITE_TESTCTRL_ASSERT:
15322 case SQLITE_TESTCTRL_ALWAYS:
15323 case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
15324 if( nArg==3 ){
15325 int opt = booleanValue(azArg[2]);
15326 rc2 = sqlite3_test_control(testctrl, opt);
15327 isOk = 1;
15328 }
@@ -15449,11 +15613,11 @@
15613 ** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
15614 ** any arbitrary text is a complete SQL statement. This is not very
15615 ** user-friendly, but it does seem to work.
15616 */
15617 #ifdef SQLITE_OMIT_COMPLETE
15618 #define sqlite3_complete(x) 1
15619 #endif
15620
15621 /*
15622 ** Return true if zSql is a complete SQL statement. Return false if it
15623 ** ends in the middle of a string literal or C-style comment.
@@ -16035,10 +16199,14 @@
16199 }else if( strcmp(z,"-zip")==0 ){
16200 data.openMode = SHELL_OPEN_ZIPFILE;
16201 #endif
16202 }else if( strcmp(z,"-append")==0 ){
16203 data.openMode = SHELL_OPEN_APPENDVFS;
16204 #ifdef SQLITE_ENABLE_DESERIALIZE
16205 }else if( strcmp(z,"-deserialize")==0 ){
16206 data.openMode = SHELL_OPEN_DESERIALIZE;
16207 #endif
16208 }else if( strcmp(z,"-readonly")==0 ){
16209 data.openMode = SHELL_OPEN_READONLY;
16210 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
16211 }else if( strncmp(z, "-A",2)==0 ){
16212 /* All remaining command-line arguments are passed to the ".archive"
@@ -16130,10 +16298,14 @@
16298 }else if( strcmp(z,"-zip")==0 ){
16299 data.openMode = SHELL_OPEN_ZIPFILE;
16300 #endif
16301 }else if( strcmp(z,"-append")==0 ){
16302 data.openMode = SHELL_OPEN_APPENDVFS;
16303 #ifdef SQLITE_ENABLE_DESERIALIZE
16304 }else if( strcmp(z,"-deserialize")==0 ){
16305 data.openMode = SHELL_OPEN_DESERIALIZE;
16306 #endif
16307 }else if( strcmp(z,"-readonly")==0 ){
16308 data.openMode = SHELL_OPEN_READONLY;
16309 }else if( strcmp(z,"-ascii")==0 ){
16310 data.mode = MODE_Ascii;
16311 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
@@ -16274,11 +16446,11 @@
16446 }else{
16447 /* Run commands received from standard input
16448 */
16449 if( stdin_is_interactive ){
16450 char *zHome;
16451 char *zHistory;
16452 int nHistory;
16453 printf(
16454 "SQLite version %s %.19s\n" /*extra-version-info*/
16455 "Enter \".help\" for usage hints.\n",
16456 sqlite3_libversion(), sqlite3_sourceid()
@@ -16287,12 +16459,14 @@
16459 printf("Connected to a ");
16460 printBold("transient in-memory database");
16461 printf(".\nUse \".open FILENAME\" to reopen on a "
16462 "persistent database.\n");
16463 }
16464 zHistory = getenv("SQLITE_HISTORY");
16465 if( zHistory ){
16466 zHistory = strdup(zHistory);
16467 }else if( (zHome = find_home_dir(0))!=0 ){
16468 nHistory = strlen30(zHome) + 20;
16469 if( (zHistory = malloc(nHistory))!=0 ){
16470 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
16471 }
16472 }
16473
+10 -8
--- src/skins.c
+++ src/skins.c
@@ -459,11 +459,11 @@
459459
Stmt q;
460460
int seenCurrent = 0;
461461
int once;
462462
463463
login_check_credentials();
464
- if( !g.perm.Setup ){
464
+ if( !g.perm.Admin ){
465465
login_needed(0);
466466
return;
467467
}
468468
db_begin_transaction();
469469
zCurrent = getSkin(0);
@@ -676,15 +676,17 @@
676676
if( fossil_strcmp(zLabel, "current")==0 ){
677677
zResult = db_get(zFile, "");
678678
}else if( sqlite3_strglob("draft[1-9]", zLabel)==0 ){
679679
zResult = db_get_mprintf("", "%s-%s", zLabel, zFile);
680680
}else{
681
- while( 1 ){
681
+ int i;
682
+ for(i=0; i<2; i++){
682683
char *zKey = mprintf("skins/%s/%s.txt", zLabel, zFile);
683684
zResult = builtin_text(zKey);
684685
fossil_free(zKey);
685
- if( zResult!=0 || fossil_strcmp(zLabel,"default")==0 ) break;
686
+ if( zResult!=0 ) break;
687
+ zLabel = "default";
686688
}
687689
}
688690
return zResult;
689691
}
690692
@@ -691,11 +693,11 @@
691693
692694
/*
693695
** WEBPAGE: setup_skinedit
694696
**
695697
** Edit aspects of a skin determined by the w= query parameter.
696
-** Requires Setup privileges.
698
+** Requires Admin or Setup privileges.
697699
**
698700
** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details, 4=js
699701
** sk=NUM -- the draft skin number
700702
*/
701703
void setup_skinedit(void){
@@ -728,11 +730,11 @@
728730
/* Figure out which skin we are editing */
729731
iSkin = atoi(PD("sk","1"));
730732
if( iSkin<1 || iSkin>9 ) iSkin = 1;
731733
732734
/* Check that the user is authorized to edit this skin. */
733
- if( !g.perm.Setup ){
735
+ if( !g.perm.Admin ){
734736
char *zAllowedEditors = "";
735737
Glob *pAllowedEditors;
736738
int isMatch = 0;
737739
if( login_is_individual() ){
738740
zAllowedEditors = db_get_mprintf("", "draft%d-users", iSkin);
@@ -901,11 +903,11 @@
901903
if( !login_is_individual() ){
902904
login_needed(0);
903905
return;
904906
}
905907
zAllowedEditors = db_get_mprintf("", "draft%d-users", iSkin);
906
- if( g.perm.Setup ){
908
+ if( g.perm.Admin ){
907909
isSetup = isEditor = 1;
908910
}else{
909911
Glob *pAllowedEditors;
910912
isSetup = isEditor = 0;
911913
if( zAllowedEditors[0] ){
@@ -1055,11 +1057,11 @@
10551057
@ a production-ready skin.
10561058
@
10571059
@ <a name='step7'></a>
10581060
@ <h1>Step 7: Publish</h1>
10591061
@
1060
- if( !g.perm.Setup ){
1062
+ if( !g.perm.Admin ){
10611063
@ <p>Only administrators are allowed to publish draft skins. Contact
10621064
@ an administrator to get this "draft%d(iSkin)" skin published.</p>
10631065
}else{
10641066
@ <p>When the draft%d(iSkin) skin is ready for production use,
10651067
@ make it the default scan by clicking the acknowledgements and
@@ -1080,15 +1082,15 @@
10801082
}
10811083
@
10821084
@ <a name='step8'></a>
10831085
@ <h1>Step 8: Cleanup and Undo Actions</h1>
10841086
@
1085
- if( !g.perm.Setup ){
1087
+ if( !g.perm.Admin ){
10861088
@ <p>Administrators can optionally save or restore legacy skins, and/or
10871089
@ undo a prior publish.
10881090
}else{
10891091
@ <p>Visit the <a href='%R/setup_skin_admin'>Skin Admin</a> page
10901092
@ for cleanup and recovery actions.
10911093
}
10921094
style_load_one_js_file("skin.js");
10931095
style_footer();
10941096
}
10951097
--- src/skins.c
+++ src/skins.c
@@ -459,11 +459,11 @@
459 Stmt q;
460 int seenCurrent = 0;
461 int once;
462
463 login_check_credentials();
464 if( !g.perm.Setup ){
465 login_needed(0);
466 return;
467 }
468 db_begin_transaction();
469 zCurrent = getSkin(0);
@@ -676,15 +676,17 @@
676 if( fossil_strcmp(zLabel, "current")==0 ){
677 zResult = db_get(zFile, "");
678 }else if( sqlite3_strglob("draft[1-9]", zLabel)==0 ){
679 zResult = db_get_mprintf("", "%s-%s", zLabel, zFile);
680 }else{
681 while( 1 ){
 
682 char *zKey = mprintf("skins/%s/%s.txt", zLabel, zFile);
683 zResult = builtin_text(zKey);
684 fossil_free(zKey);
685 if( zResult!=0 || fossil_strcmp(zLabel,"default")==0 ) break;
 
686 }
687 }
688 return zResult;
689 }
690
@@ -691,11 +693,11 @@
691
692 /*
693 ** WEBPAGE: setup_skinedit
694 **
695 ** Edit aspects of a skin determined by the w= query parameter.
696 ** Requires Setup privileges.
697 **
698 ** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details, 4=js
699 ** sk=NUM -- the draft skin number
700 */
701 void setup_skinedit(void){
@@ -728,11 +730,11 @@
728 /* Figure out which skin we are editing */
729 iSkin = atoi(PD("sk","1"));
730 if( iSkin<1 || iSkin>9 ) iSkin = 1;
731
732 /* Check that the user is authorized to edit this skin. */
733 if( !g.perm.Setup ){
734 char *zAllowedEditors = "";
735 Glob *pAllowedEditors;
736 int isMatch = 0;
737 if( login_is_individual() ){
738 zAllowedEditors = db_get_mprintf("", "draft%d-users", iSkin);
@@ -901,11 +903,11 @@
901 if( !login_is_individual() ){
902 login_needed(0);
903 return;
904 }
905 zAllowedEditors = db_get_mprintf("", "draft%d-users", iSkin);
906 if( g.perm.Setup ){
907 isSetup = isEditor = 1;
908 }else{
909 Glob *pAllowedEditors;
910 isSetup = isEditor = 0;
911 if( zAllowedEditors[0] ){
@@ -1055,11 +1057,11 @@
1055 @ a production-ready skin.
1056 @
1057 @ <a name='step7'></a>
1058 @ <h1>Step 7: Publish</h1>
1059 @
1060 if( !g.perm.Setup ){
1061 @ <p>Only administrators are allowed to publish draft skins. Contact
1062 @ an administrator to get this "draft%d(iSkin)" skin published.</p>
1063 }else{
1064 @ <p>When the draft%d(iSkin) skin is ready for production use,
1065 @ make it the default scan by clicking the acknowledgements and
@@ -1080,15 +1082,15 @@
1080 }
1081 @
1082 @ <a name='step8'></a>
1083 @ <h1>Step 8: Cleanup and Undo Actions</h1>
1084 @
1085 if( !g.perm.Setup ){
1086 @ <p>Administrators can optionally save or restore legacy skins, and/or
1087 @ undo a prior publish.
1088 }else{
1089 @ <p>Visit the <a href='%R/setup_skin_admin'>Skin Admin</a> page
1090 @ for cleanup and recovery actions.
1091 }
1092 style_load_one_js_file("skin.js");
1093 style_footer();
1094 }
1095
--- src/skins.c
+++ src/skins.c
@@ -459,11 +459,11 @@
459 Stmt q;
460 int seenCurrent = 0;
461 int once;
462
463 login_check_credentials();
464 if( !g.perm.Admin ){
465 login_needed(0);
466 return;
467 }
468 db_begin_transaction();
469 zCurrent = getSkin(0);
@@ -676,15 +676,17 @@
676 if( fossil_strcmp(zLabel, "current")==0 ){
677 zResult = db_get(zFile, "");
678 }else if( sqlite3_strglob("draft[1-9]", zLabel)==0 ){
679 zResult = db_get_mprintf("", "%s-%s", zLabel, zFile);
680 }else{
681 int i;
682 for(i=0; i<2; i++){
683 char *zKey = mprintf("skins/%s/%s.txt", zLabel, zFile);
684 zResult = builtin_text(zKey);
685 fossil_free(zKey);
686 if( zResult!=0 ) break;
687 zLabel = "default";
688 }
689 }
690 return zResult;
691 }
692
@@ -691,11 +693,11 @@
693
694 /*
695 ** WEBPAGE: setup_skinedit
696 **
697 ** Edit aspects of a skin determined by the w= query parameter.
698 ** Requires Admin or Setup privileges.
699 **
700 ** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details, 4=js
701 ** sk=NUM -- the draft skin number
702 */
703 void setup_skinedit(void){
@@ -728,11 +730,11 @@
730 /* Figure out which skin we are editing */
731 iSkin = atoi(PD("sk","1"));
732 if( iSkin<1 || iSkin>9 ) iSkin = 1;
733
734 /* Check that the user is authorized to edit this skin. */
735 if( !g.perm.Admin ){
736 char *zAllowedEditors = "";
737 Glob *pAllowedEditors;
738 int isMatch = 0;
739 if( login_is_individual() ){
740 zAllowedEditors = db_get_mprintf("", "draft%d-users", iSkin);
@@ -901,11 +903,11 @@
903 if( !login_is_individual() ){
904 login_needed(0);
905 return;
906 }
907 zAllowedEditors = db_get_mprintf("", "draft%d-users", iSkin);
908 if( g.perm.Admin ){
909 isSetup = isEditor = 1;
910 }else{
911 Glob *pAllowedEditors;
912 isSetup = isEditor = 0;
913 if( zAllowedEditors[0] ){
@@ -1055,11 +1057,11 @@
1057 @ a production-ready skin.
1058 @
1059 @ <a name='step7'></a>
1060 @ <h1>Step 7: Publish</h1>
1061 @
1062 if( !g.perm.Admin ){
1063 @ <p>Only administrators are allowed to publish draft skins. Contact
1064 @ an administrator to get this "draft%d(iSkin)" skin published.</p>
1065 }else{
1066 @ <p>When the draft%d(iSkin) skin is ready for production use,
1067 @ make it the default scan by clicking the acknowledgements and
@@ -1080,15 +1082,15 @@
1082 }
1083 @
1084 @ <a name='step8'></a>
1085 @ <h1>Step 8: Cleanup and Undo Actions</h1>
1086 @
1087 if( !g.perm.Admin ){
1088 @ <p>Administrators can optionally save or restore legacy skins, and/or
1089 @ undo a prior publish.
1090 }else{
1091 @ <p>Visit the <a href='%R/setup_skin_admin'>Skin Admin</a> page
1092 @ for cleanup and recovery actions.
1093 }
1094 style_load_one_js_file("skin.js");
1095 style_footer();
1096 }
1097
+18 -7
--- src/smtp.c
+++ src/smtp.c
@@ -19,15 +19,27 @@
1919
** to RFC 5321.
2020
*/
2121
#include "config.h"
2222
#include "smtp.h"
2323
#include <assert.h>
24
-#if defined(__linux__) && !defined(FOSSIL_OMIT_DNS)
24
+#if (HAVE_DN_EXPAND || HAVE___NS_NAME_UNCOMPRESS || HAVE_NS_NAME_UNCOMPRESS) && \
25
+ (HAVE_NS_PARSERR || HAVE___NS_PARSERR) && !defined(FOSSIL_OMIT_DNS)
2526
# include <sys/types.h>
2627
# include <netinet/in.h>
27
-# include <arpa/nameser.h>
28
-# include <resolv.h>
28
+# if defined(HAVE_BIND_RESOLV_H)
29
+# include <bind/resolv.h>
30
+# include <bind/arpa/nameser_compat.h>
31
+# else
32
+# include <arpa/nameser.h>
33
+# include <resolv.h>
34
+# endif
35
+# if defined(HAVENS_NAME_UNCOMPRESS) && !defined(dn_expand)
36
+# define dn_expand ns_name_uncompress
37
+# endif
38
+# if defined(HAVE__NS_NAME_UNCOMPRESS) && !defined(dn_expand)
39
+# define dn_expand __ns_name_uncompress
40
+# endif
2941
# define FOSSIL_UNIX_STYLE_DNS 1
3042
#endif
3143
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
3244
# include <windows.h>
3345
# include <windns.h>
@@ -77,12 +89,11 @@
7789
iBestPriority = priority;
7890
}
7991
}
8092
}
8193
if( pBest ){
82
- ns_name_uncompress(aDns, aDns+nDns, pBest+2,
83
- zHostname, sizeof(zHostname));
94
+ dn_expand(aDns, aDns+nDns, pBest+2, zHostname, sizeof(zHostname));
8495
return fossil_strdup(zHostname);
8596
}
8697
return 0;
8798
#elif defined(FOSSIL_WINDOWS_STYLE_DNS)
8899
DNS_STATUS status; /* Return status */
@@ -1299,11 +1310,11 @@
12991310
}
13001311
}
13011312
13021313
13031314
/*
1304
-** COMMAND: smtpd
1315
+** COMMAND: smtpd*
13051316
**
13061317
** Usage: %fossil smtpd [OPTIONS] REPOSITORY
13071318
**
13081319
** Begin a SMTP conversation with a client using stdin/stdout. The
13091320
** received email is stored in REPOSITORY.
@@ -1446,11 +1457,11 @@
14461457
static int pop3_login(const char *zUser, char *zPass){
14471458
return login_search_uid(&zUser, zPass) != 0;
14481459
}
14491460
14501461
/*
1451
-** COMMAND: pop3d
1462
+** COMMAND: pop3d*
14521463
**
14531464
** Usage: %fossil pop3d [OPTIONS] REPOSITORY
14541465
**
14551466
** Begin a POP3 conversation with a client using stdin/stdout using
14561467
** the mailboxes stored in REPOSITORY.
14571468
--- src/smtp.c
+++ src/smtp.c
@@ -19,15 +19,27 @@
19 ** to RFC 5321.
20 */
21 #include "config.h"
22 #include "smtp.h"
23 #include <assert.h>
24 #if defined(__linux__) && !defined(FOSSIL_OMIT_DNS)
 
25 # include <sys/types.h>
26 # include <netinet/in.h>
27 # include <arpa/nameser.h>
28 # include <resolv.h>
 
 
 
 
 
 
 
 
 
 
 
29 # define FOSSIL_UNIX_STYLE_DNS 1
30 #endif
31 #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
32 # include <windows.h>
33 # include <windns.h>
@@ -77,12 +89,11 @@
77 iBestPriority = priority;
78 }
79 }
80 }
81 if( pBest ){
82 ns_name_uncompress(aDns, aDns+nDns, pBest+2,
83 zHostname, sizeof(zHostname));
84 return fossil_strdup(zHostname);
85 }
86 return 0;
87 #elif defined(FOSSIL_WINDOWS_STYLE_DNS)
88 DNS_STATUS status; /* Return status */
@@ -1299,11 +1310,11 @@
1299 }
1300 }
1301
1302
1303 /*
1304 ** COMMAND: smtpd
1305 **
1306 ** Usage: %fossil smtpd [OPTIONS] REPOSITORY
1307 **
1308 ** Begin a SMTP conversation with a client using stdin/stdout. The
1309 ** received email is stored in REPOSITORY.
@@ -1446,11 +1457,11 @@
1446 static int pop3_login(const char *zUser, char *zPass){
1447 return login_search_uid(&zUser, zPass) != 0;
1448 }
1449
1450 /*
1451 ** COMMAND: pop3d
1452 **
1453 ** Usage: %fossil pop3d [OPTIONS] REPOSITORY
1454 **
1455 ** Begin a POP3 conversation with a client using stdin/stdout using
1456 ** the mailboxes stored in REPOSITORY.
1457
--- src/smtp.c
+++ src/smtp.c
@@ -19,15 +19,27 @@
19 ** to RFC 5321.
20 */
21 #include "config.h"
22 #include "smtp.h"
23 #include <assert.h>
24 #if (HAVE_DN_EXPAND || HAVE___NS_NAME_UNCOMPRESS || HAVE_NS_NAME_UNCOMPRESS) && \
25 (HAVE_NS_PARSERR || HAVE___NS_PARSERR) && !defined(FOSSIL_OMIT_DNS)
26 # include <sys/types.h>
27 # include <netinet/in.h>
28 # if defined(HAVE_BIND_RESOLV_H)
29 # include <bind/resolv.h>
30 # include <bind/arpa/nameser_compat.h>
31 # else
32 # include <arpa/nameser.h>
33 # include <resolv.h>
34 # endif
35 # if defined(HAVENS_NAME_UNCOMPRESS) && !defined(dn_expand)
36 # define dn_expand ns_name_uncompress
37 # endif
38 # if defined(HAVE__NS_NAME_UNCOMPRESS) && !defined(dn_expand)
39 # define dn_expand __ns_name_uncompress
40 # endif
41 # define FOSSIL_UNIX_STYLE_DNS 1
42 #endif
43 #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
44 # include <windows.h>
45 # include <windns.h>
@@ -77,12 +89,11 @@
89 iBestPriority = priority;
90 }
91 }
92 }
93 if( pBest ){
94 dn_expand(aDns, aDns+nDns, pBest+2, zHostname, sizeof(zHostname));
 
95 return fossil_strdup(zHostname);
96 }
97 return 0;
98 #elif defined(FOSSIL_WINDOWS_STYLE_DNS)
99 DNS_STATUS status; /* Return status */
@@ -1299,11 +1310,11 @@
1310 }
1311 }
1312
1313
1314 /*
1315 ** COMMAND: smtpd*
1316 **
1317 ** Usage: %fossil smtpd [OPTIONS] REPOSITORY
1318 **
1319 ** Begin a SMTP conversation with a client using stdin/stdout. The
1320 ** received email is stored in REPOSITORY.
@@ -1446,11 +1457,11 @@
1457 static int pop3_login(const char *zUser, char *zPass){
1458 return login_search_uid(&zUser, zPass) != 0;
1459 }
1460
1461 /*
1462 ** COMMAND: pop3d*
1463 **
1464 ** Usage: %fossil pop3d [OPTIONS] REPOSITORY
1465 **
1466 ** Begin a POP3 conversation with a client using stdin/stdout using
1467 ** the mailboxes stored in REPOSITORY.
1468
+2017 -647
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.25.2. By combining all the individual C code files into this
3
+** version 3.26.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -257,10 +257,13 @@
257257
#if SQLITE_ENABLE_FTS4
258258
"ENABLE_FTS4",
259259
#endif
260260
#if SQLITE_ENABLE_FTS5
261261
"ENABLE_FTS5",
262
+#endif
263
+#if SQLITE_ENABLE_GEOPOLY
264
+ "ENABLE_GEOPOLY",
262265
#endif
263266
#if SQLITE_ENABLE_HIDDEN_COLUMNS
264267
"ENABLE_HIDDEN_COLUMNS",
265268
#endif
266269
#if SQLITE_ENABLE_ICU
@@ -287,10 +290,13 @@
287290
#if SQLITE_ENABLE_MEMSYS5
288291
"ENABLE_MEMSYS5",
289292
#endif
290293
#if SQLITE_ENABLE_MULTIPLEX
291294
"ENABLE_MULTIPLEX",
295
+#endif
296
+#if SQLITE_ENABLE_NORMALIZE
297
+ "ENABLE_NORMALIZE",
292298
#endif
293299
#if SQLITE_ENABLE_NULL_TRIM
294300
"ENABLE_NULL_TRIM",
295301
#endif
296302
#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
@@ -1154,13 +1160,13 @@
11541160
**
11551161
** See also: [sqlite3_libversion()],
11561162
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
11571163
** [sqlite_version()] and [sqlite_source_id()].
11581164
*/
1159
-#define SQLITE_VERSION "3.25.2"
1160
-#define SQLITE_VERSION_NUMBER 3025002
1161
-#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
1165
+#define SQLITE_VERSION "3.26.0"
1166
+#define SQLITE_VERSION_NUMBER 3026000
1167
+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
11621168
11631169
/*
11641170
** CAPI3REF: Run-Time Library Version Numbers
11651171
** KEYWORDS: sqlite3_version sqlite3_sourceid
11661172
**
@@ -3048,10 +3054,11 @@
30483054
** the call worked. ^The [sqlite3_db_config()] interface will return a
30493055
** non-zero [error code] if a discontinued or unsupported configuration option
30503056
** is invoked.
30513057
**
30523058
** <dl>
3059
+** [[SQLITE_DBCONFIG_LOOKASIDE]]
30533060
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
30543061
** <dd> ^This option takes three additional arguments that determine the
30553062
** [lookaside memory allocator] configuration for the [database connection].
30563063
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
30573064
** pointer to a memory buffer to use for lookaside memory.
@@ -3070,10 +3077,11 @@
30703077
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
30713078
** Any attempt to change the lookaside memory configuration when lookaside
30723079
** memory is in use leaves the configuration unchanged and returns
30733080
** [SQLITE_BUSY].)^</dd>
30743081
**
3082
+** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
30753083
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
30763084
** <dd> ^This option is used to enable or disable the enforcement of
30773085
** [foreign key constraints]. There should be two additional arguments.
30783086
** The first argument is an integer which is 0 to disable FK enforcement,
30793087
** positive to enable FK enforcement or negative to leave FK enforcement
@@ -3080,10 +3088,11 @@
30803088
** unchanged. The second parameter is a pointer to an integer into which
30813089
** is written 0 or 1 to indicate whether FK enforcement is off or on
30823090
** following this call. The second parameter may be a NULL pointer, in
30833091
** which case the FK enforcement setting is not reported back. </dd>
30843092
**
3093
+** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
30853094
** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
30863095
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
30873096
** There should be two additional arguments.
30883097
** The first argument is an integer which is 0 to disable triggers,
30893098
** positive to enable triggers or negative to leave the setting unchanged.
@@ -3090,10 +3099,11 @@
30903099
** The second parameter is a pointer to an integer into which
30913100
** is written 0 or 1 to indicate whether triggers are disabled or enabled
30923101
** following this call. The second parameter may be a NULL pointer, in
30933102
** which case the trigger setting is not reported back. </dd>
30943103
**
3104
+** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
30953105
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
30963106
** <dd> ^This option is used to enable or disable the two-argument
30973107
** version of the [fts3_tokenizer()] function which is part of the
30983108
** [FTS3] full-text search engine extension.
30993109
** There should be two additional arguments.
@@ -3103,10 +3113,11 @@
31033113
** The second parameter is a pointer to an integer into which
31043114
** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
31053115
** following this call. The second parameter may be a NULL pointer, in
31063116
** which case the new setting is not reported back. </dd>
31073117
**
3118
+** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
31083119
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
31093120
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
31103121
** interface independently of the [load_extension()] SQL function.
31113122
** The [sqlite3_enable_load_extension()] API enables or disables both the
31123123
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -3120,19 +3131,20 @@
31203131
** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
31213132
** is disabled or enabled following this call. The second parameter may
31223133
** be a NULL pointer, in which case the new setting is not reported back.
31233134
** </dd>
31243135
**
3125
-** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
3136
+** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
31263137
** <dd> ^This option is used to change the name of the "main" database
31273138
** schema. ^The sole argument is a pointer to a constant UTF8 string
31283139
** which will become the new schema name in place of "main". ^SQLite
31293140
** does not make a copy of the new main schema name string, so the application
31303141
** must ensure that the argument passed into this DBCONFIG option is unchanged
31313142
** until after the database connection closes.
31323143
** </dd>
31333144
**
3145
+** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
31343146
** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
31353147
** <dd> Usually, when a database in wal mode is closed or detached from a
31363148
** database handle, SQLite checks if this will mean that there are now no
31373149
** connections at all to the database. If so, it performs a checkpoint
31383150
** operation before closing the connection. This option may be used to
@@ -3142,11 +3154,11 @@
31423154
** The second parameter is a pointer to an integer
31433155
** into which is written 0 or 1 to indicate whether checkpoints-on-close
31443156
** have been disabled - 0 if they are not disabled, 1 if they are.
31453157
** </dd>
31463158
**
3147
-** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
3159
+** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
31483160
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
31493161
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
31503162
** a single SQL query statement will always use the same algorithm regardless
31513163
** of values of [bound parameters].)^ The QPSG disables some query optimizations
31523164
** that look at the values of bound parameters, which can make some queries
@@ -3158,11 +3170,11 @@
31583170
** unchanged. The second parameter is a pointer to an integer into which
31593171
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
31603172
** following this call.
31613173
** </dd>
31623174
**
3163
-** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
3175
+** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
31643176
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
31653177
** include output for any operations performed by trigger programs. This
31663178
** option is used to set or clear (the default) a flag that governs this
31673179
** behavior. The first parameter passed to this operation is an integer -
31683180
** positive to enable output for trigger programs, or zero to disable it,
@@ -3170,11 +3182,11 @@
31703182
** The second parameter is a pointer to an integer into which is written
31713183
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
31723184
** it is not disabled, 1 if it is.
31733185
** </dd>
31743186
**
3175
-** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
3187
+** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
31763188
** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
31773189
** [VACUUM] in order to reset a database back to an empty database
31783190
** with no schema and no content. The following process works even for
31793191
** a badly corrupted database file:
31803192
** <ol>
@@ -3189,10 +3201,22 @@
31893201
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
31903202
** </ol>
31913203
** Because resetting a database is destructive and irreversible, the
31923204
** process requires the use of this obscure API and multiple steps to help
31933205
** ensure that it does not happen by accident.
3206
+**
3207
+** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
3208
+** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
3209
+** "defensive" flag for a database connection. When the defensive
3210
+** flag is enabled, language features that allow ordinary SQL to
3211
+** deliberately corrupt the database file are disabled. The disabled
3212
+** features include but are not limited to the following:
3213
+** <ul>
3214
+** <li> The [PRAGMA writable_schema=ON] statement.
3215
+** <li> Writes to the [sqlite_dbpage] virtual table.
3216
+** <li> Direct writes to [shadow tables].
3217
+** </ul>
31943218
** </dd>
31953219
** </dl>
31963220
*/
31973221
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
31983222
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -3202,11 +3226,12 @@
32023226
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
32033227
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
32043228
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
32053229
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
32063230
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
3207
-#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
3231
+#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
3232
+#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
32083233
32093234
/*
32103235
** CAPI3REF: Enable Or Disable Extended Result Codes
32113236
** METHOD: sqlite3
32123237
**
@@ -4640,13 +4665,23 @@
46404665
** be used just once or at most a few times and then destroyed using
46414666
** [sqlite3_finalize()] relatively soon. The current implementation acts
46424667
** on this hint by avoiding the use of [lookaside memory] so as not to
46434668
** deplete the limited store of lookaside memory. Future versions of
46444669
** SQLite may act on this hint differently.
4670
+**
4671
+** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
4672
+** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
4673
+** representation of the SQL statement should be calculated and then
4674
+** associated with the prepared statement, which can be obtained via
4675
+** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
4676
+** normalize a SQL statement are unspecified and subject to change.
4677
+** At a minimum, literal values will be replaced with suitable
4678
+** placeholders.
46454679
** </dl>
46464680
*/
46474681
#define SQLITE_PREPARE_PERSISTENT 0x01
4682
+#define SQLITE_PREPARE_NORMALIZE 0x02
46484683
46494684
/*
46504685
** CAPI3REF: Compiling An SQL Statement
46514686
** KEYWORDS: {SQL statement compiler}
46524687
** METHOD: sqlite3
@@ -4800,10 +4835,15 @@
48004835
** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
48014836
** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
48024837
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
48034838
** string containing the SQL text of prepared statement P with
48044839
** [bound parameters] expanded.
4840
+** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
4841
+** string containing the normalized SQL text of prepared statement P. The
4842
+** semantics used to normalize a SQL statement are unspecified and subject
4843
+** to change. At a minimum, literal values will be replaced with suitable
4844
+** placeholders.
48054845
**
48064846
** ^(For example, if a prepared statement is created using the SQL
48074847
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
48084848
** and parameter :xyz is unbound, then sqlite3_sql() will return
48094849
** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -4815,18 +4855,20 @@
48154855
**
48164856
** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
48174857
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
48184858
** option causes sqlite3_expanded_sql() to always return NULL.
48194859
**
4820
-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
4821
-** automatically freed when the prepared statement is finalized.
4860
+** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
4861
+** are managed by SQLite and are automatically freed when the prepared
4862
+** statement is finalized.
48224863
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
48234864
** is obtained from [sqlite3_malloc()] and must be free by the application
48244865
** by passing it to [sqlite3_free()].
48254866
*/
48264867
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
48274868
SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
4869
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
48284870
48294871
/*
48304872
** CAPI3REF: Determine If An SQL Statement Writes The Database
48314873
** METHOD: sqlite3_stmt
48324874
**
@@ -7312,10 +7354,13 @@
73127354
/* The methods above are in version 1 of the sqlite_module object. Those
73137355
** below are for version 2 and greater. */
73147356
int (*xSavepoint)(sqlite3_vtab *pVTab, int);
73157357
int (*xRelease)(sqlite3_vtab *pVTab, int);
73167358
int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
7359
+ /* The methods above are in versions 1 and 2 of the sqlite_module object.
7360
+ ** Those below are for version 3 and greater. */
7361
+ int (*xShadowName)(const char*);
73177362
};
73187363
73197364
/*
73207365
** CAPI3REF: Virtual Table Indexing Information
73217366
** KEYWORDS: sqlite3_index_info
@@ -8234,10 +8279,11 @@
82348279
#define SQLITE_TESTCTRL_ALWAYS 13
82358280
#define SQLITE_TESTCTRL_RESERVE 14
82368281
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
82378282
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
82388283
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8284
+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
82398285
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
82408286
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
82418287
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
82428288
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
82438289
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -9646,10 +9692,11 @@
96469692
** These macros define the various options to the
96479693
** [sqlite3_vtab_config()] interface that [virtual table] implementations
96489694
** can use to customize and optimize their behavior.
96499695
**
96509696
** <dl>
9697
+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
96519698
** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
96529699
** <dd>Calls of the form
96539700
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
96549701
** where X is an integer. If X is zero, then the [virtual table] whose
96559702
** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -10415,11 +10462,11 @@
1041510462
int iLevel; /* Level of current node or entry */
1041610463
int mxLevel; /* The largest iLevel value in the tree */
1041710464
sqlite3_int64 iRowid; /* Rowid for current entry */
1041810465
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
1041910466
int eParentWithin; /* Visibility of parent node */
10420
- int eWithin; /* OUT: Visiblity */
10467
+ int eWithin; /* OUT: Visibility */
1042110468
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
1042210469
/* The following fields are only available in 3.8.11 and later */
1042310470
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
1042410471
};
1042510472
@@ -10911,16 +10958,42 @@
1091110958
** an application iterates through a changeset using an iterator created by
1091210959
** this function, all changes that relate to a single table are visited
1091310960
** consecutively. There is no chance that the iterator will visit a change
1091410961
** the applies to table X, then one for table Y, and then later on visit
1091510962
** another change for table X.
10963
+**
10964
+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
10965
+** may be modified by passing a combination of
10966
+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
10967
+**
10968
+** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
10969
+** and therefore subject to change.
1091610970
*/
1091710971
SQLITE_API int sqlite3changeset_start(
1091810972
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
1091910973
int nChangeset, /* Size of changeset blob in bytes */
1092010974
void *pChangeset /* Pointer to blob containing changeset */
1092110975
);
10976
+SQLITE_API int sqlite3changeset_start_v2(
10977
+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
10978
+ int nChangeset, /* Size of changeset blob in bytes */
10979
+ void *pChangeset, /* Pointer to blob containing changeset */
10980
+ int flags /* SESSION_CHANGESETSTART_* flags */
10981
+);
10982
+
10983
+/*
10984
+** CAPI3REF: Flags for sqlite3changeset_start_v2
10985
+**
10986
+** The following flags may passed via the 4th parameter to
10987
+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
10988
+**
10989
+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
10990
+** Invert the changeset while iterating through it. This is equivalent to
10991
+** inverting a changeset using sqlite3changeset_invert() before applying it.
10992
+** It is an error to specify this flag with a patchset.
10993
+*/
10994
+#define SQLITE_CHANGESETSTART_INVERT 0x0002
1092210995
1092310996
1092410997
/*
1092510998
** CAPI3REF: Advance A Changeset Iterator
1092610999
** METHOD: sqlite3_changeset_iter
@@ -11571,11 +11644,11 @@
1157111644
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
1157211645
sqlite3_changeset_iter *p /* Handle describing change and conflict */
1157311646
),
1157411647
void *pCtx, /* First argument passed to xConflict */
1157511648
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
11576
- int flags /* Combination of SESSION_APPLY_* flags */
11649
+ int flags /* SESSION_CHANGESETAPPLY_* flags */
1157711650
);
1157811651
1157911652
/*
1158011653
** CAPI3REF: Flags for sqlite3changeset_apply_v2
1158111654
**
@@ -11589,12 +11662,18 @@
1158911662
** SAVEPOINT is committed if the changeset or patchset is successfully
1159011663
** applied, or rolled back if an error occurs. Specifying this flag
1159111664
** causes the sessions module to omit this savepoint. In this case, if the
1159211665
** caller has an open transaction or savepoint when apply_v2() is called,
1159311666
** it may revert the partially applied changeset by rolling it back.
11667
+**
11668
+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
11669
+** Invert the changeset before applying it. This is equivalent to inverting
11670
+** a changeset using sqlite3changeset_invert() before applying it. It is
11671
+** an error to specify this flag with a patchset.
1159411672
*/
1159511673
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
11674
+#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
1159611675
1159711676
/*
1159811677
** CAPI3REF: Constants Passed To The Conflict Handler
1159911678
**
1160011679
** Values that may be passed as the second argument to a conflict-handler.
@@ -11983,10 +12062,16 @@
1198312062
);
1198412063
SQLITE_API int sqlite3changeset_start_strm(
1198512064
sqlite3_changeset_iter **pp,
1198612065
int (*xInput)(void *pIn, void *pData, int *pnData),
1198712066
void *pIn
12067
+);
12068
+SQLITE_API int sqlite3changeset_start_v2_strm(
12069
+ sqlite3_changeset_iter **pp,
12070
+ int (*xInput)(void *pIn, void *pData, int *pnData),
12071
+ void *pIn,
12072
+ int flags
1198812073
);
1198912074
SQLITE_API int sqlite3session_changeset_strm(
1199012075
sqlite3_session *pSession,
1199112076
int (*xOutput)(void *pOut, const void *pData, int nData),
1199212077
void *pOut
@@ -12010,10 +12095,49 @@
1201012095
void *pIn,
1201112096
int (*xOutput)(void *pOut, const void *pData, int nData),
1201212097
void *pOut
1201312098
);
1201412099
12100
+/*
12101
+** CAPI3REF: Configure global parameters
12102
+**
12103
+** The sqlite3session_config() interface is used to make global configuration
12104
+** changes to the sessions module in order to tune it to the specific needs
12105
+** of the application.
12106
+**
12107
+** The sqlite3session_config() interface is not threadsafe. If it is invoked
12108
+** while any other thread is inside any other sessions method then the
12109
+** results are undefined. Furthermore, if it is invoked after any sessions
12110
+** related objects have been created, the results are also undefined.
12111
+**
12112
+** The first argument to the sqlite3session_config() function must be one
12113
+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
12114
+** interpretation of the (void*) value passed as the second parameter and
12115
+** the effect of calling this function depends on the value of the first
12116
+** parameter.
12117
+**
12118
+** <dl>
12119
+** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
12120
+** By default, the sessions module streaming interfaces attempt to input
12121
+** and output data in approximately 1 KiB chunks. This operand may be used
12122
+** to set and query the value of this configuration setting. The pointer
12123
+** passed as the second argument must point to a value of type (int).
12124
+** If this value is greater than 0, it is used as the new streaming data
12125
+** chunk size for both input and output. Before returning, the (int) value
12126
+** pointed to by pArg is set to the final value of the streaming interface
12127
+** chunk size.
12128
+** </dl>
12129
+**
12130
+** This function returns SQLITE_OK if successful, or an SQLite error code
12131
+** otherwise.
12132
+*/
12133
+SQLITE_API int sqlite3session_config(int op, void *pArg);
12134
+
12135
+/*
12136
+** CAPI3REF: Values for sqlite3session_config().
12137
+*/
12138
+#define SQLITE_SESSION_CONFIG_STRMSIZE 1
1201512139
1201612140
/*
1201712141
** Make sure we can call this stuff from C++.
1201812142
*/
1201912143
#if 0
@@ -15275,22 +15399,21 @@
1527515399
SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
1527615400
SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
1527715401
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
1527815402
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
1527915403
SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
15280
-# ifdef SQLITE_DIRECT_OVERFLOW_READ
15281
-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno);
15282
-# endif
1528315404
# ifdef SQLITE_ENABLE_SNAPSHOT
1528415405
SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
1528515406
SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
1528615407
SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
1528715408
SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
1528815409
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
1528915410
# endif
15290
-#else
15291
-# define sqlite3PagerUseWal(x,y) 0
15411
+#endif
15412
+
15413
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
15414
+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
1529215415
#endif
1529315416
1529415417
#ifdef SQLITE_ENABLE_ZIPVFS
1529515418
SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
1529615419
#endif
@@ -15530,10 +15653,14 @@
1553015653
SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
1553115654
SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
1553215655
1553315656
/* Number of dirty pages as a percentage of the configured cache size */
1553415657
SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
15658
+
15659
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
15660
+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
15661
+#endif
1553515662
1553615663
#endif /* _PCACHE_H_ */
1553715664
1553815665
/************** End of pcache.h **********************************************/
1553915666
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -16036,16 +16163,18 @@
1603616163
/*
1603716164
** A hash table for built-in function definitions. (Application-defined
1603816165
** functions use a regular table table from hash.h.)
1603916166
**
1604016167
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
16041
-** Collisions are on the FuncDef.u.pHash chain.
16168
+** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH()
16169
+** macro to compute a hash on the function name.
1604216170
*/
1604316171
#define SQLITE_FUNC_HASH_SZ 23
1604416172
struct FuncDefHash {
1604516173
FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
1604616174
};
16175
+#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
1604716176
1604816177
#ifdef SQLITE_USER_AUTHENTICATION
1604916178
/*
1605016179
** Information held in the "sqlite3" database connection object and used
1605116180
** to manage user authentication.
@@ -16102,11 +16231,11 @@
1610216231
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
1610316232
sqlite3_mutex *mutex; /* Connection mutex */
1610416233
Db *aDb; /* All backends */
1610516234
int nDb; /* Number of backends currently in use */
1610616235
u32 mDbFlags; /* flags recording internal state */
16107
- u32 flags; /* flags settable by pragmas. See below */
16236
+ u64 flags; /* flags settable by pragmas. See below */
1610816237
i64 lastRowid; /* ROWID of most recent insert (see above) */
1610916238
i64 szMmap; /* Default mmap_size setting */
1611016239
u32 nSchemaLock; /* Do not reset the schema when non-zero */
1611116240
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
1611216241
int errCode; /* Most recent error code (SQLITE_*) */
@@ -16268,18 +16397,21 @@
1626816397
#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
1626916398
#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
1627016399
#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
1627116400
#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
1627216401
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
16402
+#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
16403
+#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
1627316404
1627416405
/* Flags used only if debugging */
16406
+#define HI(X) ((u64)(X)<<32)
1627516407
#ifdef SQLITE_DEBUG
16276
-#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
16277
-#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */
16278
-#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */
16279
-#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */
16280
-#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
16408
+#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
16409
+#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
16410
+#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
16411
+#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
16412
+#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
1628116413
#endif
1628216414
1628316415
/*
1628416416
** Allowed values for sqlite3.mDbFlags
1628516417
*/
@@ -16409,12 +16541,13 @@
1640916541
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
1641016542
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
1641116543
** single query - might change over time */
1641216544
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
1641316545
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
16414
-#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */
16415
-#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
16546
+#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
16547
+#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
16548
+#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
1641616549
1641716550
/*
1641816551
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
1641916552
** used to create the initializers for the FuncDef structures.
1642016553
**
@@ -16486,14 +16619,17 @@
1648616619
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
1648716620
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
1648816621
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
1648916622
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
1649016623
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
16491
-
1649216624
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
1649316625
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
1649416626
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
16627
+#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
16628
+ {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
16629
+ 0, 0, xFunc, 0, 0, 0, #zName, {0} }
16630
+
1649516631
1649616632
/*
1649716633
** All current savepoints are stored in a linked list starting at
1649816634
** sqlite3.pSavepoint. The first element in the list is the most recently
1649916635
** opened savepoint. Savepoints are added to the list by the vdbe
@@ -16674,10 +16810,13 @@
1667416810
** by an instance of the following structure.
1667516811
*/
1667616812
struct Table {
1667716813
char *zName; /* Name of the table or view */
1667816814
Column *aCol; /* Information about each column */
16815
+#ifdef SQLITE_ENABLE_NORMALIZE
16816
+ Hash *pColHash; /* All columns indexed by name */
16817
+#endif
1667916818
Index *pIndex; /* List of SQL indexes on this table. */
1668016819
Select *pSelect; /* NULL for tables. Points to definition if a view. */
1668116820
FKey *pFKey; /* Linked list of all foreign keys in this table */
1668216821
char *zColAff; /* String defining the affinity of each column */
1668316822
ExprList *pCheck; /* All CHECK constraints */
@@ -16724,10 +16863,11 @@
1672416863
#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
1672516864
#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
1672616865
#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
1672716866
** Index.aiRowLogEst[] values */
1672816867
#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
16868
+#define TF_Shadow 0x0400 /* True for a shadow table */
1672916869
1673016870
/*
1673116871
** Test to see whether or not a table is a virtual table. This is
1673216872
** done as a macro so that it will be optimized out when virtual
1673316873
** table support is omitted from the build.
@@ -17010,10 +17150,16 @@
1701017150
tRowcnt *anEq; /* Est. number of rows where the key equals this sample */
1701117151
tRowcnt *anLt; /* Est. number of rows where key is less than this sample */
1701217152
tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
1701317153
};
1701417154
17155
+/*
17156
+** Possible values to use within the flags argument to sqlite3GetToken().
17157
+*/
17158
+#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */
17159
+#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */
17160
+
1701517161
/*
1701617162
** Each token coming out of the lexer is an instance of
1701717163
** this structure. Tokens are also used as part of an expression.
1701817164
**
1701917165
** The memory that "z" points to is owned by other objects. Take care
@@ -17191,15 +17337,15 @@
1719117337
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
1719217338
u8 op2; /* TK_REGISTER: original value of Expr.op
1719317339
** TK_COLUMN: the value of p5 for OP_Column
1719417340
** TK_AGG_FUNCTION: nesting depth */
1719517341
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
17196
- Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
17197
- ** for a column of an index on an expression */
17198
-#ifndef SQLITE_OMIT_WINDOWFUNC
17199
- Window *pWin; /* Window definition for window functions */
17200
-#endif
17342
+ union {
17343
+ Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
17344
+ ** for a column of an index on an expression */
17345
+ Window *pWin; /* TK_FUNCTION: Window definition for the func */
17346
+ } y;
1720117347
};
1720217348
1720317349
/*
1720417350
** The following are the meanings of bits in the Expr.flags field.
1720517351
*/
@@ -17225,10 +17371,11 @@
1722517371
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
1722617372
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
1722717373
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
1722817374
#define EP_Alias 0x400000 /* Is an alias for a result set column */
1722917375
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
17376
+#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
1723017377
1723117378
/*
1723217379
** The EP_Propagate mask is a set of properties that automatically propagate
1723317380
** upwards into parent nodes.
1723417381
*/
@@ -17910,10 +18057,11 @@
1791018057
** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
1791118058
** OPFLAG_AUXDELETE == BTREE_AUXDELETE
1791218059
*/
1791318060
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
1791418061
/* Also used in P2 (not P5) of OP_Delete */
18062
+#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */
1791518063
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
1791618064
#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
1791718065
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
1791818066
#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
1791918067
#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
@@ -18128,10 +18276,11 @@
1812818276
#endif
1812918277
#ifndef SQLITE_UNTESTABLE
1813018278
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
1813118279
#endif
1813218280
int bLocaltimeFault; /* True to fail localtime() calls */
18281
+ int bInternalFunctions; /* Internal SQL functions are visible */
1813318282
int iOnceResetThreshold; /* When to reset OP_Once counters */
1813418283
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
1813518284
};
1813618285
1813718286
/*
@@ -18381,10 +18530,11 @@
1838118530
/*
1838218531
** Internal function prototypes
1838318532
*/
1838418533
SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
1838518534
SQLITE_PRIVATE int sqlite3Strlen30(const char*);
18535
+#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
1838618536
SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
1838718537
#define sqlite3StrNICmp sqlite3_strnicmp
1838818538
1838918539
SQLITE_PRIVATE int sqlite3MallocInit(void);
1839018540
SQLITE_PRIVATE void sqlite3MallocEnd(void);
@@ -18497,10 +18647,11 @@
1849718647
1849818648
#if defined(SQLITE_DEBUG)
1849918649
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
1850018650
SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
1850118651
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
18652
+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
1850218653
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
1850318654
SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
1850418655
#ifndef SQLITE_OMIT_WINDOWFUNC
1850518656
SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
1850618657
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
@@ -18729,15 +18880,19 @@
1872918880
#endif
1873018881
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
1873118882
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
1873218883
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
1873318884
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
18885
+#ifdef SQLITE_ENABLE_NORMALIZE
18886
+SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int);
18887
+#endif
1873418888
SQLITE_PRIVATE void sqlite3GenerateRowDelete(
1873518889
Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
1873618890
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
1873718891
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
1873818892
SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
18893
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
1873918894
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
1874018895
u8,u8,int,int*,int*,Upsert*);
1874118896
#ifdef SQLITE_ENABLE_NULL_TRIM
1874218897
SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
1874318898
#else
@@ -18754,10 +18909,13 @@
1875418909
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
1875518910
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
1875618911
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
1875718912
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
1875818913
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
18914
+#ifdef SQLITE_ENABLE_NORMALIZE
18915
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int);
18916
+#endif
1875918917
SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
1876018918
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
1876118919
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
1876218920
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
1876318921
SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
@@ -18911,10 +19069,11 @@
1891119069
SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
1891219070
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
1891319071
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
1891419072
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
1891519073
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
19074
+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*);
1891619075
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
1891719076
SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
1891819077
SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
1891919078
SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
1892019079
SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64);
@@ -18957,10 +19116,13 @@
1895719116
SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
1895819117
SQLITE_PRIVATE void sqlite3AlterFunctions(void);
1895919118
SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
1896019119
SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
1896119120
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
19121
+#ifdef SQLITE_ENABLE_NORMALIZE
19122
+SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
19123
+#endif
1896219124
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
1896319125
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
1896419126
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
1896519127
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
1896619128
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
@@ -19114,10 +19276,13 @@
1911419276
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
1911519277
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
1911619278
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
1911719279
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
1911819280
SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
19281
+#ifdef SQLITE_ENABLE_NORMALIZE
19282
+SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8);
19283
+#endif
1911919284
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
1912019285
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
1912119286
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
1912219287
SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
1912319288
SQLITE_PRIVATE const char *sqlite3JournalModename(int);
@@ -19575,10 +19740,11 @@
1957519740
#endif
1957619741
#ifndef SQLITE_UNTESTABLE
1957719742
0, /* xTestCallback */
1957819743
#endif
1957919744
0, /* bLocaltimeFault */
19745
+ 0, /* bInternalFunctions */
1958019746
0x7ffffffe, /* iOnceResetThreshold */
1958119747
SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
1958219748
};
1958319749
1958419750
/*
@@ -20066,10 +20232,13 @@
2006620232
bft bIsReader:1; /* True for statements that read */
2006720233
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
2006820234
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
2006920235
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
2007020236
char *zSql; /* Text of the SQL statement that generated this */
20237
+#ifdef SQLITE_ENABLE_NORMALIZE
20238
+ char *zNormSql; /* Normalization of the associated SQL statement */
20239
+#endif
2007120240
void *pFree; /* Free this when deleting the vdbe */
2007220241
VdbeFrame *pFrame; /* Parent frame */
2007320242
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
2007420243
int nFrame; /* Number of frames in pFrame list */
2007520244
u32 expmask; /* Binding to these vars invalidates VM */
@@ -20128,11 +20297,13 @@
2012820297
2012920298
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
2013020299
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
2013120300
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
2013220301
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
20302
+#ifndef SQLITE_OMIT_EXPLAIN
2013320303
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
20304
+#endif
2013420305
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
2013520306
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
2013620307
SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
2013720308
SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
2013820309
SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
@@ -20167,11 +20338,13 @@
2016720338
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
2016820339
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
2016920340
#ifndef SQLITE_OMIT_WINDOWFUNC
2017020341
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
2017120342
#endif
20343
+#ifndef SQLITE_OMIT_EXPLAIN
2017220344
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
20345
+#endif
2017320346
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
2017420347
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
2017520348
SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
2017620349
#ifdef SQLITE_DEBUG
2017720350
SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
@@ -28294,10 +28467,46 @@
2829428467
}
2829528468
sqlite3TreeViewPop(pView);
2829628469
}
2829728470
}
2829828471
28472
+/*
28473
+** Generate a human-readable description of a SrcList object.
28474
+*/
28475
+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
28476
+ int i;
28477
+ for(i=0; i<pSrc->nSrc; i++){
28478
+ const struct SrcList_item *pItem = &pSrc->a[i];
28479
+ StrAccum x;
28480
+ char zLine[100];
28481
+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
28482
+ sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
28483
+ if( pItem->zDatabase ){
28484
+ sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
28485
+ }else if( pItem->zName ){
28486
+ sqlite3_str_appendf(&x, " %s", pItem->zName);
28487
+ }
28488
+ if( pItem->pTab ){
28489
+ sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
28490
+ }
28491
+ if( pItem->zAlias ){
28492
+ sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
28493
+ }
28494
+ if( pItem->fg.jointype & JT_LEFT ){
28495
+ sqlite3_str_appendf(&x, " LEFT-JOIN");
28496
+ }
28497
+ sqlite3StrAccumFinish(&x);
28498
+ sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
28499
+ if( pItem->pSelect ){
28500
+ sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
28501
+ }
28502
+ if( pItem->fg.isTabFunc ){
28503
+ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
28504
+ }
28505
+ sqlite3TreeViewPop(pView);
28506
+ }
28507
+}
2829928508
2830028509
/*
2830128510
** Generate a human-readable description of a Select object.
2830228511
*/
2830328512
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
@@ -28348,43 +28557,13 @@
2834828557
}
2834928558
sqlite3TreeViewPop(pView);
2835028559
}
2835128560
#endif
2835228561
if( p->pSrc && p->pSrc->nSrc ){
28353
- int i;
2835428562
pView = sqlite3TreeViewPush(pView, (n--)>0);
2835528563
sqlite3TreeViewLine(pView, "FROM");
28356
- for(i=0; i<p->pSrc->nSrc; i++){
28357
- struct SrcList_item *pItem = &p->pSrc->a[i];
28358
- StrAccum x;
28359
- char zLine[100];
28360
- sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
28361
- sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
28362
- if( pItem->zDatabase ){
28363
- sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
28364
- }else if( pItem->zName ){
28365
- sqlite3_str_appendf(&x, " %s", pItem->zName);
28366
- }
28367
- if( pItem->pTab ){
28368
- sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
28369
- }
28370
- if( pItem->zAlias ){
28371
- sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
28372
- }
28373
- if( pItem->fg.jointype & JT_LEFT ){
28374
- sqlite3_str_appendf(&x, " LEFT-JOIN");
28375
- }
28376
- sqlite3StrAccumFinish(&x);
28377
- sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
28378
- if( pItem->pSelect ){
28379
- sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
28380
- }
28381
- if( pItem->fg.isTabFunc ){
28382
- sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
28383
- }
28384
- sqlite3TreeViewPop(pView);
28385
- }
28564
+ sqlite3TreeViewSrcList(pView, p->pSrc);
2838628565
sqlite3TreeViewPop(pView);
2838728566
}
2838828567
if( p->pWhere ){
2838928568
sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
2839028569
sqlite3TreeViewExpr(pView, p->pWhere, 0);
@@ -28670,11 +28849,11 @@
2867028849
pFarg = 0;
2867128850
pWin = 0;
2867228851
}else{
2867328852
pFarg = pExpr->x.pList;
2867428853
#ifndef SQLITE_OMIT_WINDOWFUNC
28675
- pWin = pExpr->pWin;
28854
+ pWin = pExpr->y.pWin;
2867628855
#else
2867728856
pWin = 0;
2867828857
#endif
2867928858
}
2868028859
if( pExpr->op==TK_AGG_FUNCTION ){
@@ -31498,10 +31677,24 @@
3149831677
h += sqlite3UpperToLower[c];
3149931678
h *= 0x9e3779b1;
3150031679
}
3150131680
return h;
3150231681
}
31682
+#ifdef SQLITE_ENABLE_NORMALIZE
31683
+static unsigned int strHashN(const char *z, int n){
31684
+ unsigned int h = 0;
31685
+ int i;
31686
+ for(i=0; i<n; i++){
31687
+ /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
31688
+ ** 0x9e3779b1 is 2654435761 which is the closest prime number to
31689
+ ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
31690
+ h += sqlite3UpperToLower[z[i]];
31691
+ h *= 0x9e3779b1;
31692
+ }
31693
+ return h;
31694
+}
31695
+#endif /* SQLITE_ENABLE_NORMALIZE */
3150331696
3150431697
3150531698
/* Link pNew element into the hash table pH. If pEntry!=0 then also
3150631699
** insert pNew into the pEntry hash bucket.
3150731700
*/
@@ -31609,10 +31802,44 @@
3160931802
}
3161031803
elem = elem->next;
3161131804
}
3161231805
return &nullElement;
3161331806
}
31807
+#ifdef SQLITE_ENABLE_NORMALIZE
31808
+static HashElem *findElementWithHashN(
31809
+ const Hash *pH, /* The pH to be searched */
31810
+ const char *pKey, /* The key we are searching for */
31811
+ int nKey, /* Number of key bytes to use */
31812
+ unsigned int *pHash /* Write the hash value here */
31813
+){
31814
+ HashElem *elem; /* Used to loop thru the element list */
31815
+ int count; /* Number of elements left to test */
31816
+ unsigned int h; /* The computed hash */
31817
+ static HashElem nullElement = { 0, 0, 0, 0 };
31818
+
31819
+ if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
31820
+ struct _ht *pEntry;
31821
+ h = strHashN(pKey, nKey) % pH->htsize;
31822
+ pEntry = &pH->ht[h];
31823
+ elem = pEntry->chain;
31824
+ count = pEntry->count;
31825
+ }else{
31826
+ h = 0;
31827
+ elem = pH->first;
31828
+ count = pH->count;
31829
+ }
31830
+ if( pHash ) *pHash = h;
31831
+ while( count-- ){
31832
+ assert( elem!=0 );
31833
+ if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
31834
+ return elem;
31835
+ }
31836
+ elem = elem->next;
31837
+ }
31838
+ return &nullElement;
31839
+}
31840
+#endif /* SQLITE_ENABLE_NORMALIZE */
3161431841
3161531842
/* Remove a single entry from the hash table given a pointer to that
3161631843
** element and a hash on the element's key.
3161731844
*/
3161831845
static void removeElementGivenHash(
@@ -31653,10 +31880,18 @@
3165331880
SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
3165431881
assert( pH!=0 );
3165531882
assert( pKey!=0 );
3165631883
return findElementWithHash(pH, pKey, 0)->data;
3165731884
}
31885
+#ifdef SQLITE_ENABLE_NORMALIZE
31886
+SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
31887
+ assert( pH!=0 );
31888
+ assert( pKey!=0 );
31889
+ assert( nKey>=0 );
31890
+ return findElementWithHashN(pH, pKey, nKey, 0)->data;
31891
+}
31892
+#endif /* SQLITE_ENABLE_NORMALIZE */
3165831893
3165931894
/* Insert an element into the hash table pH. The key is pKey
3166031895
** and the data is "data".
3166131896
**
3166231897
** If no element exists with a matching key, then a new
@@ -32035,16 +32270,14 @@
3203532270
** Allowed values of unixFile.fsFlags
3203632271
*/
3203732272
#define SQLITE_FSFLAGS_IS_MSDOS 0x1
3203832273
3203932274
/*
32040
-** If we are to be thread-safe, include the pthreads header and define
32041
-** the SQLITE_UNIX_THREADS macro.
32275
+** If we are to be thread-safe, include the pthreads header.
3204232276
*/
3204332277
#if SQLITE_THREADSAFE
3204432278
/* # include <pthread.h> */
32045
-# define SQLITE_UNIX_THREADS 1
3204632279
#endif
3204732280
3204832281
/*
3204932282
** Default permissions when creating a new file
3205032283
*/
@@ -33216,12 +33449,11 @@
3321633449
#endif
3321733450
};
3321833451
3321933452
/*
3322033453
** An instance of the following structure is allocated for each open
33221
-** inode. Or, on LinuxThreads, there is one of these structures for
33222
-** each inode opened by each thread.
33454
+** inode.
3322333455
**
3322433456
** A single inode can have multiple file descriptors, so each unixFile
3322533457
** structure contains a pointer to an instance of this object and this
3322633458
** object keeps a count of the number of unixFile pointing to it.
3322733459
**
@@ -33263,17 +33495,20 @@
3326333495
#endif
3326433496
};
3326533497
3326633498
/*
3326733499
** A lists of all unixInodeInfo objects.
33500
+**
33501
+** Must hold unixBigLock in order to read or write this variable.
3326833502
*/
3326933503
static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
3327033504
3327133505
#ifdef SQLITE_DEBUG
3327233506
/*
33273
-** True if the inode mutex is held, or not. Used only within assert()
33274
-** to help verify correct mutex usage.
33507
+** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
33508
+** This routine is used only within assert() to help verify correct mutex
33509
+** usage.
3327533510
*/
3327633511
int unixFileMutexHeld(unixFile *pFile){
3327733512
assert( pFile->pInode );
3327833513
return sqlite3_mutex_held(pFile->pInode->pLockMutex);
3327933514
}
@@ -33397,12 +33632,12 @@
3339733632
}
3339833633
3339933634
/*
3340033635
** Release a unixInodeInfo structure previously allocated by findInodeInfo().
3340133636
**
33402
-** The mutex entered using the unixEnterMutex() function must be held
33403
-** when this function is called.
33637
+** The global mutex must be held when this routine is called, but the mutex
33638
+** on the inode being deleted must NOT be held.
3340433639
*/
3340533640
static void releaseInodeInfo(unixFile *pFile){
3340633641
unixInodeInfo *pInode = pFile->pInode;
3340733642
assert( unixMutexHeld() );
3340833643
assert( unixFileMutexNotheld(pFile) );
@@ -33433,12 +33668,11 @@
3343333668
/*
3343433669
** Given a file descriptor, locate the unixInodeInfo object that
3343533670
** describes that file descriptor. Create a new one if necessary. The
3343633671
** return value might be uninitialized if an error occurs.
3343733672
**
33438
-** The mutex entered using the unixEnterMutex() function must be held
33439
-** when this function is called.
33673
+** The global mutex must held when calling this routine.
3344033674
**
3344133675
** Return an appropriate error code.
3344233676
*/
3344333677
static int findInodeInfo(
3344433678
unixFile *pFile, /* Unix file with file desc used in the key */
@@ -33495,10 +33729,11 @@
3349533729
#if OS_VXWORKS
3349633730
fileId.pId = pFile->pId;
3349733731
#else
3349833732
fileId.ino = (u64)statbuf.st_ino;
3349933733
#endif
33734
+ assert( unixMutexHeld() );
3350033735
pInode = inodeList;
3350133736
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
3350233737
pInode = pInode->pNext;
3350333738
}
3350433739
if( pInode==0 ){
@@ -33514,10 +33749,11 @@
3351433749
sqlite3_free(pInode);
3351533750
return SQLITE_NOMEM_BKPT;
3351633751
}
3351733752
}
3351833753
pInode->nRef = 1;
33754
+ assert( unixMutexHeld() );
3351933755
pInode->pNext = inodeList;
3352033756
pInode->pPrev = 0;
3352133757
if( inodeList ) inodeList->pPrev = pInode;
3352233758
inodeList = pInode;
3352333759
}else{
@@ -36311,22 +36547,22 @@
3631136547
**
3631236548
** nRef
3631336549
**
3631436550
** The following fields are read-only after the object is created:
3631536551
**
36316
-** fid
36552
+** hShm
3631736553
** zFilename
3631836554
**
36319
-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
36555
+** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
3632036556
** unixMutexHeld() is true when reading or writing any other field
3632136557
** in this structure.
3632236558
*/
3632336559
struct unixShmNode {
3632436560
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
36325
- sqlite3_mutex *mutex; /* Mutex to access this object */
36561
+ sqlite3_mutex *pShmMutex; /* Mutex to access this object */
3632636562
char *zFilename; /* Name of the mmapped file */
36327
- int h; /* Open file descriptor */
36563
+ int hShm; /* Open file descriptor */
3632836564
int szRegion; /* Size of shared-memory regions */
3632936565
u16 nRegion; /* Size of array apRegion */
3633036566
u8 isReadonly; /* True if read-only */
3633136567
u8 isUnlocked; /* True if no DMS lock held */
3633236568
char **apRegion; /* Array of mapped shared-memory regions */
@@ -36344,20 +36580,20 @@
3634436580
** open shared memory connection.
3634536581
**
3634636582
** The following fields are initialized when this object is created and
3634736583
** are read-only thereafter:
3634836584
**
36349
-** unixShm.pFile
36585
+** unixShm.pShmNode
3635036586
** unixShm.id
3635136587
**
36352
-** All other fields are read/write. The unixShm.pFile->mutex must be held
36353
-** while accessing any read/write fields.
36588
+** All other fields are read/write. The unixShm.pShmNode->pShmMutex must
36589
+** be held while accessing any read/write fields.
3635436590
*/
3635536591
struct unixShm {
3635636592
unixShmNode *pShmNode; /* The underlying unixShmNode object */
3635736593
unixShm *pNext; /* Next unixShm with the same unixShmNode */
36358
- u8 hasMutex; /* True if holding the unixShmNode mutex */
36594
+ u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */
3635936595
u8 id; /* Id of this connection within its unixShmNode */
3636036596
u16 sharedMask; /* Mask of shared locks held */
3636136597
u16 exclMask; /* Mask of exclusive locks held */
3636236598
};
3636336599
@@ -36383,25 +36619,26 @@
3638336619
struct flock f; /* The posix advisory locking structure */
3638436620
int rc = SQLITE_OK; /* Result code form fcntl() */
3638536621
3638636622
/* Access to the unixShmNode object is serialized by the caller */
3638736623
pShmNode = pFile->pInode->pShmNode;
36388
- assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
36624
+ assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
36625
+ assert( pShmNode->nRef>0 || unixMutexHeld() );
3638936626
3639036627
/* Shared locks never span more than one byte */
3639136628
assert( n==1 || lockType!=F_RDLCK );
3639236629
3639336630
/* Locks are within range */
3639436631
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
3639536632
36396
- if( pShmNode->h>=0 ){
36633
+ if( pShmNode->hShm>=0 ){
3639736634
/* Initialize the locking parameters */
3639836635
f.l_type = lockType;
3639936636
f.l_whence = SEEK_SET;
3640036637
f.l_start = ofst;
3640136638
f.l_len = n;
36402
- rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
36639
+ rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
3640336640
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
3640436641
}
3640536642
3640636643
/* Update the global lock state and do debug tracing */
3640736644
#ifdef SQLITE_DEBUG
@@ -36469,22 +36706,22 @@
3646936706
assert( unixMutexHeld() );
3647036707
if( p && ALWAYS(p->nRef==0) ){
3647136708
int nShmPerMap = unixShmRegionPerMap();
3647236709
int i;
3647336710
assert( p->pInode==pFd->pInode );
36474
- sqlite3_mutex_free(p->mutex);
36711
+ sqlite3_mutex_free(p->pShmMutex);
3647536712
for(i=0; i<p->nRegion; i+=nShmPerMap){
36476
- if( p->h>=0 ){
36713
+ if( p->hShm>=0 ){
3647736714
osMunmap(p->apRegion[i], p->szRegion);
3647836715
}else{
3647936716
sqlite3_free(p->apRegion[i]);
3648036717
}
3648136718
}
3648236719
sqlite3_free(p->apRegion);
36483
- if( p->h>=0 ){
36484
- robust_close(pFd, p->h, __LINE__);
36485
- p->h = -1;
36720
+ if( p->hShm>=0 ){
36721
+ robust_close(pFd, p->hShm, __LINE__);
36722
+ p->hShm = -1;
3648636723
}
3648736724
p->pInode->pShmNode = 0;
3648836725
sqlite3_free(p);
3648936726
}
3649036727
}
@@ -36522,19 +36759,24 @@
3652236759
** system crash, the database itself may also become corrupt. */
3652336760
lock.l_whence = SEEK_SET;
3652436761
lock.l_start = UNIX_SHM_DMS;
3652536762
lock.l_len = 1;
3652636763
lock.l_type = F_WRLCK;
36527
- if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
36764
+ if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
3652836765
rc = SQLITE_IOERR_LOCK;
3652936766
}else if( lock.l_type==F_UNLCK ){
3653036767
if( pShmNode->isReadonly ){
3653136768
pShmNode->isUnlocked = 1;
3653236769
rc = SQLITE_READONLY_CANTINIT;
3653336770
}else{
3653436771
rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
36535
- if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
36772
+ /* The first connection to attach must truncate the -shm file. We
36773
+ ** truncate to 3 bytes (an arbitrary small number, less than the
36774
+ ** -shm header size) rather than 0 as a system debugging aid, to
36775
+ ** help detect if a -shm file truncation is legitimate or is the work
36776
+ ** or a rogue process. */
36777
+ if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
3653636778
rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
3653736779
}
3653836780
}
3653936781
}else if( lock.l_type==F_WRLCK ){
3654036782
rc = SQLITE_BUSY;
@@ -36636,28 +36878,28 @@
3663636878
(u32)sStat.st_ino, (u32)sStat.st_dev);
3663736879
#else
3663836880
sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
3663936881
sqlite3FileSuffix3(pDbFd->zPath, zShm);
3664036882
#endif
36641
- pShmNode->h = -1;
36883
+ pShmNode->hShm = -1;
3664236884
pDbFd->pInode->pShmNode = pShmNode;
3664336885
pShmNode->pInode = pDbFd->pInode;
3664436886
if( sqlite3GlobalConfig.bCoreMutex ){
36645
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
36646
- if( pShmNode->mutex==0 ){
36887
+ pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
36888
+ if( pShmNode->pShmMutex==0 ){
3664736889
rc = SQLITE_NOMEM_BKPT;
3664836890
goto shm_open_err;
3664936891
}
3665036892
}
3665136893
3665236894
if( pInode->bProcessLock==0 ){
3665336895
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
36654
- pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
36896
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
3665536897
}
36656
- if( pShmNode->h<0 ){
36657
- pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
36658
- if( pShmNode->h<0 ){
36898
+ if( pShmNode->hShm<0 ){
36899
+ pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
36900
+ if( pShmNode->hShm<0 ){
3665936901
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
3666036902
goto shm_open_err;
3666136903
}
3666236904
pShmNode->isReadonly = 1;
3666336905
}
@@ -36664,11 +36906,11 @@
3666436906
3666536907
/* If this process is running as root, make sure that the SHM file
3666636908
** is owned by the same user that owns the original database. Otherwise,
3666736909
** the original owner will not be able to connect.
3666836910
*/
36669
- robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
36911
+ robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
3667036912
3667136913
rc = unixLockSharedMemory(pDbFd, pShmNode);
3667236914
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
3667336915
}
3667436916
}
@@ -36684,17 +36926,17 @@
3668436926
3668536927
/* The reference count on pShmNode has already been incremented under
3668636928
** the cover of the unixEnterMutex() mutex and the pointer from the
3668736929
** new (struct unixShm) object to the pShmNode has been set. All that is
3668836930
** left to do is to link the new object into the linked list starting
36689
- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
36690
- ** mutex.
36931
+ ** at pShmNode->pFirst. This must be done while holding the
36932
+ ** pShmNode->pShmMutex.
3669136933
*/
36692
- sqlite3_mutex_enter(pShmNode->mutex);
36934
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
3669336935
p->pNext = pShmNode->pFirst;
3669436936
pShmNode->pFirst = p;
36695
- sqlite3_mutex_leave(pShmNode->mutex);
36937
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
3669636938
return rc;
3669736939
3669836940
/* Jump here on any error */
3669936941
shm_open_err:
3670036942
unixShmPurge(pDbFd); /* This call frees pShmNode if required */
@@ -36742,20 +36984,20 @@
3674236984
if( rc!=SQLITE_OK ) return rc;
3674336985
}
3674436986
3674536987
p = pDbFd->pShm;
3674636988
pShmNode = p->pShmNode;
36747
- sqlite3_mutex_enter(pShmNode->mutex);
36989
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
3674836990
if( pShmNode->isUnlocked ){
3674936991
rc = unixLockSharedMemory(pDbFd, pShmNode);
3675036992
if( rc!=SQLITE_OK ) goto shmpage_out;
3675136993
pShmNode->isUnlocked = 0;
3675236994
}
3675336995
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
3675436996
assert( pShmNode->pInode==pDbFd->pInode );
36755
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
36756
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
36997
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
36998
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
3675736999
3675837000
/* Minimum number of regions required to be mapped. */
3675937001
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
3676037002
3676137003
if( pShmNode->nRegion<nReqRegion ){
@@ -36763,16 +37005,16 @@
3676337005
int nByte = nReqRegion*szRegion; /* Minimum required file size */
3676437006
struct stat sStat; /* Used by fstat() */
3676537007
3676637008
pShmNode->szRegion = szRegion;
3676737009
36768
- if( pShmNode->h>=0 ){
37010
+ if( pShmNode->hShm>=0 ){
3676937011
/* The requested region is not mapped into this processes address space.
3677037012
** Check to see if it has been allocated (i.e. if the wal-index file is
3677137013
** large enough to contain the requested region).
3677237014
*/
36773
- if( osFstat(pShmNode->h, &sStat) ){
37015
+ if( osFstat(pShmNode->hShm, &sStat) ){
3677437016
rc = SQLITE_IOERR_SHMSIZE;
3677537017
goto shmpage_out;
3677637018
}
3677737019
3677837020
if( sStat.st_size<nByte ){
@@ -36796,11 +37038,11 @@
3679637038
3679737039
/* Write to the last byte of each newly allocated or extended page */
3679837040
assert( (nByte % pgsz)==0 );
3679937041
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
3680037042
int x = 0;
36801
- if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
37043
+ if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
3680237044
const char *zFile = pShmNode->zFilename;
3680337045
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
3680437046
goto shmpage_out;
3680537047
}
3680637048
}
@@ -36819,26 +37061,26 @@
3681937061
pShmNode->apRegion = apNew;
3682037062
while( pShmNode->nRegion<nReqRegion ){
3682137063
int nMap = szRegion*nShmPerMap;
3682237064
int i;
3682337065
void *pMem;
36824
- if( pShmNode->h>=0 ){
37066
+ if( pShmNode->hShm>=0 ){
3682537067
pMem = osMmap(0, nMap,
3682637068
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
36827
- MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
37069
+ MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
3682837070
);
3682937071
if( pMem==MAP_FAILED ){
3683037072
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
3683137073
goto shmpage_out;
3683237074
}
3683337075
}else{
36834
- pMem = sqlite3_malloc64(szRegion);
37076
+ pMem = sqlite3_malloc64(nMap);
3683537077
if( pMem==0 ){
3683637078
rc = SQLITE_NOMEM_BKPT;
3683737079
goto shmpage_out;
3683837080
}
36839
- memset(pMem, 0, szRegion);
37081
+ memset(pMem, 0, nMap);
3684037082
}
3684137083
3684237084
for(i=0; i<nShmPerMap; i++){
3684337085
pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
3684437086
}
@@ -36851,11 +37093,11 @@
3685137093
*pp = pShmNode->apRegion[iRegion];
3685237094
}else{
3685337095
*pp = 0;
3685437096
}
3685537097
if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
36856
- sqlite3_mutex_leave(pShmNode->mutex);
37098
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
3685737099
return rc;
3685837100
}
3685937101
3686037102
/*
3686137103
** Change the lock state for a shared-memory segment.
@@ -36885,16 +37127,16 @@
3688537127
assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
3688637128
|| flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
3688737129
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
3688837130
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
3688937131
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
36890
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
36891
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
37132
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
37133
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
3689237134
3689337135
mask = (1<<(ofst+n)) - (1<<ofst);
3689437136
assert( n>1 || mask==(1<<ofst) );
36895
- sqlite3_mutex_enter(pShmNode->mutex);
37137
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
3689637138
if( flags & SQLITE_SHM_UNLOCK ){
3689737139
u16 allMask = 0; /* Mask of locks held by siblings */
3689837140
3689937141
/* See if any siblings hold this same lock */
3690037142
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
@@ -36963,11 +37205,11 @@
3696337205
assert( (p->sharedMask & mask)==0 );
3696437206
p->exclMask |= mask;
3696537207
}
3696637208
}
3696737209
}
36968
- sqlite3_mutex_leave(pShmNode->mutex);
37210
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
3696937211
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
3697037212
p->id, osGetpid(0), p->sharedMask, p->exclMask));
3697137213
return rc;
3697237214
}
3697337215
@@ -37013,27 +37255,27 @@
3701337255
assert( pShmNode==pDbFd->pInode->pShmNode );
3701437256
assert( pShmNode->pInode==pDbFd->pInode );
3701537257
3701637258
/* Remove connection p from the set of connections associated
3701737259
** with pShmNode */
37018
- sqlite3_mutex_enter(pShmNode->mutex);
37260
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
3701937261
for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
3702037262
*pp = p->pNext;
3702137263
3702237264
/* Free the connection p */
3702337265
sqlite3_free(p);
3702437266
pDbFd->pShm = 0;
37025
- sqlite3_mutex_leave(pShmNode->mutex);
37267
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
3702637268
3702737269
/* If pShmNode->nRef has reached 0, then close the underlying
3702837270
** shared-memory file, too */
3702937271
assert( unixFileMutexNotheld(pDbFd) );
3703037272
unixEnterMutex();
3703137273
assert( pShmNode->nRef>0 );
3703237274
pShmNode->nRef--;
3703337275
if( pShmNode->nRef==0 ){
37034
- if( deleteFlag && pShmNode->h>=0 ){
37276
+ if( deleteFlag && pShmNode->hShm>=0 ){
3703537277
osUnlink(pShmNode->zFilename);
3703637278
}
3703737279
unixShmPurge(pDbFd);
3703837280
}
3703937281
unixLeaveMutex();
@@ -40447,12 +40689,11 @@
4044740689
#endif
4044840690
#if SQLITE_MAX_MMAP_SIZE>0
4044940691
int nFetchOut; /* Number of outstanding xFetch references */
4045040692
HANDLE hMap; /* Handle for accessing memory mapping */
4045140693
void *pMapRegion; /* Area memory mapped */
40452
- sqlite3_int64 mmapSize; /* Usable size of mapped region */
40453
- sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
40694
+ sqlite3_int64 mmapSize; /* Size of mapped region */
4045440695
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
4045540696
#endif
4045640697
};
4045740698
4045840699
/*
@@ -43069,10 +43310,30 @@
4306943310
winFile *pFile = (winFile*)id; /* File handle object */
4307043311
int rc = SQLITE_OK; /* Return code for this function */
4307143312
DWORD lastErrno;
4307243313
#if SQLITE_MAX_MMAP_SIZE>0
4307343314
sqlite3_int64 oldMmapSize;
43315
+ if( pFile->nFetchOut>0 ){
43316
+ /* File truncation is a no-op if there are outstanding memory mapped
43317
+ ** pages. This is because truncating the file means temporarily unmapping
43318
+ ** the file, and that might delete memory out from under existing cursors.
43319
+ **
43320
+ ** This can result in incremental vacuum not truncating the file,
43321
+ ** if there is an active read cursor when the incremental vacuum occurs.
43322
+ ** No real harm comes of this - the database file is not corrupted,
43323
+ ** though some folks might complain that the file is bigger than it
43324
+ ** needs to be.
43325
+ **
43326
+ ** The only feasible work-around is to defer the truncation until after
43327
+ ** all references to memory-mapped content are closed. That is doable,
43328
+ ** but involves adding a few branches in the common write code path which
43329
+ ** could slow down normal operations slightly. Hence, we have decided for
43330
+ ** now to simply make trancations a no-op if there are pending reads. We
43331
+ ** can maybe revisit this decision in the future.
43332
+ */
43333
+ return SQLITE_OK;
43334
+ }
4307443335
#endif
4307543336
4307643337
assert( pFile );
4307743338
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
4307843339
OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
@@ -44497,13 +44758,13 @@
4449744758
*/
4449844759
#if SQLITE_MAX_MMAP_SIZE>0
4449944760
static int winUnmapfile(winFile *pFile){
4450044761
assert( pFile!=0 );
4450144762
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
44502
- "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
44763
+ "mmapSize=%lld, mmapSizeMax=%lld\n",
4450344764
osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
44504
- pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
44765
+ pFile->mmapSize, pFile->mmapSizeMax));
4450544766
if( pFile->pMapRegion ){
4450644767
if( !osUnmapViewOfFile(pFile->pMapRegion) ){
4450744768
pFile->lastErrno = osGetLastError();
4450844769
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
4450944770
"rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
@@ -44511,11 +44772,10 @@
4451144772
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
4451244773
"winUnmapfile1", pFile->zPath);
4451344774
}
4451444775
pFile->pMapRegion = 0;
4451544776
pFile->mmapSize = 0;
44516
- pFile->mmapSizeActual = 0;
4451744777
}
4451844778
if( pFile->hMap!=NULL ){
4451944779
if( !osCloseHandle(pFile->hMap) ){
4452044780
pFile->lastErrno = osGetLastError();
4452144781
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
@@ -44622,11 +44882,10 @@
4462244882
osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
4462344883
return SQLITE_OK;
4462444884
}
4462544885
pFd->pMapRegion = pNew;
4462644886
pFd->mmapSize = nMap;
44627
- pFd->mmapSizeActual = nMap;
4462844887
}
4462944888
4463044889
OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
4463144890
osGetCurrentProcessId(), pFd));
4463244891
return SQLITE_OK;
@@ -45424,11 +45683,10 @@
4542445683
pFile->zPath = zName;
4542545684
#if SQLITE_MAX_MMAP_SIZE>0
4542645685
pFile->hMap = NULL;
4542745686
pFile->pMapRegion = 0;
4542845687
pFile->mmapSize = 0;
45429
- pFile->mmapSizeActual = 0;
4543045688
pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
4543145689
#endif
4543245690
4543345691
OpenCounter(+1);
4543445692
return rc;
@@ -47321,11 +47579,11 @@
4732147579
** pDirtyTail to the last (oldest).
4732247580
**
4732347581
** The PCache.pSynced variable is used to optimize searching for a dirty
4732447582
** page to eject from the cache mid-transaction. It is better to eject
4732547583
** a page that does not require a journal sync than one that does.
47326
-** Therefore, pSynced is maintained to that it *almost* always points
47584
+** Therefore, pSynced is maintained so that it *almost* always points
4732747585
** to either the oldest page in the pDirty/pDirtyTail list that has a
4732847586
** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
4732947587
** (so that the right page to eject can be found by following pDirtyPrev
4733047588
** pointers).
4733147589
*/
@@ -48144,10 +48402,19 @@
4814448402
int nDirty = 0;
4814548403
int nCache = numberOfCachePages(pCache);
4814648404
for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
4814748405
return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
4814848406
}
48407
+
48408
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
48409
+/*
48410
+** Return true if there are one or more dirty pages in the cache. Else false.
48411
+*/
48412
+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){
48413
+ return (pCache->pDirty!=0);
48414
+}
48415
+#endif
4814948416
4815048417
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
4815148418
/*
4815248419
** For all dirty pages currently in the cache, invoke the specified
4815348420
** callback. This is only used if the SQLITE_CHECK_PAGES macro is
@@ -48268,11 +48535,12 @@
4826848535
PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
4826948536
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
4827048537
};
4827148538
4827248539
/*
48273
-** A page is pinned if it is no on the LRU list
48540
+** A page is pinned if it is not on the LRU list. To be "pinned" means
48541
+** that the page is in active use and must not be deallocated.
4827448542
*/
4827548543
#define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
4827648544
#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
4827748545
4827848546
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
@@ -50908,23 +51176,34 @@
5090851176
**
5090951177
** if( pPager->jfd->pMethods ){ ...
5091051178
*/
5091151179
#define isOpen(pFd) ((pFd)->pMethods!=0)
5091251180
51181
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
5091351182
/*
50914
-** Return true if this pager uses a write-ahead log to read page pgno.
50915
-** Return false if the pager reads pgno directly from the database.
51183
+** Return true if page pgno can be read directly from the database file
51184
+** by the b-tree layer. This is the case if:
51185
+**
51186
+** * the database file is open,
51187
+** * there are no dirty pages in the cache, and
51188
+** * the desired page is not currently in the wal file.
5091651189
*/
50917
-#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
50918
-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
50919
- u32 iRead = 0;
50920
- int rc;
50921
- if( pPager->pWal==0 ) return 0;
50922
- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
50923
- return rc || iRead;
51190
+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
51191
+ if( pPager->fd->pMethods==0 ) return 0;
51192
+ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
51193
+#ifndef SQLITE_OMIT_WAL
51194
+ if( pPager->pWal ){
51195
+ u32 iRead = 0;
51196
+ int rc;
51197
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
51198
+ return (rc==SQLITE_OK && iRead==0);
51199
+ }
51200
+#endif
51201
+ return 1;
5092451202
}
5092551203
#endif
51204
+
5092651205
#ifndef SQLITE_OMIT_WAL
5092751206
# define pagerUseWal(x) ((x)->pWal!=0)
5092851207
#else
5092951208
# define pagerUseWal(x) 0
5093051209
# define pagerRollbackWal(x) 0
@@ -57104,11 +57383,15 @@
5710457383
void *(*xCodec)(void*,void*,Pgno,int),
5710557384
void (*xCodecSizeChng)(void*,int,int),
5710657385
void (*xCodecFree)(void*),
5710757386
void *pCodec
5710857387
){
57109
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
57388
+ if( pPager->xCodecFree ){
57389
+ pPager->xCodecFree(pPager->pCodec);
57390
+ }else{
57391
+ pager_reset(pPager);
57392
+ }
5711057393
pPager->xCodec = pPager->memDb ? 0 : xCodec;
5711157394
pPager->xCodecSizeChng = xCodecSizeChng;
5711257395
pPager->xCodecFree = xCodecFree;
5711357396
pPager->pCodec = pCodec;
5711457397
setGetterMethod(pPager);
@@ -65764,11 +66047,11 @@
6576466047
freeTempSpace(pBt);
6576566048
rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
6576666049
pageSize-usableSize);
6576766050
return rc;
6576866051
}
65769
- if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
66052
+ if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
6577066053
rc = SQLITE_CORRUPT_BKPT;
6577166054
goto page1_init_failed;
6577266055
}
6577366056
/* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
6577466057
** be less than 480. In other words, if the page size is 512, then the
@@ -66238,10 +66521,11 @@
6623866521
6623966522
assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
6624066523
eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
6624166524
assert( sqlite3_mutex_held(pBt->mutex) );
6624266525
assert( pDbPage->pBt==pBt );
66526
+ if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
6624366527
6624466528
/* Move page iDbPage from its current location to page number iFreePage */
6624566529
TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
6624666530
iDbPage, iFreePage, iPtrPage, eType));
6624766531
rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
@@ -67409,13 +67693,10 @@
6740967693
offset -= ovflSize;
6741067694
}else{
6741167695
/* Need to read this page properly. It contains some of the
6741267696
** range of data that is being read (eOp==0) or written (eOp!=0).
6741367697
*/
67414
-#ifdef SQLITE_DIRECT_OVERFLOW_READ
67415
- sqlite3_file *fd; /* File from which to do direct overflow read */
67416
-#endif
6741767698
int a = amt;
6741867699
if( a + offset > ovflSize ){
6741967700
a = ovflSize - offset;
6742067701
}
6742167702
@@ -67422,11 +67703,11 @@
6742267703
#ifdef SQLITE_DIRECT_OVERFLOW_READ
6742367704
/* If all the following are true:
6742467705
**
6742567706
** 1) this is a read operation, and
6742667707
** 2) data is required from the start of this overflow page, and
67427
- ** 3) there is no open write-transaction, and
67708
+ ** 3) there are no dirty pages in the page-cache
6742867709
** 4) the database is file-backed, and
6742967710
** 5) the page is not in the WAL file
6743067711
** 6) at least 4 bytes have already been read into the output buffer
6743167712
**
6743267713
** then data can be read directly from the database file into the
@@ -67433,15 +67714,14 @@
6743367714
** output buffer, bypassing the page-cache altogether. This speeds
6743467715
** up loading large records that span many overflow pages.
6743567716
*/
6743667717
if( eOp==0 /* (1) */
6743767718
&& offset==0 /* (2) */
67438
- && pBt->inTransaction==TRANS_READ /* (3) */
67439
- && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */
67440
- && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */
67719
+ && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */
6744167720
&& &pBuf[-4]>=pBufStart /* (6) */
6744267721
){
67722
+ sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
6744367723
u8 aSave[4];
6744467724
u8 *aWrite = &pBuf[-4];
6744567725
assert( aWrite>=pBufStart ); /* due to (6) */
6744667726
memcpy(aSave, aWrite, 4);
6744767727
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
@@ -74033,11 +74313,12 @@
7403374313
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
7403474314
}else{
7403574315
assert( fg & MEM_Real );
7403674316
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
7403774317
}
74038
- pMem->n = sqlite3Strlen30(pMem->z);
74318
+ assert( pMem->z!=0 );
74319
+ pMem->n = sqlite3Strlen30NN(pMem->z);
7403974320
pMem->enc = SQLITE_UTF8;
7404074321
pMem->flags |= MEM_Str|MEM_Term;
7404174322
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
7404274323
sqlite3VdbeChangeEncoding(pMem, enc);
7404374324
return SQLITE_OK;
@@ -75608,10 +75889,17 @@
7560875889
if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
7560975890
p->expmask = 0;
7561075891
}
7561175892
assert( p->zSql==0 );
7561275893
p->zSql = sqlite3DbStrNDup(p->db, z, n);
75894
+#ifdef SQLITE_ENABLE_NORMALIZE
75895
+ assert( p->zNormSql==0 );
75896
+ if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
75897
+ sqlite3Normalize(p, p->zSql, n, prepFlags);
75898
+ assert( p->zNormSql!=0 || p->db->mallocFailed );
75899
+ }
75900
+#endif
7561375901
}
7561475902
7561575903
/*
7561675904
** Swap all content between two VDBE structures.
7561775905
*/
@@ -75629,10 +75917,15 @@
7562975917
pA->pPrev = pB->pPrev;
7563075918
pB->pPrev = pTmp;
7563175919
zTmp = pA->zSql;
7563275920
pA->zSql = pB->zSql;
7563375921
pB->zSql = zTmp;
75922
+#ifdef SQLITE_ENABLE_NORMALIZE
75923
+ zTmp = pA->zNormSql;
75924
+ pA->zNormSql = pB->zNormSql;
75925
+ pB->zNormSql = zTmp;
75926
+#endif
7563475927
pB->expmask = pA->expmask;
7563575928
pB->prepFlags = pA->prepFlags;
7563675929
memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
7563775930
pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
7563875931
}
@@ -78700,10 +78993,13 @@
7870078993
sqlite3DbFree(db, p->pFree);
7870178994
}
7870278995
vdbeFreeOpArray(db, p->aOp, p->nOp);
7870378996
sqlite3DbFree(db, p->aColName);
7870478997
sqlite3DbFree(db, p->zSql);
78998
+#ifdef SQLITE_ENABLE_NORMALIZE
78999
+ sqlite3DbFree(db, p->zNormSql);
79000
+#endif
7870579001
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
7870679002
{
7870779003
int i;
7870879004
for(i=0; i<p->nScan; i++){
7870979005
sqlite3DbFree(db, p->aScan[i].zName);
@@ -80101,11 +80397,13 @@
8010180397
8010280398
/* The index entry must begin with a header size */
8010380399
(void)getVarint32((u8*)m.z, szHdr);
8010480400
testcase( szHdr==3 );
8010580401
testcase( szHdr==m.n );
80106
- if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
80402
+ testcase( szHdr>0x7fffffff );
80403
+ assert( m.n>=0 );
80404
+ if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
8010780405
goto idx_rowid_corruption;
8010880406
}
8010980407
8011080408
/* The last field of the index should be an integer - the ROWID.
8011180409
** Verify that the last entry really is an integer. */
@@ -82112,10 +82410,20 @@
8211282410
}
8211382411
return z;
8211482412
#endif
8211582413
}
8211682414
82415
+#ifdef SQLITE_ENABLE_NORMALIZE
82416
+/*
82417
+** Return the normalized SQL associated with a prepared statement.
82418
+*/
82419
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
82420
+ Vdbe *p = (Vdbe *)pStmt;
82421
+ return p ? p->zNormSql : 0;
82422
+}
82423
+#endif /* SQLITE_ENABLE_NORMALIZE */
82424
+
8211782425
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
8211882426
/*
8211982427
** Allocate and populate an UnpackedRecord structure based on the serialized
8212082428
** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
8212182429
** if successful, or a NULL pointer if an OOM error is encountered.
@@ -85551,21 +85859,29 @@
8555185859
nVarint = sqlite3VarintLen(nHdr);
8555285860
nHdr += nVarint;
8555385861
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
8555485862
}
8555585863
nByte = nHdr+nData;
85556
- if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
85557
- goto too_big;
85558
- }
8555985864
8556085865
/* Make sure the output register has a buffer large enough to store
8556185866
** the new record. The output register (pOp->p3) is not allowed to
8556285867
** be one of the input registers (because the following call to
8556385868
** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
8556485869
*/
85565
- if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
85566
- goto no_mem;
85870
+ if( nByte+nZero<=pOut->szMalloc ){
85871
+ /* The output register is already large enough to hold the record.
85872
+ ** No error checks or buffer enlargement is required */
85873
+ pOut->z = pOut->zMalloc;
85874
+ }else{
85875
+ /* Need to make sure that the output is not too big and then enlarge
85876
+ ** the output register to hold the full result */
85877
+ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
85878
+ goto too_big;
85879
+ }
85880
+ if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
85881
+ goto no_mem;
85882
+ }
8556785883
}
8556885884
zNewRecord = (u8 *)pOut->z;
8556985885
8557085886
/* Write the record */
8557185887
i = putVarint32(zNewRecord, nHdr);
@@ -88417,11 +88733,11 @@
8841788733
}else
8841888734
#endif
8841988735
{
8842088736
zMaster = MASTER_NAME;
8842188737
initData.db = db;
88422
- initData.iDb = pOp->p1;
88738
+ initData.iDb = iDb;
8842388739
initData.pzErrMsg = &p->zErrMsg;
8842488740
initData.mInitFlags = 0;
8842588741
zSql = sqlite3MPrintf(db,
8842688742
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
8842788743
db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
@@ -89614,14 +89930,15 @@
8961489930
** Store in register P3 the value of the P2-th column of
8961589931
** the current row of the virtual-table of cursor P1.
8961689932
**
8961789933
** If the VColumn opcode is being used to fetch the value of
8961889934
** an unchanging column during an UPDATE operation, then the P5
89619
-** value is 1. Otherwise, P5 is 0. The P5 value is returned
89620
-** by sqlite3_vtab_nochange() routine and can be used
89621
-** by virtual table implementations to return special "no-change"
89622
-** marks which can be more efficient, depending on the virtual table.
89935
+** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange()
89936
+** function to return true inside the xColumn method of the virtual
89937
+** table implementation. The P5 column might also contain other
89938
+** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
89939
+** unused by OP_VColumn.
8962389940
*/
8962489941
case OP_VColumn: {
8962589942
sqlite3_vtab *pVtab;
8962689943
const sqlite3_module *pModule;
8962789944
Mem *pDest;
@@ -89639,11 +89956,12 @@
8963989956
pVtab = pCur->uc.pVCur->pVtab;
8964089957
pModule = pVtab->pModule;
8964189958
assert( pModule->xColumn );
8964289959
memset(&sContext, 0, sizeof(sContext));
8964389960
sContext.pOut = pDest;
89644
- if( pOp->p5 ){
89961
+ testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
89962
+ if( pOp->p5 & OPFLAG_NOCHNG ){
8964589963
sqlite3VdbeMemSetNull(pDest);
8964689964
pDest->flags = MEM_Null|MEM_Zero;
8964789965
pDest->u.nZero = 0;
8964889966
}else{
8964989967
MemSetTypeFlag(pDest, MEM_Null);
@@ -93998,12 +94316,12 @@
9399894316
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
9399994317
}else if( pExpr->x.pList ){
9400094318
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
9400194319
}
9400294320
#ifndef SQLITE_OMIT_WINDOWFUNC
94003
- if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
94004
- Window *pWin = pExpr->pWin;
94321
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
94322
+ Window *pWin = pExpr->y.pWin;
9400594323
if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
9400694324
if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
9400794325
if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
9400894326
}
9400994327
#endif
@@ -94272,11 +94590,11 @@
9427294590
**
9427394591
** pExpr->iDb Set the index in db->aDb[] of the database X
9427494592
** (even if X is implied).
9427594593
** pExpr->iTable Set to the cursor number for the table obtained
9427694594
** from pSrcList.
94277
-** pExpr->pTab Points to the Table structure of X.Y (even if
94595
+** pExpr->y.pTab Points to the Table structure of X.Y (even if
9427894596
** X and/or Y are implied.)
9427994597
** pExpr->iColumn Set to the column number within the table.
9428094598
** pExpr->op Set to TK_COLUMN.
9428194599
** pExpr->pLeft Any expression this points to is deleted
9428294600
** pExpr->pRight Any expression this points to is deleted.
@@ -94316,11 +94634,10 @@
9431694634
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
9431794635
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
9431894636
9431994637
/* Initialize the node to no-match */
9432094638
pExpr->iTable = -1;
94321
- pExpr->pTab = 0;
9432294639
ExprSetVVAProperty(pExpr, EP_NoReduce);
9432394640
9432494641
/* Translate the schema name in zDb into a pointer to the corresponding
9432594642
** schema. If not found, pSchema will remain NULL and nothing will match
9432694643
** resulting in an appropriate error message toward the end of this routine
@@ -94378,11 +94695,11 @@
9437894695
assert( zTabName!=0 );
9437994696
if( sqlite3StrICmp(zTabName, zTab)!=0 ){
9438094697
continue;
9438194698
}
9438294699
if( IN_RENAME_OBJECT && pItem->zAlias ){
94383
- sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
94700
+ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
9438494701
}
9438594702
}
9438694703
if( 0==(cntTab++) ){
9438794704
pMatch = pItem;
9438894705
}
@@ -94404,17 +94721,17 @@
9440494721
}
9440594722
}
9440694723
}
9440794724
if( pMatch ){
9440894725
pExpr->iTable = pMatch->iCursor;
94409
- pExpr->pTab = pMatch->pTab;
94726
+ pExpr->y.pTab = pMatch->pTab;
9441094727
/* RIGHT JOIN not (yet) supported */
9441194728
assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
9441294729
if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
9441394730
ExprSetProperty(pExpr, EP_CanBeNull);
9441494731
}
94415
- pSchema = pExpr->pTab->pSchema;
94732
+ pSchema = pExpr->y.pTab->pSchema;
9441694733
}
9441794734
} /* if( pSrcList ) */
9441894735
9441994736
#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
9442094737
/* If we have not already resolved the name, then maybe
@@ -94467,11 +94784,11 @@
9446794784
#ifndef SQLITE_OMIT_UPSERT
9446894785
if( pExpr->iTable==2 ){
9446994786
testcase( iCol==(-1) );
9447094787
if( IN_RENAME_OBJECT ){
9447194788
pExpr->iColumn = iCol;
94472
- pExpr->pTab = pTab;
94789
+ pExpr->y.pTab = pTab;
9447394790
eNewExprOp = TK_COLUMN;
9447494791
}else{
9447594792
pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
9447694793
eNewExprOp = TK_REGISTER;
9447794794
ExprSetProperty(pExpr, EP_Alias);
@@ -94489,11 +94806,11 @@
9448994806
}else{
9449094807
testcase( iCol==31 );
9449194808
testcase( iCol==32 );
9449294809
pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
9449394810
}
94494
- pExpr->pTab = pTab;
94811
+ pExpr->y.pTab = pTab;
9449594812
pExpr->iColumn = (i16)iCol;
9449694813
eNewExprOp = TK_TRIGGER;
9449794814
#endif /* SQLITE_OMIT_TRIGGER */
9449894815
}
9449994816
}
@@ -94589,11 +94906,11 @@
9458994906
*/
9459094907
if( cnt==0 && zTab==0 ){
9459194908
assert( pExpr->op==TK_ID );
9459294909
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
9459394910
pExpr->op = TK_STRING;
94594
- pExpr->pTab = 0;
94911
+ pExpr->y.pTab = 0;
9459594912
return WRC_Prune;
9459694913
}
9459794914
if( sqlite3ExprIdToTrueFalse(pExpr) ){
9459894915
return WRC_Prune;
9459994916
}
@@ -94667,13 +94984,13 @@
9466794984
*/
9466894985
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
9466994986
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
9467094987
if( p ){
9467194988
struct SrcList_item *pItem = &pSrc->a[iSrc];
94672
- p->pTab = pItem->pTab;
94989
+ p->y.pTab = pItem->pTab;
9467394990
p->iTable = pItem->iCursor;
94674
- if( p->pTab->iPKey==iCol ){
94991
+ if( p->y.pTab->iPKey==iCol ){
9467594992
p->iColumn = -1;
9467694993
}else{
9467794994
p->iColumn = (ynVar)iCol;
9467894995
testcase( iCol==BMS );
9467994996
testcase( iCol==BMS-1 );
@@ -94759,11 +95076,11 @@
9475995076
struct SrcList_item *pItem;
9476095077
assert( pSrcList && pSrcList->nSrc==1 );
9476195078
pItem = pSrcList->a;
9476295079
assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
9476395080
pExpr->op = TK_COLUMN;
94764
- pExpr->pTab = pItem->pTab;
95081
+ pExpr->y.pTab = pItem->pTab;
9476595082
pExpr->iTable = pItem->iCursor;
9476695083
pExpr->iColumn = -1;
9476795084
pExpr->affinity = SQLITE_AFF_INTEGER;
9476895085
break;
9476995086
}
@@ -94803,13 +95120,11 @@
9480395120
}
9480495121
zTable = pLeft->u.zToken;
9480595122
zColumn = pRight->u.zToken;
9480695123
if( IN_RENAME_OBJECT ){
9480795124
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
94808
- }
94809
- if( IN_RENAME_OBJECT ){
94810
- sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
95125
+ sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
9481195126
}
9481295127
}
9481395128
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
9481495129
}
9481595130
@@ -94887,30 +95202,39 @@
9488795202
** sqlite_version() that might change over time cannot be used
9488895203
** in an index. */
9488995204
notValid(pParse, pNC, "non-deterministic functions",
9489095205
NC_IdxExpr|NC_PartIdx);
9489195206
}
95207
+ if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
95208
+ && pParse->nested==0
95209
+ && sqlite3Config.bInternalFunctions==0
95210
+ ){
95211
+ /* Internal-use-only functions are disallowed unless the
95212
+ ** SQL is being compiled using sqlite3NestedParse() */
95213
+ no_such_func = 1;
95214
+ pDef = 0;
95215
+ }
9489295216
}
9489395217
9489495218
if( 0==IN_RENAME_OBJECT ){
9489595219
#ifndef SQLITE_OMIT_WINDOWFUNC
9489695220
assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
9489795221
|| (pDef->xValue==0 && pDef->xInverse==0)
9489895222
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
9489995223
);
94900
- if( pDef && pDef->xValue==0 && pExpr->pWin ){
95224
+ if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
9490195225
sqlite3ErrorMsg(pParse,
9490295226
"%.*s() may not be used as a window function", nId, zId
9490395227
);
9490495228
pNC->nErr++;
9490595229
}else if(
9490695230
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
94907
- || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
94908
- || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
95231
+ || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
95232
+ || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
9490995233
){
9491095234
const char *zType;
94911
- if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
95235
+ if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
9491295236
zType = "window";
9491395237
}else{
9491495238
zType = "aggregate";
9491595239
}
9491695240
sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
@@ -94936,30 +95260,30 @@
9493695260
nId, zId);
9493795261
pNC->nErr++;
9493895262
}
9493995263
if( is_agg ){
9494095264
#ifndef SQLITE_OMIT_WINDOWFUNC
94941
- pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
95265
+ pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
9494295266
#else
9494395267
pNC->ncFlags &= ~NC_AllowAgg;
9494495268
#endif
9494595269
}
9494695270
}
9494795271
sqlite3WalkExprList(pWalker, pList);
9494895272
if( is_agg ){
9494995273
#ifndef SQLITE_OMIT_WINDOWFUNC
94950
- if( pExpr->pWin ){
95274
+ if( pExpr->y.pWin ){
9495195275
Select *pSel = pNC->pWinSelect;
94952
- sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
94953
- sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
94954
- sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
94955
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
95276
+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
95277
+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
95278
+ sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
95279
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
9495695280
if( 0==pSel->pWin
94957
- || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin)
95281
+ || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
9495895282
){
94959
- pExpr->pWin->pNextWin = pSel->pWin;
94960
- pSel->pWin = pExpr->pWin;
95283
+ pExpr->y.pWin->pNextWin = pSel->pWin;
95284
+ pSel->pWin = pExpr->y.pWin;
9496195285
}
9496295286
pNC->ncFlags |= NC_AllowWin;
9496395287
}else
9496495288
#endif /* SQLITE_OMIT_WINDOWFUNC */
9496595289
{
@@ -95378,17 +95702,17 @@
9537895702
return 1;
9537995703
}
9538095704
for(j=0; j<pSelect->pEList->nExpr; j++){
9538195705
if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
9538295706
#ifndef SQLITE_OMIT_WINDOWFUNC
95383
- if( pE->pWin ){
95707
+ if( ExprHasProperty(pE, EP_WinFunc) ){
9538495708
/* Since this window function is being changed into a reference
9538595709
** to the same window function the result set, remove the instance
9538695710
** of this window function from the Select.pWin list. */
9538795711
Window **pp;
9538895712
for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
95389
- if( *pp==pE->pWin ){
95713
+ if( *pp==pE->y.pWin ){
9539095714
*pp = (*pp)->pNextWin;
9539195715
}
9539295716
}
9539395717
}
9539495718
#endif
@@ -95847,12 +96171,12 @@
9584796171
if( op==TK_CAST ){
9584896172
assert( !ExprHasProperty(pExpr, EP_IntValue) );
9584996173
return sqlite3AffinityType(pExpr->u.zToken, 0);
9585096174
}
9585196175
#endif
95852
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
95853
- return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
96176
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
96177
+ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
9585496178
}
9585596179
if( op==TK_SELECT_COLUMN ){
9585696180
assert( pExpr->pLeft->flags&EP_xIsSelect );
9585796181
return sqlite3ExprAffinity(
9585896182
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
@@ -95932,17 +96256,17 @@
9593296256
while( p ){
9593396257
int op = p->op;
9593496258
if( p->flags & EP_Generic ) break;
9593596259
if( (op==TK_AGG_COLUMN || op==TK_COLUMN
9593696260
|| op==TK_REGISTER || op==TK_TRIGGER)
95937
- && p->pTab!=0
96261
+ && p->y.pTab!=0
9593896262
){
95939
- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
96263
+ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
9594096264
** a TK_COLUMN but was previously evaluated and cached in a register */
9594196265
int j = p->iColumn;
9594296266
if( j>=0 ){
95943
- const char *zColl = p->pTab->aCol[j].zColl;
96267
+ const char *zColl = p->y.pTab->aCol[j].zColl;
9594496268
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
9594596269
}
9594696270
break;
9594796271
}
9594896272
if( op==TK_CAST || op==TK_UPLUS ){
@@ -96841,10 +97165,14 @@
9684197165
*/
9684297166
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
9684397167
assert( p!=0 );
9684497168
/* Sanity check: Assert that the IntValue is non-negative if it exists */
9684597169
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
97170
+
97171
+ assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
97172
+ assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
97173
+ || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
9684697174
#ifdef SQLITE_DEBUG
9684797175
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
9684897176
assert( p->pLeft==0 );
9684997177
assert( p->pRight==0 );
9685097178
assert( p->x.pSelect==0 );
@@ -96859,12 +97187,13 @@
9685997187
}else if( ExprHasProperty(p, EP_xIsSelect) ){
9686097188
sqlite3SelectDelete(db, p->x.pSelect);
9686197189
}else{
9686297190
sqlite3ExprListDelete(db, p->x.pList);
9686397191
}
96864
- if( !ExprHasProperty(p, EP_Reduced) ){
96865
- sqlite3WindowDelete(db, p->pWin);
97192
+ if( ExprHasProperty(p, EP_WinFunc) ){
97193
+ assert( p->op==TK_FUNCTION );
97194
+ sqlite3WindowDelete(db, p->y.pWin);
9686697195
}
9686797196
}
9686897197
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
9686997198
if( !ExprHasProperty(p, EP_Static) ){
9687097199
sqlite3DbFreeNN(db, p);
@@ -96924,11 +97253,11 @@
9692497253
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
9692597254
assert( EXPR_FULLSIZE<=0xfff );
9692697255
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
9692797256
if( 0==flags || p->op==TK_SELECT_COLUMN
9692897257
#ifndef SQLITE_OMIT_WINDOWFUNC
96929
- || p->pWin
97258
+ || ExprHasProperty(p, EP_WinFunc)
9693097259
#endif
9693197260
){
9693297261
nSize = EXPR_FULLSIZE;
9693397262
}else{
9693497263
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -96951,11 +97280,11 @@
9695197280
** string is defined.)
9695297281
*/
9695397282
static int dupedExprNodeSize(Expr *p, int flags){
9695497283
int nByte = dupedExprStructSize(p, flags) & 0xfff;
9695597284
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
96956
- nByte += sqlite3Strlen30(p->u.zToken)+1;
97285
+ nByte += sqlite3Strlen30NN(p->u.zToken)+1;
9695797286
}
9695897287
return ROUND8(nByte);
9695997288
}
9696097289
9696197290
/*
@@ -97054,26 +97383,28 @@
9705497383
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
9705597384
}
9705697385
}
9705797386
9705897387
/* Fill in pNew->pLeft and pNew->pRight. */
97059
- zAlloc += dupedExprNodeSize(p, dupFlags);
97060
- if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
97388
+ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
97389
+ zAlloc += dupedExprNodeSize(p, dupFlags);
9706197390
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
9706297391
pNew->pLeft = p->pLeft ?
9706397392
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
9706497393
pNew->pRight = p->pRight ?
9706597394
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
9706697395
}
97067
- }else{
9706897396
#ifndef SQLITE_OMIT_WINDOWFUNC
97069
- if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
97070
- pNew->pWin = 0;
97071
- }else{
97072
- pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
97397
+ if( ExprHasProperty(p, EP_WinFunc) ){
97398
+ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
97399
+ assert( ExprHasProperty(pNew, EP_WinFunc) );
9707397400
}
9707497401
#endif /* SQLITE_OMIT_WINDOWFUNC */
97402
+ if( pzBuffer ){
97403
+ *pzBuffer = zAlloc;
97404
+ }
97405
+ }else{
9707597406
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
9707697407
if( pNew->op==TK_SELECT_COLUMN ){
9707797408
pNew->pLeft = p->pLeft;
9707897409
assert( p->iColumn==0 || p->pRight==0 );
9707997410
assert( p->pRight==0 || p->pRight==p->pLeft );
@@ -97081,13 +97412,10 @@
9708197412
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
9708297413
}
9708397414
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
9708497415
}
9708597416
}
97086
- if( pzBuffer ){
97087
- *pzBuffer = zAlloc;
97088
- }
9708997417
}
9709097418
return pNew;
9709197419
}
9709297420
9709397421
/*
@@ -97878,12 +98206,12 @@
9787898206
case TK_FLOAT:
9787998207
case TK_BLOB:
9788098208
return 0;
9788198209
case TK_COLUMN:
9788298210
return ExprHasProperty(p, EP_CanBeNull) ||
97883
- p->pTab==0 || /* Reference to column of index on expression */
97884
- (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
98211
+ p->y.pTab==0 || /* Reference to column of index on expression */
98212
+ (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
9788598213
default:
9788698214
return 1;
9788798215
}
9788898216
}
9788998217
@@ -97934,10 +98262,18 @@
9793498262
if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
9793598263
if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
9793698264
if( sqlite3StrICmp(z, "OID")==0 ) return 1;
9793798265
return 0;
9793898266
}
98267
+#ifdef SQLITE_ENABLE_NORMALIZE
98268
+SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){
98269
+ if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
98270
+ if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
98271
+ if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
98272
+ return 0;
98273
+}
98274
+#endif
9793998275
9794098276
/*
9794198277
** pX is the RHS of an IN operator. If pX is a SELECT statement
9794298278
** that can be simplified to a direct table access, then return
9794398279
** a pointer to the SELECT statement. If pX is not a SELECT statement,
@@ -99167,11 +99503,11 @@
9916799503
** expresssion. However, make sure the constant has the correct
9916899504
** datatype by applying the Affinity of the table column to the
9916999505
** constant.
9917099506
*/
9917199507
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
99172
- int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
99508
+ int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
9917399509
if( aff!=SQLITE_AFF_BLOB ){
9917499510
static const char zAff[] = "B\000C\000D\000E";
9917599511
assert( SQLITE_AFF_BLOB=='A' );
9917699512
assert( SQLITE_AFF_TEXT=='B' );
9917799513
if( iReg!=target ){
@@ -99191,11 +99527,11 @@
9919199527
/* Coding an expression that is part of an index where column names
9919299528
** in the index refer to the table to which the index belongs */
9919399529
iTab = pParse->iSelfTab - 1;
9919499530
}
9919599531
}
99196
- return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
99532
+ return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
9919799533
pExpr->iColumn, iTab, target,
9919899534
pExpr->op2);
9919999535
}
9920099536
case TK_INTEGER: {
9920199537
codeInteger(pParse, pExpr, 0, target);
@@ -99405,12 +99741,12 @@
9940599741
sqlite3 *db = pParse->db; /* The database connection */
9940699742
u8 enc = ENC(db); /* The text encoding used by this database */
9940799743
CollSeq *pColl = 0; /* A collating sequence */
9940899744
9940999745
#ifndef SQLITE_OMIT_WINDOWFUNC
99410
- if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
99411
- return pExpr->pWin->regResult;
99746
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
99747
+ return pExpr->y.pWin->regResult;
9941299748
}
9941399749
#endif
9941499750
9941599751
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
9941699752
/* SQL functions can be expensive. So try to move constant functions
@@ -99649,11 +99985,11 @@
9964999985
**
9965099986
** p1==0 -> old.rowid p1==3 -> new.rowid
9965199987
** p1==1 -> old.a p1==4 -> new.a
9965299988
** p1==2 -> old.b p1==5 -> new.b
9965399989
*/
99654
- Table *pTab = pExpr->pTab;
99990
+ Table *pTab = pExpr->y.pTab;
9965599991
int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
9965699992
9965799993
assert( pExpr->iTable==0 || pExpr->iTable==1 );
9965899994
assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
9965999995
assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
@@ -99660,11 +99996,11 @@
9966099996
assert( p1>=0 && p1<(pTab->nCol*2+2) );
9966199997
9966299998
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
9966399999
VdbeComment((v, "r[%d]=%s.%s", target,
99664100000
(pExpr->iTable ? "new" : "old"),
99665
- (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
100001
+ (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
99666100002
));
99667100003
99668100004
#ifndef SQLITE_OMIT_FLOATING_POINT
99669100005
/* If the column has REAL affinity, it may currently be stored as an
99670100006
** integer. Use OP_RealAffinity to make sure it is really real.
@@ -100511,10 +100847,24 @@
100511100847
return 2;
100512100848
}
100513100849
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
100514100850
if( pA->op==TK_FUNCTION ){
100515100851
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
100852
+#ifndef SQLITE_OMIT_WINDOWFUNC
100853
+ /* Justification for the assert():
100854
+ ** window functions have p->op==TK_FUNCTION but aggregate functions
100855
+ ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
100856
+ ** function and a window function should have failed before reaching
100857
+ ** this point. And, it is not possible to have a window function and
100858
+ ** a scalar function with the same name and number of arguments. So
100859
+ ** if we reach this point, either A and B both window functions or
100860
+ ** neither are a window functions. */
100861
+ assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
100862
+ if( ExprHasProperty(pA,EP_WinFunc) ){
100863
+ if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
100864
+ }
100865
+#endif
100516100866
}else if( pA->op==TK_COLLATE ){
100517100867
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
100518100868
}else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
100519100869
return 2;
100520100870
}
@@ -100530,25 +100880,10 @@
100530100880
if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
100531100881
if( pA->iColumn!=pB->iColumn ) return 2;
100532100882
if( pA->iTable!=pB->iTable
100533100883
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
100534100884
}
100535
-#ifndef SQLITE_OMIT_WINDOWFUNC
100536
- /* Justification for the assert():
100537
- ** window functions have p->op==TK_FUNCTION but aggregate functions
100538
- ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
100539
- ** function and a window function should have failed before reaching
100540
- ** this point. And, it is not possible to have a window function and
100541
- ** a scalar function with the same name and number of arguments. So
100542
- ** if we reach this point, either A and B both window functions or
100543
- ** neither are a window functions. */
100544
- assert( (pA->pWin==0)==(pB->pWin==0) );
100545
-
100546
- if( pA->pWin!=0 ){
100547
- if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
100548
- }
100549
-#endif
100550100885
}
100551100886
return 0;
100552100887
}
100553100888
100554100889
/*
@@ -100685,12 +101020,12 @@
100685101020
testcase( pExpr->op==TK_NE );
100686101021
testcase( pExpr->op==TK_LT );
100687101022
testcase( pExpr->op==TK_LE );
100688101023
testcase( pExpr->op==TK_GT );
100689101024
testcase( pExpr->op==TK_GE );
100690
- if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
100691
- || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
101025
+ if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
101026
+ || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
100692101027
){
100693101028
return WRC_Prune;
100694101029
}
100695101030
default:
100696101031
return WRC_Continue;
@@ -100917,11 +101252,11 @@
100917101252
}
100918101253
if( (k>=pAggInfo->nColumn)
100919101254
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
100920101255
){
100921101256
pCol = &pAggInfo->aCol[k];
100922
- pCol->pTab = pExpr->pTab;
101257
+ pCol->pTab = pExpr->y.pTab;
100923101258
pCol->iTable = pExpr->iTable;
100924101259
pCol->iColumn = pExpr->iColumn;
100925101260
pCol->iMem = ++pParse->nMem;
100926101261
pCol->iSorterColumn = -1;
100927101262
pCol->pExpr = pExpr;
@@ -101800,14 +102135,20 @@
101800102135
#else
101801102136
# define renameTokenCheckAll(x,y)
101802102137
#endif
101803102138
101804102139
/*
101805
-** Add a new RenameToken object mapping parse tree element pPtr into
101806
-** token *pToken to the Parse object currently under construction.
102140
+** Remember that the parser tree element pPtr was created using
102141
+** the token pToken.
101807102142
**
101808
-** Return a copy of pPtr.
102143
+** In other words, construct a new RenameToken object and add it
102144
+** to the list of RenameToken objects currently being built up
102145
+** in pParse->pRename.
102146
+**
102147
+** The pPtr argument is returned so that this routine can be used
102148
+** with tail recursion in tokenExpr() routine, for a small performance
102149
+** improvement.
101809102150
*/
101810102151
SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
101811102152
RenameToken *pNew;
101812102153
assert( pPtr || pParse->db->mallocFailed );
101813102154
renameTokenCheckAll(pParse, pPtr);
@@ -101936,11 +102277,11 @@
101936102277
&& pWalker->pParse->pTriggerTab==p->pTab
101937102278
){
101938102279
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
101939102280
}else if( pExpr->op==TK_COLUMN
101940102281
&& pExpr->iColumn==p->iCol
101941
- && p->pTab==pExpr->pTab
102282
+ && p->pTab==pExpr->y.pTab
101942102283
){
101943102284
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
101944102285
}
101945102286
return WRC_Continue;
101946102287
}
@@ -102194,13 +102535,18 @@
102194102535
assert( pNew->pTabSchema );
102195102536
pParse->pTriggerTab = sqlite3FindTable(db, pNew->table,
102196102537
db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
102197102538
);
102198102539
pParse->eTriggerOp = pNew->op;
102540
+ /* ALWAYS() because if the table of the trigger does not exist, the
102541
+ ** error would have been hit before this point */
102542
+ if( ALWAYS(pParse->pTriggerTab) ){
102543
+ rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
102544
+ }
102199102545
102200102546
/* Resolve symbols in WHEN clause */
102201
- if( pNew->pWhen ){
102547
+ if( rc==SQLITE_OK && pNew->pWhen ){
102202102548
rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
102203102549
}
102204102550
102205102551
for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
102206102552
if( pStep->pSelect ){
@@ -102310,19 +102656,12 @@
102310102656
** Do a column rename operation on the CREATE statement given in zSql.
102311102657
** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
102312102658
** into zNew. The name should be quoted if bQuote is true.
102313102659
**
102314102660
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
102315
-** Though accessible to application code, it is not intended for use by
102316
-** applications. The existance of this function, and the way it works,
102317
-** is subject to change without notice.
102318
-**
102319
-** If any of the parameters are out-of-bounds, then simply return NULL.
102320
-** An out-of-bounds parameter can only occur when the application calls
102321
-** this function directly. The parameters will always be well-formed when
102322
-** this routine is invoked by the bytecode for a legitimate ALTER TABLE
102323
-** statement.
102661
+** It is only accessible to SQL created using sqlite3NestedParse(). It is
102662
+** not reachable from ordinary SQL passed into sqlite3_prepare().
102324102663
*/
102325102664
static void renameColumnFunc(
102326102665
sqlite3_context *context,
102327102666
int NotUsed,
102328102667
sqlite3_value **argv
@@ -102474,12 +102813,12 @@
102474102813
/*
102475102814
** Walker expression callback used by "RENAME TABLE".
102476102815
*/
102477102816
static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
102478102817
RenameCtx *p = pWalker->u.pRename;
102479
- if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
102480
- renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
102818
+ if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
102819
+ renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
102481102820
}
102482102821
return WRC_Continue;
102483102822
}
102484102823
102485102824
/*
@@ -102572,11 +102911,11 @@
102572102911
sqlite3WalkSelect(&sWalker, pTab->pSelect);
102573102912
}
102574102913
}else{
102575102914
/* Modify any FK definitions to point to the new table. */
102576102915
#ifndef SQLITE_OMIT_FOREIGN_KEY
102577
- if( db->flags & SQLITE_ForeignKeys ){
102916
+ if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
102578102917
FKey *pFKey;
102579102918
for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
102580102919
if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
102581102920
renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
102582102921
}
@@ -102726,13 +103065,13 @@
102726103065
/*
102727103066
** Register built-in functions used to help implement ALTER TABLE
102728103067
*/
102729103068
SQLITE_PRIVATE void sqlite3AlterFunctions(void){
102730103069
static FuncDef aAlterTableFuncs[] = {
102731
- FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc),
102732
- FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc),
102733
- FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest),
103070
+ INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
103071
+ INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc),
103072
+ INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest),
102734103073
};
102735103074
sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
102736103075
}
102737103076
#endif /* SQLITE_ALTER_TABLE */
102738103077
@@ -104777,11 +105116,11 @@
104777105116
if( pVfs==0 ) return;
104778105117
pNew = &db->aDb[db->init.iDb];
104779105118
if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
104780105119
pNew->pBt = 0;
104781105120
pNew->pSchema = 0;
104782
- rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
105121
+ rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
104783105122
}else{
104784105123
/* This is a real ATTACH
104785105124
**
104786105125
** Check for the following errors:
104787105126
**
@@ -105457,10 +105796,11 @@
105457105796
int iSrc; /* Index in pTabList->a[] of table being read */
105458105797
int iDb; /* The index of the database the expression refers to */
105459105798
int iCol; /* Index of column in table */
105460105799
105461105800
assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
105801
+ assert( !IN_RENAME_OBJECT || db->xAuth==0 );
105462105802
if( db->xAuth==0 ) return;
105463105803
iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
105464105804
if( iDb<0 ){
105465105805
/* An attempt to read a column out of a subquery or other
105466105806
** temporary table. */
@@ -105513,10 +105853,11 @@
105513105853
int rc;
105514105854
105515105855
/* Don't do any authorization checks if the database is initialising
105516105856
** or if the parser is being invoked from within sqlite3_declare_vtab.
105517105857
*/
105858
+ assert( !IN_RENAME_OBJECT || db->xAuth==0 );
105518105859
if( db->init.busy || IN_SPECIAL_PARSE ){
105519105860
return SQLITE_OK;
105520105861
}
105521105862
105522105863
if( db->xAuth==0 ){
@@ -105936,21 +106277,19 @@
105936106277
105937106278
p = sqlite3FindTable(db, zName, zDbase);
105938106279
if( p==0 ){
105939106280
const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
105940106281
#ifndef SQLITE_OMIT_VIRTUALTABLE
105941
- if( sqlite3FindDbName(db, zDbase)<1 ){
105942
- /* If zName is the not the name of a table in the schema created using
105943
- ** CREATE, then check to see if it is the name of an virtual table that
105944
- ** can be an eponymous virtual table. */
105945
- Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
105946
- if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
105947
- pMod = sqlite3PragmaVtabRegister(db, zName);
105948
- }
105949
- if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
105950
- return pMod->pEpoTab;
105951
- }
106282
+ /* If zName is the not the name of a table in the schema created using
106283
+ ** CREATE, then check to see if it is the name of an virtual table that
106284
+ ** can be an eponymous virtual table. */
106285
+ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
106286
+ if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
106287
+ pMod = sqlite3PragmaVtabRegister(db, zName);
106288
+ }
106289
+ if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
106290
+ return pMod->pEpoTab;
105952106291
}
105953106292
#endif
105954106293
if( (flags & LOCATE_NOERR)==0 ){
105955106294
if( zDbase ){
105956106295
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
@@ -106126,21 +106465,26 @@
106126106465
** "main" and "temp") for a single database connection.
106127106466
*/
106128106467
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
106129106468
int i;
106130106469
sqlite3BtreeEnterAll(db);
106131
- assert( db->nSchemaLock==0 );
106132106470
for(i=0; i<db->nDb; i++){
106133106471
Db *pDb = &db->aDb[i];
106134106472
if( pDb->pSchema ){
106135
- sqlite3SchemaClear(pDb->pSchema);
106473
+ if( db->nSchemaLock==0 ){
106474
+ sqlite3SchemaClear(pDb->pSchema);
106475
+ }else{
106476
+ DbSetProperty(db, i, DB_ResetWanted);
106477
+ }
106136106478
}
106137106479
}
106138106480
db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
106139106481
sqlite3VtabUnlockList(db);
106140106482
sqlite3BtreeLeaveAll(db);
106141
- sqlite3CollapseDatabaseArray(db);
106483
+ if( db->nSchemaLock==0 ){
106484
+ sqlite3CollapseDatabaseArray(db);
106485
+ }
106142106486
}
106143106487
106144106488
/*
106145106489
** This routine is called when a commit occurs.
106146106490
*/
@@ -106213,10 +106557,16 @@
106213106557
/* Delete any foreign keys attached to this table. */
106214106558
sqlite3FkDelete(db, pTable);
106215106559
106216106560
/* Delete the Table structure itself.
106217106561
*/
106562
+#ifdef SQLITE_ENABLE_NORMALIZE
106563
+ if( pTable->pColHash ){
106564
+ sqlite3HashClear(pTable->pColHash);
106565
+ sqlite3_free(pTable->pColHash);
106566
+ }
106567
+#endif
106218106568
sqlite3DeleteColumnNames(db, pTable);
106219106569
sqlite3DbFree(db, pTable->zName);
106220106570
sqlite3DbFree(db, pTable->zColAff);
106221106571
sqlite3SelectDelete(db, pTable->pSelect);
106222106572
sqlite3ExprListDelete(db, pTable->pCheck);
@@ -106370,10 +106720,24 @@
106370106720
iDb = db->init.iDb;
106371106721
*pUnqual = pName1;
106372106722
}
106373106723
return iDb;
106374106724
}
106725
+
106726
+/*
106727
+** True if PRAGMA writable_schema is ON
106728
+*/
106729
+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
106730
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
106731
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
106732
+ SQLITE_WriteSchema );
106733
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
106734
+ SQLITE_Defensive );
106735
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
106736
+ (SQLITE_WriteSchema|SQLITE_Defensive) );
106737
+ return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
106738
+}
106375106739
106376106740
/*
106377106741
** This routine is used to check if the UTF-8 string zName is a legal
106378106742
** unqualified name for a new schema object (table, index, view or
106379106743
** trigger). All names are legal except those that begin with the string
@@ -106380,11 +106744,11 @@
106380106744
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
106381106745
** is reserved for internal use.
106382106746
*/
106383106747
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
106384106748
if( !pParse->db->init.busy && pParse->nested==0
106385
- && (pParse->db->flags & SQLITE_WriteSchema)==0
106749
+ && sqlite3WritableSchema(pParse->db)==0
106386106750
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
106387106751
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
106388106752
return SQLITE_ERROR;
106389106753
}
106390106754
return SQLITE_OK;
@@ -107456,10 +107820,40 @@
107456107820
pPk->nColumn = pTab->nCol;
107457107821
}
107458107822
recomputeColumnsNotIndexed(pPk);
107459107823
}
107460107824
107825
+#ifndef SQLITE_OMIT_VIRTUALTABLE
107826
+/*
107827
+** Return true if zName is a shadow table name in the current database
107828
+** connection.
107829
+**
107830
+** zName is temporarily modified while this routine is running, but is
107831
+** restored to its original value prior to this routine returning.
107832
+*/
107833
+static int isShadowTableName(sqlite3 *db, char *zName){
107834
+ char *zTail; /* Pointer to the last "_" in zName */
107835
+ Table *pTab; /* Table that zName is a shadow of */
107836
+ Module *pMod; /* Module for the virtual table */
107837
+
107838
+ zTail = strrchr(zName, '_');
107839
+ if( zTail==0 ) return 0;
107840
+ *zTail = 0;
107841
+ pTab = sqlite3FindTable(db, zName, 0);
107842
+ *zTail = '_';
107843
+ if( pTab==0 ) return 0;
107844
+ if( !IsVirtual(pTab) ) return 0;
107845
+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
107846
+ if( pMod==0 ) return 0;
107847
+ if( pMod->pModule->iVersion<3 ) return 0;
107848
+ if( pMod->pModule->xShadowName==0 ) return 0;
107849
+ return pMod->pModule->xShadowName(zTail+1);
107850
+}
107851
+#else
107852
+# define isShadowTableName(x,y) 0
107853
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
107854
+
107461107855
/*
107462107856
** This routine is called to report the final ")" that terminates
107463107857
** a CREATE TABLE statement.
107464107858
**
107465107859
** The table structure that other action routines have been building
@@ -107494,10 +107888,14 @@
107494107888
return;
107495107889
}
107496107890
assert( !db->mallocFailed );
107497107891
p = pParse->pNewTable;
107498107892
if( p==0 ) return;
107893
+
107894
+ if( pSelect==0 && isShadowTableName(db, p->zName) ){
107895
+ p->tabFlags |= TF_Shadow;
107896
+ }
107499107897
107500107898
/* If the db->init.busy is 1 it means we are reading the SQL off the
107501107899
** "sqlite_master" or "sqlite_temp_master" table on the disk.
107502107900
** So do not write to the disk again. Extract the root page number
107503107901
** for the table from the db->init.newTnum field. (The page number
@@ -108002,11 +108400,11 @@
108002108400
** erasing iTable (this can happen with an auto-vacuum database).
108003108401
*/
108004108402
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
108005108403
Vdbe *v = sqlite3GetVdbe(pParse);
108006108404
int r1 = sqlite3GetTempReg(pParse);
108007
- assert( iTable>1 );
108405
+ if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
108008108406
sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
108009108407
sqlite3MayAbort(pParse);
108010108408
#ifndef SQLITE_OMIT_AUTOVACUUM
108011108409
/* OP_Destroy stores an in integer r1. If this integer
108012108410
** is non-zero, then it is the root page number of a table moved to
@@ -110457,10 +110855,25 @@
110457110855
return p;
110458110856
}
110459110857
}
110460110858
return 0;
110461110859
}
110860
+#ifdef SQLITE_ENABLE_NORMALIZE
110861
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(
110862
+ int h, /* Hash of the name */
110863
+ const char *zFunc, /* Name of function */
110864
+ int nFunc /* Length of the name */
110865
+){
110866
+ FuncDef *p;
110867
+ for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
110868
+ if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
110869
+ return p;
110870
+ }
110871
+ }
110872
+ return 0;
110873
+}
110874
+#endif /* SQLITE_ENABLE_NORMALIZE */
110462110875
110463110876
/*
110464110877
** Insert a new FuncDef into a FuncDefHash hash table.
110465110878
*/
110466110879
SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
@@ -110470,11 +110883,11 @@
110470110883
int i;
110471110884
for(i=0; i<nDef; i++){
110472110885
FuncDef *pOther;
110473110886
const char *zName = aDef[i].zName;
110474110887
int nName = sqlite3Strlen30(zName);
110475
- int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
110888
+ int h = SQLITE_FUNC_HASH(zName[0], nName);
110476110889
assert( zName[0]>='a' && zName[0]<='z' );
110477110890
pOther = functionSearch(h, zName);
110478110891
if( pOther ){
110479110892
assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
110480110893
aDef[i].pNext = pOther->pNext;
@@ -110549,11 +110962,11 @@
110549110962
** new function. But the FuncDefs for built-in functions are read-only.
110550110963
** So we must not search for built-ins when creating a new function.
110551110964
*/
110552110965
if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
110553110966
bestScore = 0;
110554
- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
110967
+ h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
110555110968
p = functionSearch(h, zName);
110556110969
while( p ){
110557110970
int score = matchQuality(p, nArg, enc);
110558110971
if( score>bestScore ){
110559110972
pBest = p;
@@ -110696,37 +111109,54 @@
110696111109
if( sqlite3IndexedByLookup(pParse, pItem) ){
110697111110
pTab = 0;
110698111111
}
110699111112
return pTab;
110700111113
}
111114
+
111115
+/* Return true if table pTab is read-only.
111116
+**
111117
+** A table is read-only if any of the following are true:
111118
+**
111119
+** 1) It is a virtual table and no implementation of the xUpdate method
111120
+** has been provided
111121
+**
111122
+** 2) It is a system table (i.e. sqlite_master), this call is not
111123
+** part of a nested parse and writable_schema pragma has not
111124
+** been specified
111125
+**
111126
+** 3) The table is a shadow table, the database connection is in
111127
+** defensive mode, and the current sqlite3_prepare()
111128
+** is for a top-level SQL statement.
111129
+*/
111130
+static int tabIsReadOnly(Parse *pParse, Table *pTab){
111131
+ sqlite3 *db;
111132
+ if( IsVirtual(pTab) ){
111133
+ return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
111134
+ }
111135
+ if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
111136
+ db = pParse->db;
111137
+ if( (pTab->tabFlags & TF_Readonly)!=0 ){
111138
+ return sqlite3WritableSchema(db)==0 && pParse->nested==0;
111139
+ }
111140
+ assert( pTab->tabFlags & TF_Shadow );
111141
+ return (db->flags & SQLITE_Defensive)!=0
111142
+#ifndef SQLITE_OMIT_VIRTUALTABLE
111143
+ && db->pVtabCtx==0
111144
+#endif
111145
+ && db->nVdbeExec==0;
111146
+}
110701111147
110702111148
/*
110703111149
** Check to make sure the given table is writable. If it is not
110704111150
** writable, generate an error message and return 1. If it is
110705111151
** writable return 0;
110706111152
*/
110707111153
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
110708
- /* A table is not writable under the following circumstances:
110709
- **
110710
- ** 1) It is a virtual table and no implementation of the xUpdate method
110711
- ** has been provided, or
110712
- ** 2) It is a system table (i.e. sqlite_master), this call is not
110713
- ** part of a nested parse and writable_schema pragma has not
110714
- ** been specified.
110715
- **
110716
- ** In either case leave an error message in pParse and return non-zero.
110717
- */
110718
- if( ( IsVirtual(pTab)
110719
- && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
110720
- || ( (pTab->tabFlags & TF_Readonly)!=0
110721
- && (pParse->db->flags & SQLITE_WriteSchema)==0
110722
- && pParse->nested==0 )
110723
- ){
111154
+ if( tabIsReadOnly(pParse, pTab) ){
110724111155
sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
110725111156
return 1;
110726111157
}
110727
-
110728111158
#ifndef SQLITE_OMIT_VIEW
110729111159
if( !viewOk && pTab->pSelect ){
110730111160
sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
110731111161
return 1;
110732111162
}
@@ -114126,11 +114556,11 @@
114126114556
int iCursor, /* The open cursor on the table */
114127114557
i16 iCol /* The column that is wanted */
114128114558
){
114129114559
Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
114130114560
if( pExpr ){
114131
- pExpr->pTab = pTab;
114561
+ pExpr->y.pTab = pTab;
114132114562
pExpr->iTable = iCursor;
114133114563
pExpr->iColumn = iCol;
114134114564
}
114135114565
return pExpr;
114136114566
}
@@ -115202,11 +115632,12 @@
115202115632
do{
115203115633
zColAff[i--] = 0;
115204115634
}while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
115205115635
pTab->zColAff = zColAff;
115206115636
}
115207
- i = sqlite3Strlen30(zColAff);
115637
+ assert( zColAff!=0 );
115638
+ i = sqlite3Strlen30NN(zColAff);
115208115639
if( i ){
115209115640
if( iReg ){
115210115641
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
115211115642
}else{
115212115643
sqlite3VdbeChangeP4(v, -1, zColAff, i);
@@ -116182,18 +116613,19 @@
116182116613
#ifdef tmask
116183116614
#undef tmask
116184116615
#endif
116185116616
116186116617
/*
116187
-** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
116618
+** Meanings of bits in of pWalker->eCode for
116619
+** sqlite3ExprReferencesUpdatedColumn()
116188116620
*/
116189116621
#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
116190116622
#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
116191116623
116192
-/* This is the Walker callback from checkConstraintUnchanged(). Set
116193
-** bit 0x01 of pWalker->eCode if
116194
-** pWalker->eCode to 0 if this expression node references any of the
116624
+/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
116625
+* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
116626
+** expression node references any of the
116195116627
** columns that are being modifed by an UPDATE statement.
116196116628
*/
116197116629
static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
116198116630
if( pExpr->op==TK_COLUMN ){
116199116631
assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
@@ -116211,16 +116643,25 @@
116211116643
/*
116212116644
** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The
116213116645
** only columns that are modified by the UPDATE are those for which
116214116646
** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
116215116647
**
116216
-** Return true if CHECK constraint pExpr does not use any of the
116648
+** Return true if CHECK constraint pExpr uses any of the
116217116649
** changing columns (or the rowid if it is changing). In other words,
116218
-** return true if this CHECK constraint can be skipped when validating
116650
+** return true if this CHECK constraint must be validated for
116219116651
** the new row in the UPDATE statement.
116652
+**
116653
+** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
116654
+** The operation of this routine is the same - return true if an only if
116655
+** the expression uses one or more of columns identified by the second and
116656
+** third arguments.
116220116657
*/
116221
-static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
116658
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
116659
+ Expr *pExpr, /* The expression to be checked */
116660
+ int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
116661
+ int chngRowid /* True if UPDATE changes the rowid */
116662
+){
116222116663
Walker w;
116223116664
memset(&w, 0, sizeof(w));
116224116665
w.eCode = 0;
116225116666
w.xExprCallback = checkConstraintExprNode;
116226116667
w.u.aiCol = aiChng;
@@ -116231,11 +116672,11 @@
116231116672
}
116232116673
testcase( w.eCode==0 );
116233116674
testcase( w.eCode==CKCNSTRNT_COLUMN );
116234116675
testcase( w.eCode==CKCNSTRNT_ROWID );
116235116676
testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
116236
- return !w.eCode;
116677
+ return w.eCode!=0;
116237116678
}
116238116679
116239116680
/*
116240116681
** Generate code to do constraint checks prior to an INSERT or an UPDATE
116241116682
** on table pTab.
@@ -116437,11 +116878,17 @@
116437116878
pParse->iSelfTab = -(regNewData+1);
116438116879
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
116439116880
for(i=0; i<pCheck->nExpr; i++){
116440116881
int allOk;
116441116882
Expr *pExpr = pCheck->a[i].pExpr;
116442
- if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
116883
+ if( aiChng
116884
+ && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
116885
+ ){
116886
+ /* The check constraints do not reference any of the columns being
116887
+ ** updated so there is no point it verifying the check constraint */
116888
+ continue;
116889
+ }
116443116890
allOk = sqlite3VdbeMakeLabel(v);
116444116891
sqlite3VdbeVerifyAbortable(v, onError);
116445116892
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
116446116893
if( onError==OE_Ignore ){
116447116894
sqlite3VdbeGoto(v, ignoreDest);
@@ -117938,16 +118385,19 @@
117938118385
void (*str_appendchar)(sqlite3_str*, int N, char C);
117939118386
void (*str_reset)(sqlite3_str*);
117940118387
int (*str_errcode)(sqlite3_str*);
117941118388
int (*str_length)(sqlite3_str*);
117942118389
char *(*str_value)(sqlite3_str*);
118390
+ /* Version 3.25.0 and later */
117943118391
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
117944118392
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
117945118393
void (*xFinal)(sqlite3_context*),
117946118394
void (*xValue)(sqlite3_context*),
117947118395
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
117948118396
void(*xDestroy)(void*));
118397
+ /* Version 3.26.0 and later */
118398
+ const char *(*normalized_sql)(sqlite3_stmt*);
117949118399
};
117950118400
117951118401
/*
117952118402
** This is the function signature used for all extension entry points. It
117953118403
** is also defined in the file "loadext.c".
@@ -118231,10 +118681,12 @@
118231118681
#define sqlite3_str_errcode sqlite3_api->str_errcode
118232118682
#define sqlite3_str_length sqlite3_api->str_length
118233118683
#define sqlite3_str_value sqlite3_api->str_value
118234118684
/* Version 3.25.0 and later */
118235118685
#define sqlite3_create_window_function sqlite3_api->create_window_function
118686
+/* Version 3.26.0 and later */
118687
+#define sqlite3_normalized_sql sqlite3_api->normalized_sql
118236118688
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
118237118689
118238118690
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
118239118691
/* This case when the file really is being compiled as a loadable
118240118692
** extension */
@@ -118319,10 +118771,11 @@
118319118771
# define sqlite3_create_module 0
118320118772
# define sqlite3_create_module_v2 0
118321118773
# define sqlite3_declare_vtab 0
118322118774
# define sqlite3_vtab_config 0
118323118775
# define sqlite3_vtab_on_conflict 0
118776
+# define sqlite3_vtab_collation 0
118324118777
#endif
118325118778
118326118779
#ifdef SQLITE_OMIT_SHARED_CACHE
118327118780
# define sqlite3_enable_shared_cache 0
118328118781
#endif
@@ -118686,11 +119139,17 @@
118686119139
sqlite3_str_reset,
118687119140
sqlite3_str_errcode,
118688119141
sqlite3_str_length,
118689119142
sqlite3_str_value,
118690119143
/* Version 3.25.0 and later */
118691
- sqlite3_create_window_function
119144
+ sqlite3_create_window_function,
119145
+ /* Version 3.26.0 and later */
119146
+#ifdef SQLITE_ENABLE_NORMALIZE
119147
+ sqlite3_normalized_sql
119148
+#else
119149
+ 0
119150
+#endif
118692119151
};
118693119152
118694119153
/*
118695119154
** Attempt to load an SQLite extension library contained in the file
118696119155
** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -119136,14 +119595,13 @@
119136119595
#define PragTyp_WAL_AUTOCHECKPOINT 38
119137119596
#define PragTyp_WAL_CHECKPOINT 39
119138119597
#define PragTyp_ACTIVATE_EXTENSIONS 40
119139119598
#define PragTyp_HEXKEY 41
119140119599
#define PragTyp_KEY 42
119141
-#define PragTyp_REKEY 43
119142
-#define PragTyp_LOCK_STATUS 44
119143
-#define PragTyp_PARSER_TRACE 45
119144
-#define PragTyp_STATS 46
119600
+#define PragTyp_LOCK_STATUS 43
119601
+#define PragTyp_PARSER_TRACE 44
119602
+#define PragTyp_STATS 45
119145119603
119146119604
/* Property flags associated with various pragma. */
119147119605
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
119148119606
#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
119149119607
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
@@ -119156,72 +119614,71 @@
119156119614
/* Names of columns for pragmas that return multi-column result
119157119615
** or that return single-column results where the name of the
119158119616
** result column is different from the name of the pragma
119159119617
*/
119160119618
static const char *const pragCName[] = {
119161
- /* 0 */ "cache_size", /* Used by: default_cache_size */
119162
- /* 1 */ "cid", /* Used by: table_info */
119163
- /* 2 */ "name",
119164
- /* 3 */ "type",
119165
- /* 4 */ "notnull",
119166
- /* 5 */ "dflt_value",
119167
- /* 6 */ "pk",
119168
- /* 7 */ "tbl", /* Used by: stats */
119169
- /* 8 */ "idx",
119170
- /* 9 */ "wdth",
119171
- /* 10 */ "hght",
119172
- /* 11 */ "flgs",
119173
- /* 12 */ "seqno", /* Used by: index_info */
119174
- /* 13 */ "cid",
119175
- /* 14 */ "name",
119619
+ /* 0 */ "id", /* Used by: foreign_key_list */
119620
+ /* 1 */ "seq",
119621
+ /* 2 */ "table",
119622
+ /* 3 */ "from",
119623
+ /* 4 */ "to",
119624
+ /* 5 */ "on_update",
119625
+ /* 6 */ "on_delete",
119626
+ /* 7 */ "match",
119627
+ /* 8 */ "cid", /* Used by: table_xinfo */
119628
+ /* 9 */ "name",
119629
+ /* 10 */ "type",
119630
+ /* 11 */ "notnull",
119631
+ /* 12 */ "dflt_value",
119632
+ /* 13 */ "pk",
119633
+ /* 14 */ "hidden",
119634
+ /* table_info reuses 8 */
119176119635
/* 15 */ "seqno", /* Used by: index_xinfo */
119177119636
/* 16 */ "cid",
119178119637
/* 17 */ "name",
119179119638
/* 18 */ "desc",
119180119639
/* 19 */ "coll",
119181119640
/* 20 */ "key",
119182
- /* 21 */ "seq", /* Used by: index_list */
119183
- /* 22 */ "name",
119184
- /* 23 */ "unique",
119185
- /* 24 */ "origin",
119186
- /* 25 */ "partial",
119187
- /* 26 */ "seq", /* Used by: database_list */
119641
+ /* 21 */ "tbl", /* Used by: stats */
119642
+ /* 22 */ "idx",
119643
+ /* 23 */ "wdth",
119644
+ /* 24 */ "hght",
119645
+ /* 25 */ "flgs",
119646
+ /* 26 */ "seq", /* Used by: index_list */
119188119647
/* 27 */ "name",
119189
- /* 28 */ "file",
119190
- /* 29 */ "name", /* Used by: function_list */
119191
- /* 30 */ "builtin",
119192
- /* 31 */ "name", /* Used by: module_list pragma_list */
119193
- /* 32 */ "seq", /* Used by: collation_list */
119194
- /* 33 */ "name",
119195
- /* 34 */ "id", /* Used by: foreign_key_list */
119196
- /* 35 */ "seq",
119197
- /* 36 */ "table",
119198
- /* 37 */ "from",
119199
- /* 38 */ "to",
119200
- /* 39 */ "on_update",
119201
- /* 40 */ "on_delete",
119202
- /* 41 */ "match",
119203
- /* 42 */ "table", /* Used by: foreign_key_check */
119204
- /* 43 */ "rowid",
119205
- /* 44 */ "parent",
119206
- /* 45 */ "fkid",
119207
- /* 46 */ "busy", /* Used by: wal_checkpoint */
119208
- /* 47 */ "log",
119209
- /* 48 */ "checkpointed",
119210
- /* 49 */ "timeout", /* Used by: busy_timeout */
119211
- /* 50 */ "database", /* Used by: lock_status */
119212
- /* 51 */ "status",
119648
+ /* 28 */ "unique",
119649
+ /* 29 */ "origin",
119650
+ /* 30 */ "partial",
119651
+ /* 31 */ "table", /* Used by: foreign_key_check */
119652
+ /* 32 */ "rowid",
119653
+ /* 33 */ "parent",
119654
+ /* 34 */ "fkid",
119655
+ /* index_info reuses 15 */
119656
+ /* 35 */ "seq", /* Used by: database_list */
119657
+ /* 36 */ "name",
119658
+ /* 37 */ "file",
119659
+ /* 38 */ "busy", /* Used by: wal_checkpoint */
119660
+ /* 39 */ "log",
119661
+ /* 40 */ "checkpointed",
119662
+ /* 41 */ "name", /* Used by: function_list */
119663
+ /* 42 */ "builtin",
119664
+ /* collation_list reuses 26 */
119665
+ /* 43 */ "database", /* Used by: lock_status */
119666
+ /* 44 */ "status",
119667
+ /* 45 */ "cache_size", /* Used by: default_cache_size */
119668
+ /* module_list pragma_list reuses 9 */
119669
+ /* 46 */ "timeout", /* Used by: busy_timeout */
119213119670
};
119214119671
119215119672
/* Definitions of all built-in pragmas */
119216119673
typedef struct PragmaName {
119217119674
const char *const zName; /* Name of pragma */
119218119675
u8 ePragTyp; /* PragTyp_XXX value */
119219119676
u8 mPragFlg; /* Zero or more PragFlg_XXX values */
119220119677
u8 iPragCName; /* Start of column names in pragCName[] */
119221119678
u8 nPragCName; /* Num of col names. 0 means use pragma name */
119222
- u32 iArg; /* Extra argument */
119679
+ u64 iArg; /* Extra argument */
119223119680
} PragmaName;
119224119681
static const PragmaName aPragmaName[] = {
119225119682
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
119226119683
{/* zName: */ "activate_extensions",
119227119684
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
@@ -119253,11 +119710,11 @@
119253119710
#endif
119254119711
#endif
119255119712
{/* zName: */ "busy_timeout",
119256119713
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
119257119714
/* ePragFlg: */ PragFlg_Result0,
119258
- /* ColNames: */ 49, 1,
119715
+ /* ColNames: */ 46, 1,
119259119716
/* iArg: */ 0 },
119260119717
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119261119718
{/* zName: */ "cache_size",
119262119719
/* ePragTyp: */ PragTyp_CACHE_SIZE,
119263119720
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
@@ -119290,11 +119747,11 @@
119290119747
#endif
119291119748
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119292119749
{/* zName: */ "collation_list",
119293119750
/* ePragTyp: */ PragTyp_COLLATION_LIST,
119294119751
/* ePragFlg: */ PragFlg_Result0,
119295
- /* ColNames: */ 32, 2,
119752
+ /* ColNames: */ 26, 2,
119296119753
/* iArg: */ 0 },
119297119754
#endif
119298119755
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
119299119756
{/* zName: */ "compile_options",
119300119757
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
@@ -119325,18 +119782,18 @@
119325119782
#endif
119326119783
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119327119784
{/* zName: */ "database_list",
119328119785
/* ePragTyp: */ PragTyp_DATABASE_LIST,
119329119786
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
119330
- /* ColNames: */ 26, 3,
119787
+ /* ColNames: */ 35, 3,
119331119788
/* iArg: */ 0 },
119332119789
#endif
119333119790
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
119334119791
{/* zName: */ "default_cache_size",
119335119792
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
119336119793
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
119337
- /* ColNames: */ 0, 1,
119794
+ /* ColNames: */ 45, 1,
119338119795
/* iArg: */ 0 },
119339119796
#endif
119340119797
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119341119798
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119342119799
{/* zName: */ "defer_foreign_keys",
@@ -119362,18 +119819,18 @@
119362119819
#endif
119363119820
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119364119821
{/* zName: */ "foreign_key_check",
119365119822
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
119366119823
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
119367
- /* ColNames: */ 42, 4,
119824
+ /* ColNames: */ 31, 4,
119368119825
/* iArg: */ 0 },
119369119826
#endif
119370119827
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
119371119828
{/* zName: */ "foreign_key_list",
119372119829
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
119373119830
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119374
- /* ColNames: */ 34, 8,
119831
+ /* ColNames: */ 0, 8,
119375119832
/* iArg: */ 0 },
119376119833
#endif
119377119834
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119378119835
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119379119836
{/* zName: */ "foreign_keys",
@@ -119405,25 +119862,25 @@
119405119862
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119406119863
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
119407119864
{/* zName: */ "function_list",
119408119865
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
119409119866
/* ePragFlg: */ PragFlg_Result0,
119410
- /* ColNames: */ 29, 2,
119867
+ /* ColNames: */ 41, 2,
119411119868
/* iArg: */ 0 },
119412119869
#endif
119413119870
#endif
119414119871
#if defined(SQLITE_HAS_CODEC)
119415119872
{/* zName: */ "hexkey",
119416119873
/* ePragTyp: */ PragTyp_HEXKEY,
119417119874
/* ePragFlg: */ 0,
119418119875
/* ColNames: */ 0, 0,
119419
- /* iArg: */ 0 },
119876
+ /* iArg: */ 2 },
119420119877
{/* zName: */ "hexrekey",
119421119878
/* ePragTyp: */ PragTyp_HEXKEY,
119422119879
/* ePragFlg: */ 0,
119423119880
/* ColNames: */ 0, 0,
119424
- /* iArg: */ 0 },
119881
+ /* iArg: */ 3 },
119425119882
#endif
119426119883
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119427119884
#if !defined(SQLITE_OMIT_CHECK)
119428119885
{/* zName: */ "ignore_check_constraints",
119429119886
/* ePragTyp: */ PragTyp_FLAG,
@@ -119441,16 +119898,16 @@
119441119898
#endif
119442119899
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119443119900
{/* zName: */ "index_info",
119444119901
/* ePragTyp: */ PragTyp_INDEX_INFO,
119445119902
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119446
- /* ColNames: */ 12, 3,
119903
+ /* ColNames: */ 15, 3,
119447119904
/* iArg: */ 0 },
119448119905
{/* zName: */ "index_list",
119449119906
/* ePragTyp: */ PragTyp_INDEX_LIST,
119450119907
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119451
- /* ColNames: */ 21, 5,
119908
+ /* ColNames: */ 26, 5,
119452119909
/* iArg: */ 0 },
119453119910
{/* zName: */ "index_xinfo",
119454119911
/* ePragTyp: */ PragTyp_INDEX_INFO,
119455119912
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119456119913
/* ColNames: */ 15, 6,
@@ -119503,11 +119960,11 @@
119503119960
#endif
119504119961
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
119505119962
{/* zName: */ "lock_status",
119506119963
/* ePragTyp: */ PragTyp_LOCK_STATUS,
119507119964
/* ePragFlg: */ PragFlg_Result0,
119508
- /* ColNames: */ 50, 2,
119965
+ /* ColNames: */ 43, 2,
119509119966
/* iArg: */ 0 },
119510119967
#endif
119511119968
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119512119969
{/* zName: */ "locking_mode",
119513119970
/* ePragTyp: */ PragTyp_LOCKING_MODE,
@@ -119529,11 +119986,11 @@
119529119986
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
119530119987
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
119531119988
{/* zName: */ "module_list",
119532119989
/* ePragTyp: */ PragTyp_MODULE_LIST,
119533119990
/* ePragFlg: */ PragFlg_Result0,
119534
- /* ColNames: */ 31, 1,
119991
+ /* ColNames: */ 9, 1,
119535119992
/* iArg: */ 0 },
119536119993
#endif
119537119994
#endif
119538119995
#endif
119539119996
{/* zName: */ "optimize",
@@ -119562,11 +120019,11 @@
119562120019
#endif
119563120020
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
119564120021
{/* zName: */ "pragma_list",
119565120022
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
119566120023
/* ePragFlg: */ PragFlg_Result0,
119567
- /* ColNames: */ 31, 1,
120024
+ /* ColNames: */ 9, 1,
119568120025
/* iArg: */ 0 },
119569120026
#endif
119570120027
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119571120028
{/* zName: */ "query_only",
119572120029
/* ePragTyp: */ PragTyp_FLAG,
@@ -119593,14 +120050,14 @@
119593120050
/* ColNames: */ 0, 0,
119594120051
/* iArg: */ SQLITE_RecTriggers },
119595120052
#endif
119596120053
#if defined(SQLITE_HAS_CODEC)
119597120054
{/* zName: */ "rekey",
119598
- /* ePragTyp: */ PragTyp_REKEY,
120055
+ /* ePragTyp: */ PragTyp_KEY,
119599120056
/* ePragFlg: */ 0,
119600120057
/* ColNames: */ 0, 0,
119601
- /* iArg: */ 0 },
120058
+ /* iArg: */ 1 },
119602120059
#endif
119603120060
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119604120061
{/* zName: */ "reverse_unordered_selects",
119605120062
/* ePragTyp: */ PragTyp_FLAG,
119606120063
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119649,11 +120106,11 @@
119649120106
#endif
119650120107
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
119651120108
{/* zName: */ "stats",
119652120109
/* ePragTyp: */ PragTyp_STATS,
119653120110
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
119654
- /* ColNames: */ 7, 5,
120111
+ /* ColNames: */ 21, 5,
119655120112
/* iArg: */ 0 },
119656120113
#endif
119657120114
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119658120115
{/* zName: */ "synchronous",
119659120116
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
@@ -119663,12 +120120,17 @@
119663120120
#endif
119664120121
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119665120122
{/* zName: */ "table_info",
119666120123
/* ePragTyp: */ PragTyp_TABLE_INFO,
119667120124
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119668
- /* ColNames: */ 1, 6,
120125
+ /* ColNames: */ 8, 6,
119669120126
/* iArg: */ 0 },
120127
+ {/* zName: */ "table_xinfo",
120128
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
120129
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
120130
+ /* ColNames: */ 8, 7,
120131
+ /* iArg: */ 1 },
119670120132
#endif
119671120133
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119672120134
{/* zName: */ "temp_store",
119673120135
/* ePragTyp: */ PragTyp_TEMP_STORE,
119674120136
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119677,10 +120139,22 @@
119677120139
{/* zName: */ "temp_store_directory",
119678120140
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
119679120141
/* ePragFlg: */ PragFlg_NoColumns1,
119680120142
/* ColNames: */ 0, 0,
119681120143
/* iArg: */ 0 },
120144
+#endif
120145
+#if defined(SQLITE_HAS_CODEC)
120146
+ {/* zName: */ "textkey",
120147
+ /* ePragTyp: */ PragTyp_KEY,
120148
+ /* ePragFlg: */ 0,
120149
+ /* ColNames: */ 0, 0,
120150
+ /* iArg: */ 4 },
120151
+ {/* zName: */ "textrekey",
120152
+ /* ePragTyp: */ PragTyp_KEY,
120153
+ /* ePragFlg: */ 0,
120154
+ /* ColNames: */ 0, 0,
120155
+ /* iArg: */ 5 },
119682120156
#endif
119683120157
{/* zName: */ "threads",
119684120158
/* ePragTyp: */ PragTyp_THREADS,
119685120159
/* ePragFlg: */ PragFlg_Result0,
119686120160
/* ColNames: */ 0, 0,
@@ -119728,22 +120202,22 @@
119728120202
/* ColNames: */ 0, 0,
119729120203
/* iArg: */ 0 },
119730120204
{/* zName: */ "wal_checkpoint",
119731120205
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
119732120206
/* ePragFlg: */ PragFlg_NeedSchema,
119733
- /* ColNames: */ 46, 3,
120207
+ /* ColNames: */ 38, 3,
119734120208
/* iArg: */ 0 },
119735120209
#endif
119736120210
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119737120211
{/* zName: */ "writable_schema",
119738120212
/* ePragTyp: */ PragTyp_FLAG,
119739120213
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
119740120214
/* ColNames: */ 0, 0,
119741
- /* iArg: */ SQLITE_WriteSchema },
120215
+ /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
119742120216
#endif
119743120217
};
119744
-/* Number of pragmas: 61 on by default, 78 total. */
120218
+/* Number of pragmas: 62 on by default, 81 total. */
119745120219
119746120220
/************** End of pragma.h **********************************************/
119747120221
/************** Continuing where we left off in pragma.c *********************/
119748120222
119749120223
/*
@@ -120751,11 +121225,11 @@
120751121225
case PragTyp_FLAG: {
120752121226
if( zRight==0 ){
120753121227
setPragmaResultColumnNames(v, pPragma);
120754121228
returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
120755121229
}else{
120756
- int mask = pPragma->iArg; /* Mask of bits to set or clear. */
121230
+ u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */
120757121231
if( db->autoCommit==0 ){
120758121232
/* Foreign key support may not be enabled or disabled while not
120759121233
** in auto-commit mode. */
120760121234
mask &= ~(SQLITE_ForeignKeys);
120761121235
}
@@ -120800,19 +121274,21 @@
120800121274
*/
120801121275
case PragTyp_TABLE_INFO: if( zRight ){
120802121276
Table *pTab;
120803121277
pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
120804121278
if( pTab ){
121279
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
120805121280
int i, k;
120806121281
int nHidden = 0;
120807121282
Column *pCol;
120808121283
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
120809
- pParse->nMem = 6;
120810
- sqlite3CodeVerifySchema(pParse, iDb);
121284
+ pParse->nMem = 7;
121285
+ sqlite3CodeVerifySchema(pParse, iTabDb);
120811121286
sqlite3ViewGetColumnNames(pParse, pTab);
120812121287
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
120813
- if( IsHiddenColumn(pCol) ){
121288
+ int isHidden = IsHiddenColumn(pCol);
121289
+ if( isHidden && pPragma->iArg==0 ){
120814121290
nHidden++;
120815121291
continue;
120816121292
}
120817121293
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
120818121294
k = 0;
@@ -120820,17 +121296,18 @@
120820121296
k = 1;
120821121297
}else{
120822121298
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
120823121299
}
120824121300
assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
120825
- sqlite3VdbeMultiLoad(v, 1, "issisi",
121301
+ sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
120826121302
i-nHidden,
120827121303
pCol->zName,
120828121304
sqlite3ColumnType(pCol,""),
120829121305
pCol->notNull ? 1 : 0,
120830121306
pCol->pDflt ? pCol->pDflt->u.zToken : 0,
120831
- k);
121307
+ k,
121308
+ isHidden);
120832121309
}
120833121310
}
120834121311
}
120835121312
break;
120836121313
@@ -120864,10 +121341,11 @@
120864121341
case PragTyp_INDEX_INFO: if( zRight ){
120865121342
Index *pIdx;
120866121343
Table *pTab;
120867121344
pIdx = sqlite3FindIndex(db, zRight, zDb);
120868121345
if( pIdx ){
121346
+ int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
120869121347
int i;
120870121348
int mx;
120871121349
if( pPragma->iArg ){
120872121350
/* PRAGMA index_xinfo (newer version with more rows and columns) */
120873121351
mx = pIdx->nColumn;
@@ -120876,11 +121354,11 @@
120876121354
/* PRAGMA index_info (legacy version) */
120877121355
mx = pIdx->nKeyCol;
120878121356
pParse->nMem = 3;
120879121357
}
120880121358
pTab = pIdx->pTable;
120881
- sqlite3CodeVerifySchema(pParse, iDb);
121359
+ sqlite3CodeVerifySchema(pParse, iIdxDb);
120882121360
assert( pParse->nMem<=pPragma->nPragCName );
120883121361
for(i=0; i<mx; i++){
120884121362
i16 cnum = pIdx->aiColumn[i];
120885121363
sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum,
120886121364
cnum<0 ? 0 : pTab->aCol[cnum].zName);
@@ -120900,12 +121378,13 @@
120900121378
Index *pIdx;
120901121379
Table *pTab;
120902121380
int i;
120903121381
pTab = sqlite3FindTable(db, zRight, zDb);
120904121382
if( pTab ){
121383
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
120905121384
pParse->nMem = 5;
120906
- sqlite3CodeVerifySchema(pParse, iDb);
121385
+ sqlite3CodeVerifySchema(pParse, iTabDb);
120907121386
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
120908121387
const char *azOrigin[] = { "c", "u", "pk" };
120909121388
sqlite3VdbeMultiLoad(v, 1, "isisi",
120910121389
i,
120911121390
pIdx->zName,
@@ -120948,10 +121427,11 @@
120948121427
HashElem *j;
120949121428
FuncDef *p;
120950121429
pParse->nMem = 2;
120951121430
for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
120952121431
for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
121432
+ if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
120953121433
sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
120954121434
}
120955121435
}
120956121436
for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
120957121437
p = (FuncDef*)sqliteHashData(j);
@@ -120989,13 +121469,14 @@
120989121469
Table *pTab;
120990121470
pTab = sqlite3FindTable(db, zRight, zDb);
120991121471
if( pTab ){
120992121472
pFK = pTab->pFKey;
120993121473
if( pFK ){
121474
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
120994121475
int i = 0;
120995121476
pParse->nMem = 8;
120996
- sqlite3CodeVerifySchema(pParse, iDb);
121477
+ sqlite3CodeVerifySchema(pParse, iTabDb);
120997121478
while(pFK){
120998121479
int j;
120999121480
for(j=0; j<pFK->nCol; j++){
121000121481
sqlite3VdbeMultiLoad(v, 1, "iissssss",
121001121482
i,
@@ -121036,36 +121517,38 @@
121036121517
121037121518
regResult = pParse->nMem+1;
121038121519
pParse->nMem += 4;
121039121520
regKey = ++pParse->nMem;
121040121521
regRow = ++pParse->nMem;
121041
- sqlite3CodeVerifySchema(pParse, iDb);
121042121522
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
121043121523
while( k ){
121524
+ int iTabDb;
121044121525
if( zRight ){
121045121526
pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
121046121527
k = 0;
121047121528
}else{
121048121529
pTab = (Table*)sqliteHashData(k);
121049121530
k = sqliteHashNext(k);
121050121531
}
121051121532
if( pTab==0 || pTab->pFKey==0 ) continue;
121052
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
121533
+ iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
121534
+ sqlite3CodeVerifySchema(pParse, iTabDb);
121535
+ sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
121053121536
if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
121054
- sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
121537
+ sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
121055121538
sqlite3VdbeLoadString(v, regResult, pTab->zName);
121056121539
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
121057121540
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
121058121541
if( pParent==0 ) continue;
121059121542
pIdx = 0;
121060
- sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
121543
+ sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
121061121544
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
121062121545
if( x==0 ){
121063121546
if( pIdx==0 ){
121064
- sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
121547
+ sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
121065121548
}else{
121066
- sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
121549
+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb);
121067121550
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
121068121551
}
121069121552
}else{
121070121553
k = 0;
121071121554
break;
@@ -121830,16 +122313,28 @@
121830122313
break;
121831122314
}
121832122315
#endif
121833122316
121834122317
#ifdef SQLITE_HAS_CODEC
122318
+ /* Pragma iArg
122319
+ ** ---------- ------
122320
+ ** key 0
122321
+ ** rekey 1
122322
+ ** hexkey 2
122323
+ ** hexrekey 3
122324
+ ** textkey 4
122325
+ ** textrekey 5
122326
+ */
121835122327
case PragTyp_KEY: {
121836
- if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
121837
- break;
121838
- }
121839
- case PragTyp_REKEY: {
121840
- if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
122328
+ if( zRight ){
122329
+ int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
122330
+ if( (pPragma->iArg & 1)==0 ){
122331
+ sqlite3_key_v2(db, zDb, zRight, n);
122332
+ }else{
122333
+ sqlite3_rekey_v2(db, zDb, zRight, n);
122334
+ }
122335
+ }
121841122336
break;
121842122337
}
121843122338
case PragTyp_HEXKEY: {
121844122339
if( zRight ){
121845122340
u8 iByte;
@@ -121847,11 +122342,11 @@
121847122342
char zKey[40];
121848122343
for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
121849122344
iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
121850122345
if( (i&1)!=0 ) zKey[i/2] = iByte;
121851122346
}
121852
- if( (zLeft[3] & 0xf)==0xb ){
122347
+ if( (pPragma->iArg & 1)==0 ){
121853122348
sqlite3_key_v2(db, zDb, zKey, i/2);
121854122349
}else{
121855122350
sqlite3_rekey_v2(db, zDb, zKey, i/2);
121856122351
}
121857122352
}
@@ -122177,11 +122672,12 @@
122177122672
0, /* xRollback - rollback transaction */
122178122673
0, /* xFindFunction - function overloading */
122179122674
0, /* xRename - rename the table */
122180122675
0, /* xSavepoint */
122181122676
0, /* xRelease */
122182
- 0 /* xRollbackTo */
122677
+ 0, /* xRollbackTo */
122678
+ 0 /* xShadowName */
122183122679
};
122184122680
122185122681
/*
122186122682
** Check to see if zTabName is really the name of a pragma. If it is,
122187122683
** then register an eponymous virtual table for that pragma and return
@@ -122530,12 +123026,12 @@
122530123026
}
122531123027
if( db->mallocFailed ){
122532123028
rc = SQLITE_NOMEM_BKPT;
122533123029
sqlite3ResetAllSchemasOfConnection(db);
122534123030
}
122535
- if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
122536
- /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
123031
+ if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
123032
+ /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
122537123033
** the schema loaded, even if errors occurred. In this situation the
122538123034
** current sqlite3_prepare() operation will fail, but the following one
122539123035
** will attempt to compile the supplied statement against whatever subset
122540123036
** of the schema was loaded before the error occurred. The primary
122541123037
** purpose of this is to allow access to the sqlite_master table
@@ -122912,10 +123408,298 @@
122912123408
assert( (rc&db->errMask)==rc );
122913123409
sqlite3_mutex_leave(db->mutex);
122914123410
return rc;
122915123411
}
122916123412
123413
+#ifdef SQLITE_ENABLE_NORMALIZE
123414
+/*
123415
+** Checks if the specified token is a table, column, or function name,
123416
+** based on the databases associated with the statement being prepared.
123417
+** If the function fails, zero is returned and pRc is filled with the
123418
+** error code.
123419
+*/
123420
+static int shouldTreatAsIdentifier(
123421
+ sqlite3 *db, /* Database handle. */
123422
+ const char *zToken, /* Pointer to start of token to be checked */
123423
+ int nToken, /* Length of token to be checked */
123424
+ int *pRc /* Pointer to error code upon failure */
123425
+){
123426
+ int bFound = 0; /* Non-zero if token is an identifier name. */
123427
+ int i, j; /* Database and column loop indexes. */
123428
+ Schema *pSchema; /* Schema for current database. */
123429
+ Hash *pHash; /* Hash table of tables for current database. */
123430
+ HashElem *e; /* Hash element for hash table iteration. */
123431
+ Table *pTab; /* Database table for columns being checked. */
123432
+
123433
+ if( sqlite3IsRowidN(zToken, nToken) ){
123434
+ return 1;
123435
+ }
123436
+ if( nToken>0 ){
123437
+ int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
123438
+ if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
123439
+ }
123440
+ assert( db!=0 );
123441
+ sqlite3_mutex_enter(db->mutex);
123442
+ sqlite3BtreeEnterAll(db);
123443
+ for(i=0; i<db->nDb; i++){
123444
+ pHash = &db->aFunc;
123445
+ if( sqlite3HashFindN(pHash, zToken, nToken) ){
123446
+ bFound = 1;
123447
+ break;
123448
+ }
123449
+ pSchema = db->aDb[i].pSchema;
123450
+ if( pSchema==0 ) continue;
123451
+ pHash = &pSchema->tblHash;
123452
+ if( sqlite3HashFindN(pHash, zToken, nToken) ){
123453
+ bFound = 1;
123454
+ break;
123455
+ }
123456
+ for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
123457
+ pTab = sqliteHashData(e);
123458
+ if( pTab==0 ) continue;
123459
+ pHash = pTab->pColHash;
123460
+ if( pHash==0 ){
123461
+ pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
123462
+ if( pHash ){
123463
+ sqlite3HashInit(pHash);
123464
+ for(j=0; j<pTab->nCol; j++){
123465
+ Column *pCol = &pTab->aCol[j];
123466
+ sqlite3HashInsert(pHash, pCol->zName, pCol);
123467
+ }
123468
+ }else{
123469
+ *pRc = SQLITE_NOMEM_BKPT;
123470
+ bFound = 0;
123471
+ goto done;
123472
+ }
123473
+ }
123474
+ if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
123475
+ bFound = 1;
123476
+ goto done;
123477
+ }
123478
+ }
123479
+ }
123480
+done:
123481
+ sqlite3BtreeLeaveAll(db);
123482
+ sqlite3_mutex_leave(db->mutex);
123483
+ return bFound;
123484
+}
123485
+
123486
+/*
123487
+** Attempt to estimate the final output buffer size needed for the fully
123488
+** normalized version of the specified SQL string. This should take into
123489
+** account any potential expansion that could occur (e.g. via IN clauses
123490
+** being expanded, etc). This size returned is the total number of bytes
123491
+** including the NUL terminator.
123492
+*/
123493
+static int estimateNormalizedSize(
123494
+ const char *zSql, /* The original SQL string */
123495
+ int nSql, /* Length of original SQL string */
123496
+ u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
123497
+){
123498
+ int nOut = nSql + 4;
123499
+ const char *z = zSql;
123500
+ while( nOut<nSql*5 ){
123501
+ while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; }
123502
+ if( z[0]==0 ) break;
123503
+ z++;
123504
+ if( z[0]!='N' && z[0]!='n' ) break;
123505
+ z++;
123506
+ while( sqlite3Isspace(z[0]) ){ z++; }
123507
+ if( z[0]!='(' ) break;
123508
+ z++;
123509
+ nOut += 5; /* ?,?,? */
123510
+ }
123511
+ return nOut;
123512
+}
123513
+
123514
+/*
123515
+** Copy the current token into the output buffer while dealing with quoted
123516
+** identifiers. By default, all letters will be converted into lowercase.
123517
+** If the bUpper flag is set, uppercase will be used. The piOut argument
123518
+** will be used to update the target index into the output string.
123519
+*/
123520
+static void copyNormalizedToken(
123521
+ const char *zSql, /* The original SQL string */
123522
+ int iIn, /* Current index into the original SQL string */
123523
+ int nToken, /* Number of bytes in the current token */
123524
+ int tokenFlags, /* Flags returned by the tokenizer */
123525
+ char *zOut, /* The output string */
123526
+ int *piOut /* Pointer to target index into the output string */
123527
+){
123528
+ int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED;
123529
+ int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD;
123530
+ int j = *piOut, k = 0;
123531
+ for(; k<nToken; k++){
123532
+ if( bQuoted ){
123533
+ if( k==0 && iIn>0 ){
123534
+ zOut[j++] = '"';
123535
+ continue;
123536
+ }else if( k==nToken-1 ){
123537
+ zOut[j++] = '"';
123538
+ continue;
123539
+ }
123540
+ }
123541
+ if( bKeyword ){
123542
+ zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
123543
+ }else{
123544
+ zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
123545
+ }
123546
+ }
123547
+ *piOut = j;
123548
+}
123549
+
123550
+/*
123551
+** Perform normalization of the SQL contained in the prepared statement and
123552
+** store the result in the zNormSql field. The schema for the associated
123553
+** databases are consulted while performing the normalization in order to
123554
+** determine if a token appears to be an identifier. All identifiers are
123555
+** left intact in the normalized SQL and all literals are replaced with a
123556
+** single '?'.
123557
+*/
123558
+SQLITE_PRIVATE void sqlite3Normalize(
123559
+ Vdbe *pVdbe, /* VM being reprepared */
123560
+ const char *zSql, /* The original SQL string */
123561
+ int nSql, /* Size of the input string in bytes */
123562
+ u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
123563
+){
123564
+ sqlite3 *db; /* Database handle. */
123565
+ char *z; /* The output string */
123566
+ int nZ; /* Size of the output string in bytes */
123567
+ int i; /* Next character to read from zSql[] */
123568
+ int j; /* Next character to fill in on z[] */
123569
+ int tokenType = 0; /* Type of the next token */
123570
+ int prevTokenType = 0; /* Type of the previous token, except spaces */
123571
+ int n; /* Size of the next token */
123572
+ int nParen = 0; /* Nesting level of parenthesis */
123573
+ Hash inHash; /* Table of parenthesis levels to output index. */
123574
+
123575
+ db = sqlite3VdbeDb(pVdbe);
123576
+ assert( db!=0 );
123577
+ assert( pVdbe->zNormSql==0 );
123578
+ if( zSql==0 ) return;
123579
+ nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
123580
+ z = sqlite3DbMallocRawNN(db, nZ);
123581
+ if( z==0 ) return;
123582
+ sqlite3HashInit(&inHash);
123583
+ for(i=j=0; i<nSql && zSql[i]; i+=n){
123584
+ int flags = 0;
123585
+ if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
123586
+ n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
123587
+ switch( tokenType ){
123588
+ case TK_SPACE: {
123589
+ break;
123590
+ }
123591
+ case TK_ILLEGAL: {
123592
+ sqlite3DbFree(db, z);
123593
+ sqlite3HashClear(&inHash);
123594
+ return;
123595
+ }
123596
+ case TK_STRING:
123597
+ case TK_INTEGER:
123598
+ case TK_FLOAT:
123599
+ case TK_VARIABLE:
123600
+ case TK_BLOB: {
123601
+ z[j++] = '?';
123602
+ break;
123603
+ }
123604
+ case TK_LP:
123605
+ case TK_RP: {
123606
+ if( tokenType==TK_LP ){
123607
+ nParen++;
123608
+ if( prevTokenType==TK_IN ){
123609
+ assert( nParen<nSql );
123610
+ sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
123611
+ }
123612
+ }else{
123613
+ int jj;
123614
+ assert( nParen<nSql );
123615
+ jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
123616
+ if( jj>0 ){
123617
+ sqlite3HashInsert(&inHash, zSql+nParen, 0);
123618
+ assert( jj+6<nZ );
123619
+ memcpy(z+jj+1, "?,?,?", 5);
123620
+ j = jj+6;
123621
+ assert( nZ-1-j>=0 );
123622
+ assert( nZ-1-j<nZ );
123623
+ memset(z+j, 0, nZ-1-j);
123624
+ }
123625
+ nParen--;
123626
+ }
123627
+ assert( nParen>=0 );
123628
+ /* Fall through */
123629
+ }
123630
+ case TK_MINUS:
123631
+ case TK_SEMI:
123632
+ case TK_PLUS:
123633
+ case TK_STAR:
123634
+ case TK_SLASH:
123635
+ case TK_REM:
123636
+ case TK_EQ:
123637
+ case TK_LE:
123638
+ case TK_NE:
123639
+ case TK_LSHIFT:
123640
+ case TK_LT:
123641
+ case TK_RSHIFT:
123642
+ case TK_GT:
123643
+ case TK_GE:
123644
+ case TK_BITOR:
123645
+ case TK_CONCAT:
123646
+ case TK_COMMA:
123647
+ case TK_BITAND:
123648
+ case TK_BITNOT:
123649
+ case TK_DOT:
123650
+ case TK_IN:
123651
+ case TK_IS:
123652
+ case TK_NOT:
123653
+ case TK_NULL:
123654
+ case TK_ID: {
123655
+ if( tokenType==TK_NULL ){
123656
+ if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
123657
+ /* NULL is a keyword in this case, not a literal value */
123658
+ }else{
123659
+ /* Here the NULL is a literal value */
123660
+ z[j++] = '?';
123661
+ break;
123662
+ }
123663
+ }
123664
+ if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
123665
+ z[j++] = ' ';
123666
+ }
123667
+ if( tokenType==TK_ID ){
123668
+ int i2 = i, n2 = n, rc = SQLITE_OK;
123669
+ if( nParen>0 ){
123670
+ assert( nParen<nSql );
123671
+ sqlite3HashInsert(&inHash, zSql+nParen, 0);
123672
+ }
123673
+ if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
123674
+ if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
123675
+ if( rc!=SQLITE_OK ){
123676
+ sqlite3DbFree(db, z);
123677
+ sqlite3HashClear(&inHash);
123678
+ return;
123679
+ }
123680
+ if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
123681
+ z[j++] = '?';
123682
+ break;
123683
+ }
123684
+ }
123685
+ }
123686
+ copyNormalizedToken(zSql, i, n, flags, z, &j);
123687
+ break;
123688
+ }
123689
+ }
123690
+ }
123691
+ assert( j<nZ && "one" );
123692
+ while( j>0 && z[j-1]==' ' ){ j--; }
123693
+ if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
123694
+ z[j] = 0;
123695
+ assert( j<nZ && "two" );
123696
+ pVdbe->zNormSql = z;
123697
+ sqlite3HashClear(&inHash);
123698
+}
123699
+#endif /* SQLITE_ENABLE_NORMALIZE */
123700
+
122917123701
/*
122918123702
** Rerun the compilation of a statement after a schema change.
122919123703
**
122920123704
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
122921123705
** if the statement cannot be recompiled because another connection has
@@ -123924,11 +124708,11 @@
123924124708
ExprList *pExtra = 0;
123925124709
for(i=0; i<pEList->nExpr; i++){
123926124710
struct ExprList_item *pItem = &pEList->a[i];
123927124711
if( pItem->u.x.iOrderByCol==0 ){
123928124712
Expr *pExpr = pItem->pExpr;
123929
- Table *pTab = pExpr->pTab;
124713
+ Table *pTab = pExpr->y.pTab;
123930124714
if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
123931124715
&& (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
123932124716
){
123933124717
int j;
123934124718
for(j=0; j<nDefer; j++){
@@ -123947,16 +124731,16 @@
123947124731
}
123948124732
for(k=0; k<nKey; k++){
123949124733
Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
123950124734
if( pNew ){
123951124735
pNew->iTable = pExpr->iTable;
123952
- pNew->pTab = pExpr->pTab;
124736
+ pNew->y.pTab = pExpr->y.pTab;
123953124737
pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
123954124738
pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
123955124739
}
123956124740
}
123957
- pSort->aDefer[nDefer].pTab = pExpr->pTab;
124741
+ pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
123958124742
pSort->aDefer[nDefer].iCsr = pExpr->iTable;
123959124743
pSort->aDefer[nDefer].nKey = nKey;
123960124744
nDefer++;
123961124745
}
123962124746
}
@@ -124801,11 +125585,11 @@
124801125585
** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
124802125586
** branch below. */
124803125587
break;
124804125588
}
124805125589
124806
- assert( pTab && pExpr->pTab==pTab );
125590
+ assert( pTab && pExpr->y.pTab==pTab );
124807125591
if( pS ){
124808125592
/* The "table" is actually a sub-select or a view in the FROM clause
124809125593
** of the SELECT statement. Return the declaration type and origin
124810125594
** data for the result-set column of the sub-select.
124811125595
*/
@@ -124986,19 +125770,19 @@
124986125770
for(i=0; i<pEList->nExpr; i++){
124987125771
Expr *p = pEList->a[i].pExpr;
124988125772
124989125773
assert( p!=0 );
124990125774
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
124991
- assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
125775
+ assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
124992125776
if( pEList->a[i].zName ){
124993125777
/* An AS clause always takes first priority */
124994125778
char *zName = pEList->a[i].zName;
124995125779
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
124996125780
}else if( srcName && p->op==TK_COLUMN ){
124997125781
char *zCol;
124998125782
int iCol = p->iColumn;
124999
- pTab = p->pTab;
125783
+ pTab = p->y.pTab;
125000125784
assert( pTab!=0 );
125001125785
if( iCol<0 ) iCol = pTab->iPKey;
125002125786
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
125003125787
if( iCol<0 ){
125004125788
zCol = "rowid";
@@ -125085,11 +125869,11 @@
125085125869
}
125086125870
assert( pColExpr->op!=TK_AGG_COLUMN );
125087125871
if( pColExpr->op==TK_COLUMN ){
125088125872
/* For columns use the column name name */
125089125873
int iCol = pColExpr->iColumn;
125090
- Table *pTab = pColExpr->pTab;
125874
+ Table *pTab = pColExpr->y.pTab;
125091125875
assert( pTab!=0 );
125092125876
if( iCol<0 ) iCol = pTab->iPKey;
125093125877
zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
125094125878
}else if( pColExpr->op==TK_ID ){
125095125879
assert( !ExprHasProperty(pColExpr, EP_IntValue) );
@@ -125438,10 +126222,17 @@
125438126222
int i; /* Loop counter */
125439126223
int rc; /* Result code */
125440126224
ExprList *pOrderBy; /* The ORDER BY clause */
125441126225
Expr *pLimit; /* Saved LIMIT and OFFSET */
125442126226
int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
126227
+
126228
+#ifndef SQLITE_OMIT_WINDOWFUNC
126229
+ if( p->pWin ){
126230
+ sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
126231
+ return;
126232
+ }
126233
+#endif
125443126234
125444126235
/* Obtain authorization to do a recursive query */
125445126236
if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
125446126237
125447126238
/* Process the LIMIT and OFFSET clauses, if they exist */
@@ -127188,11 +127979,11 @@
127188127979
return 1;
127189127980
}
127190127981
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
127191127982
127192127983
/*
127193
-** A structure to keep track of all of the column values that fixed to
127984
+** A structure to keep track of all of the column values that are fixed to
127194127985
** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
127195127986
*/
127196127987
typedef struct WhereConst WhereConst;
127197127988
struct WhereConst {
127198127989
Parse *pParse; /* Parsing context */
@@ -127200,17 +127991,32 @@
127200127991
int nChng; /* Number of times a constant is propagated */
127201127992
Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
127202127993
};
127203127994
127204127995
/*
127205
-** Add a new entry to the pConst object
127996
+** Add a new entry to the pConst object. Except, do not add duplicate
127997
+** pColumn entires.
127206127998
*/
127207127999
static void constInsert(
127208
- WhereConst *pConst,
127209
- Expr *pColumn,
127210
- Expr *pValue
128000
+ WhereConst *pConst, /* The WhereConst into which we are inserting */
128001
+ Expr *pColumn, /* The COLUMN part of the constraint */
128002
+ Expr *pValue /* The VALUE part of the constraint */
127211128003
){
128004
+ int i;
128005
+ assert( pColumn->op==TK_COLUMN );
128006
+
128007
+ /* 2018-10-25 ticket [cf5ed20f]
128008
+ ** Make sure the same pColumn is not inserted more than once */
128009
+ for(i=0; i<pConst->nConst; i++){
128010
+ const Expr *pExpr = pConst->apExpr[i*2];
128011
+ assert( pExpr->op==TK_COLUMN );
128012
+ if( pExpr->iTable==pColumn->iTable
128013
+ && pExpr->iColumn==pColumn->iColumn
128014
+ ){
128015
+ return; /* Already present. Return without doing anything. */
128016
+ }
128017
+ }
127212128018
127213128019
pConst->nConst++;
127214128020
pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
127215128021
pConst->nConst*2*sizeof(Expr*));
127216128022
if( pConst->apExpr==0 ){
@@ -131187,10 +131993,61 @@
131187131993
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
131188131994
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
131189131995
}
131190131996
#endif
131191131997
}
131998
+
131999
+/*
132000
+** Check to see if column iCol of index pIdx references any of the
132001
+** columns defined by aXRef and chngRowid. Return true if it does
132002
+** and false if not. This is an optimization. False-positives are a
132003
+** performance degradation, but false-negatives can result in a corrupt
132004
+** index and incorrect answers.
132005
+**
132006
+** aXRef[j] will be non-negative if column j of the original table is
132007
+** being updated. chngRowid will be true if the rowid of the table is
132008
+** being updated.
132009
+*/
132010
+static int indexColumnIsBeingUpdated(
132011
+ Index *pIdx, /* The index to check */
132012
+ int iCol, /* Which column of the index to check */
132013
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
132014
+ int chngRowid /* true if the rowid is being updated */
132015
+){
132016
+ i16 iIdxCol = pIdx->aiColumn[iCol];
132017
+ assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
132018
+ if( iIdxCol>=0 ){
132019
+ return aXRef[iIdxCol]>=0;
132020
+ }
132021
+ assert( iIdxCol==XN_EXPR );
132022
+ assert( pIdx->aColExpr!=0 );
132023
+ assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
132024
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
132025
+ aXRef,chngRowid);
132026
+}
132027
+
132028
+/*
132029
+** Check to see if index pIdx is a partial index whose conditional
132030
+** expression might change values due to an UPDATE. Return true if
132031
+** the index is subject to change and false if the index is guaranteed
132032
+** to be unchanged. This is an optimization. False-positives are a
132033
+** performance degradation, but false-negatives can result in a corrupt
132034
+** index and incorrect answers.
132035
+**
132036
+** aXRef[j] will be non-negative if column j of the original table is
132037
+** being updated. chngRowid will be true if the rowid of the table is
132038
+** being updated.
132039
+*/
132040
+static int indexWhereClauseMightChange(
132041
+ Index *pIdx, /* The index to check */
132042
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
132043
+ int chngRowid /* true if the rowid is being updated */
132044
+){
132045
+ if( pIdx->pPartIdxWhere==0 ) return 0;
132046
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
132047
+ aXRef, chngRowid);
132048
+}
131192132049
131193132050
/*
131194132051
** Process an UPDATE statement.
131195132052
**
131196132053
** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
@@ -131411,23 +132268,22 @@
131411132268
hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
131412132269
131413132270
/* There is one entry in the aRegIdx[] array for each index on the table
131414132271
** being updated. Fill in aRegIdx[] with a register number that will hold
131415132272
** the key for accessing each index.
131416
- **
131417
- ** FIXME: Be smarter about omitting indexes that use expressions.
131418132273
*/
131419132274
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
131420132275
int reg;
131421
- if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
132276
+ if( chngKey || hasFK>1 || pIdx==pPk
132277
+ || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
132278
+ ){
131422132279
reg = ++pParse->nMem;
131423132280
pParse->nMem += pIdx->nColumn;
131424132281
}else{
131425132282
reg = 0;
131426132283
for(i=0; i<pIdx->nKeyCol; i++){
131427
- i16 iIdxCol = pIdx->aiColumn[i];
131428
- if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
132284
+ if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
131429132285
reg = ++pParse->nMem;
131430132286
pParse->nMem += pIdx->nColumn;
131431132287
if( (onError==OE_Replace)
131432132288
|| (onError==OE_Default && pIdx->onError==OE_Replace)
131433132289
){
@@ -131972,11 +132828,11 @@
131972132828
for(i=0; i<pTab->nCol; i++){
131973132829
if( aXRef[i]>=0 ){
131974132830
sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
131975132831
}else{
131976132832
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
131977
- sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
132833
+ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
131978132834
}
131979132835
}
131980132836
if( HasRowid(pTab) ){
131981132837
sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
131982132838
if( pRowid ){
@@ -132473,11 +133329,12 @@
132473133329
saved_nChange = db->nChange;
132474133330
saved_nTotalChange = db->nTotalChange;
132475133331
saved_mTrace = db->mTrace;
132476133332
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
132477133333
db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
132478
- db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
133334
+ db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder
133335
+ | SQLITE_Defensive | SQLITE_CountRows);
132479133336
db->mTrace = 0;
132480133337
132481133338
zDbMain = db->aDb[iDb].zDbSName;
132482133339
pMain = db->aDb[iDb].pBt;
132483133340
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
@@ -133015,22 +133872,19 @@
133015133872
Token *pName1, /* Name of new table, or database name */
133016133873
Token *pName2, /* Name of new table or NULL */
133017133874
Token *pModuleName, /* Name of the module for the virtual table */
133018133875
int ifNotExists /* No error if the table already exists */
133019133876
){
133020
- int iDb; /* The database the table is being created in */
133021133877
Table *pTable; /* The new virtual table */
133022133878
sqlite3 *db; /* Database connection */
133023133879
133024133880
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
133025133881
pTable = pParse->pNewTable;
133026133882
if( pTable==0 ) return;
133027133883
assert( 0==pTable->pIndex );
133028133884
133029133885
db = pParse->db;
133030
- iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
133031
- assert( iDb>=0 );
133032133886
133033133887
assert( pTable->nModuleArg==0 );
133034133888
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
133035133889
addModuleArgument(db, pTable, 0);
133036133890
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
@@ -133046,10 +133900,12 @@
133046133900
** The first invocation, to obtain permission to INSERT a row into the
133047133901
** sqlite_master table, has already been made by sqlite3StartTable().
133048133902
** The second call, to obtain permission to create the table, is made now.
133049133903
*/
133050133904
if( pTable->azModuleArg ){
133905
+ int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
133906
+ assert( iDb>=0 ); /* The database the table is being created in */
133051133907
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
133052133908
pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
133053133909
}
133054133910
#endif
133055133911
}
@@ -133740,11 +134596,11 @@
133740134596
int rc = 0;
133741134597
133742134598
/* Check to see the left operand is a column in a virtual table */
133743134599
if( NEVER(pExpr==0) ) return pDef;
133744134600
if( pExpr->op!=TK_COLUMN ) return pDef;
133745
- pTab = pExpr->pTab;
134601
+ pTab = pExpr->y.pTab;
133746134602
if( pTab==0 ) return pDef;
133747134603
if( !IsVirtual(pTab) ) return pDef;
133748134604
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
133749134605
assert( pVtab!=0 );
133750134606
assert( pVtab->pModule!=0 );
@@ -134360,15 +135216,36 @@
134360135216
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
134361135217
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
134362135218
int nRecValid; /* Number of valid fields currently in pRec */
134363135219
#endif
134364135220
unsigned int bldFlags; /* SQLITE_BLDF_* flags */
135221
+ unsigned int iPlanLimit; /* Search limiter */
134365135222
};
134366135223
134367135224
/* Allowed values for WhereLoopBuider.bldFlags */
134368135225
#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
134369135226
#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
135227
+
135228
+/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
135229
+** index+constraint combinations the query planner will consider for a
135230
+** particular query. If this parameter is unlimited, then certain
135231
+** pathological queries can spend excess time in the sqlite3WhereBegin()
135232
+** routine. The limit is high enough that is should not impact real-world
135233
+** queries.
135234
+**
135235
+** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is
135236
+** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
135237
+** clause is processed, so that every table in a join is guaranteed to be
135238
+** able to propose a some index+constraint combinations even if the initial
135239
+** baseline limit was exhausted by prior tables of the join.
135240
+*/
135241
+#ifndef SQLITE_QUERY_PLANNER_LIMIT
135242
+# define SQLITE_QUERY_PLANNER_LIMIT 20000
135243
+#endif
135244
+#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
135245
+# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
135246
+#endif
134370135247
134371135248
/*
134372135249
** The WHERE clause processing routine has two halves. The
134373135250
** first part does the start of the WHERE loop and the second
134374135251
** half does the tail of the WHERE loop. An instance of
@@ -134927,11 +135804,11 @@
134927135804
Select *pSelect; /* Pointer to the SELECT on the RHS */
134928135805
134929135806
for(i=iEq; i<pLoop->nLTerm; i++){
134930135807
if( pLoop->aLTerm[i]->pExpr==pX ){
134931135808
int iField = pLoop->aLTerm[i]->iField - 1;
134932
- assert( pOrigRhs->a[iField].pExpr!=0 );
135809
+ if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
134933135810
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
134934135811
pOrigRhs->a[iField].pExpr = 0;
134935135812
assert( pOrigLhs->a[iField].pExpr!=0 );
134936135813
pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
134937135814
pOrigLhs->a[iField].pExpr = 0;
@@ -135619,11 +136496,11 @@
135619136496
IdxExprTrans *pX = p->u.pIdxTrans;
135620136497
if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
135621136498
pExpr->op = TK_COLUMN;
135622136499
pExpr->iTable = pX->iIdxCur;
135623136500
pExpr->iColumn = pX->iIdxCol;
135624
- pExpr->pTab = 0;
136501
+ pExpr->y.pTab = 0;
135625136502
return WRC_Prune;
135626136503
}else{
135627136504
return WRC_Continue;
135628136505
}
135629136506
}
@@ -137019,11 +137896,11 @@
137019137896
|| zNew[0]=='-'
137020137897
|| (zNew[0]+1=='0' && iTo==1)
137021137898
){
137022137899
if( pLeft->op!=TK_COLUMN
137023137900
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
137024
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
137901
+ || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
137025137902
){
137026137903
sqlite3ExprDelete(db, pPrefix);
137027137904
sqlite3ValueFree(pVal);
137028137905
return 0;
137029137906
}
@@ -137120,11 +137997,11 @@
137120137997
**
137121137998
** vtab_column MATCH expression
137122137999
** MATCH(expression,vtab_column)
137123138000
*/
137124138001
pCol = pList->a[1].pExpr;
137125
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
138002
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
137126138003
for(i=0; i<ArraySize(aOp); i++){
137127138004
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
137128138005
*peOp2 = aOp[i].eOp2;
137129138006
*ppRight = pList->a[0].pExpr;
137130138007
*ppLeft = pCol;
@@ -137142,16 +138019,16 @@
137142138019
** Historically, xFindFunction expected to see lower-case function
137143138020
** names. But for this use case, xFindFunction is expected to deal
137144138021
** with function names in an arbitrary case.
137145138022
*/
137146138023
pCol = pList->a[0].pExpr;
137147
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
138024
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
137148138025
sqlite3_vtab *pVtab;
137149138026
sqlite3_module *pMod;
137150138027
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
137151138028
void *pNotUsed;
137152
- pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
138029
+ pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
137153138030
assert( pVtab!=0 );
137154138031
assert( pVtab->pModule!=0 );
137155138032
pMod = (sqlite3_module *)pVtab->pModule;
137156138033
if( pMod->xFindFunction!=0 ){
137157138034
i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
@@ -137165,14 +138042,14 @@
137165138042
}
137166138043
}else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
137167138044
int res = 0;
137168138045
Expr *pLeft = pExpr->pLeft;
137169138046
Expr *pRight = pExpr->pRight;
137170
- if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
138047
+ if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
137171138048
res++;
137172138049
}
137173
- if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
138050
+ if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
137174138051
res++;
137175138052
SWAP(Expr*, pLeft, pRight);
137176138053
}
137177138054
*ppLeft = pLeft;
137178138055
*ppRight = pRight;
@@ -138120,10 +138997,11 @@
138120138997
** Note that the virtual term must be tagged with TERM_VNULL.
138121138998
*/
138122138999
if( pExpr->op==TK_NOTNULL
138123139000
&& pExpr->pLeft->op==TK_COLUMN
138124139001
&& pExpr->pLeft->iColumn>=0
139002
+ && !ExprHasProperty(pExpr, EP_FromJoin)
138125139003
&& OptimizationEnabled(db, SQLITE_Stat34)
138126139004
){
138127139005
Expr *pNewExpr;
138128139006
Expr *pLeft = pExpr->pLeft;
138129139007
int idxNew;
@@ -138311,10 +139189,11 @@
138311139189
pTab = pItem->pTab;
138312139190
assert( pTab!=0 );
138313139191
pArgs = pItem->u1.pFuncArg;
138314139192
if( pArgs==0 ) return;
138315139193
for(j=k=0; j<pArgs->nExpr; j++){
139194
+ Expr *pRhs;
138316139195
while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
138317139196
if( k>=pTab->nCol ){
138318139197
sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
138319139198
pTab->zName, j);
138320139199
return;
@@ -138321,13 +139200,14 @@
138321139200
}
138322139201
pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
138323139202
if( pColRef==0 ) return;
138324139203
pColRef->iTable = pItem->iCursor;
138325139204
pColRef->iColumn = k++;
138326
- pColRef->pTab = pTab;
138327
- pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
138328
- sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
139205
+ pColRef->y.pTab = pTab;
139206
+ pRhs = sqlite3PExpr(pParse, TK_UPLUS,
139207
+ sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
139208
+ pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
138329139209
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
138330139210
}
138331139211
}
138332139212
138333139213
/************** End of whereexpr.c *******************************************/
@@ -139186,11 +140066,10 @@
139186140066
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
139187140067
testcase( pParse->db->mallocFailed );
139188140068
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
139189140069
pTabItem->regResult, 1);
139190140070
sqlite3VdbeGoto(v, addrTop);
139191
- pTabItem->fg.viaCoroutine = 0;
139192140071
}else{
139193140072
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
139194140073
}
139195140074
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
139196140075
sqlite3VdbeJumpHere(v, addrTop);
@@ -139364,13 +140243,15 @@
139364140243
** The table object reference passed as the second argument to this function
139365140244
** must represent a virtual table. This function invokes the xBestIndex()
139366140245
** method of the virtual table with the sqlite3_index_info object that
139367140246
** comes in as the 3rd argument to this function.
139368140247
**
139369
-** If an error occurs, pParse is populated with an error message and a
139370
-** non-zero value is returned. Otherwise, 0 is returned and the output
139371
-** part of the sqlite3_index_info structure is left populated.
140248
+** If an error occurs, pParse is populated with an error message and an
140249
+** appropriate error code is returned. A return of SQLITE_CONSTRAINT from
140250
+** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that
140251
+** the current configuration of "unusable" flags in sqlite3_index_info can
140252
+** not result in a valid plan.
139372140253
**
139373140254
** Whether or not an error is returned, it is the responsibility of the
139374140255
** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
139375140256
** that this is required.
139376140257
*/
@@ -139380,11 +140261,11 @@
139380140261
139381140262
TRACE_IDX_INPUTS(p);
139382140263
rc = pVtab->pModule->xBestIndex(pVtab, p);
139383140264
TRACE_IDX_OUTPUTS(p);
139384140265
139385
- if( rc!=SQLITE_OK ){
140266
+ if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
139386140267
if( rc==SQLITE_NOMEM ){
139387140268
sqlite3OomFault(pParse->db);
139388140269
}else if( !pVtab->zErrMsg ){
139389140270
sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
139390140271
}else{
@@ -139391,23 +140272,11 @@
139391140272
sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
139392140273
}
139393140274
}
139394140275
sqlite3_free(pVtab->zErrMsg);
139395140276
pVtab->zErrMsg = 0;
139396
-
139397
-#if 0
139398
- /* This error is now caught by the caller.
139399
- ** Search for "xBestIndex malfunction" below */
139400
- for(i=0; i<p->nConstraint; i++){
139401
- if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
139402
- sqlite3ErrorMsg(pParse,
139403
- "table %s: xBestIndex returned an invalid plan", pTab->zName);
139404
- }
139405
- }
139406
-#endif
139407
-
139408
- return pParse->nErr;
140277
+ return rc;
139409140278
}
139410140279
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
139411140280
139412140281
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
139413140282
/*
@@ -140457,10 +141326,18 @@
140457141326
static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
140458141327
WhereLoop **ppPrev, *p;
140459141328
WhereInfo *pWInfo = pBuilder->pWInfo;
140460141329
sqlite3 *db = pWInfo->pParse->db;
140461141330
int rc;
141331
+
141332
+ /* Stop the search once we hit the query planner search limit */
141333
+ if( pBuilder->iPlanLimit==0 ){
141334
+ WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
141335
+ if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
141336
+ return SQLITE_DONE;
141337
+ }
141338
+ pBuilder->iPlanLimit--;
140462141339
140463141340
/* If pBuilder->pOrSet is defined, then only keep track of the costs
140464141341
** and prereqs.
140465141342
*/
140466141343
if( pBuilder->pOrSet!=0 ){
@@ -141468,11 +142345,21 @@
141468142345
pIdxInfo->idxFlags = 0;
141469142346
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
141470142347
141471142348
/* Invoke the virtual table xBestIndex() method */
141472142349
rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
141473
- if( rc ) return rc;
142350
+ if( rc ){
142351
+ if( rc==SQLITE_CONSTRAINT ){
142352
+ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
142353
+ ** that the particular combination of parameters provided is unusable.
142354
+ ** Make no entries in the loop table.
142355
+ */
142356
+ WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n"));
142357
+ return SQLITE_OK;
142358
+ }
142359
+ return rc;
142360
+ }
141474142361
141475142362
mxTerm = -1;
141476142363
assert( pNew->nLSlot>=nConstraint );
141477142364
for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
141478142365
pNew->u.vtab.omitMask = 0;
@@ -141864,13 +142751,15 @@
141864142751
u8 priorJointype = 0;
141865142752
141866142753
/* Loop over the tables in the join, from left to right */
141867142754
pNew = pBuilder->pNew;
141868142755
whereLoopInit(pNew);
142756
+ pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
141869142757
for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
141870142758
Bitmask mUnusable = 0;
141871142759
pNew->iTab = iTab;
142760
+ pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
141872142761
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
141873142762
if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
141874142763
/* This condition is true when pItem is the FROM clause term on the
141875142764
** right-hand-side of a LEFT or CROSS JOIN. */
141876142765
mPrereq = mPrior;
@@ -141892,11 +142781,19 @@
141892142781
}
141893142782
if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
141894142783
rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
141895142784
}
141896142785
mPrior |= pNew->maskSelf;
141897
- if( rc || db->mallocFailed ) break;
142786
+ if( rc || db->mallocFailed ){
142787
+ if( rc==SQLITE_DONE ){
142788
+ /* We hit the query planner search limit set by iPlanLimit */
142789
+ sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
142790
+ rc = SQLITE_OK;
142791
+ }else{
142792
+ break;
142793
+ }
142794
+ }
141898142795
}
141899142796
141900142797
whereLoopClear(db, pNew);
141901142798
return rc;
141902142799
}
@@ -144274,16 +145171,16 @@
144274145171
}
144275145172
144276145173
switch( pExpr->op ){
144277145174
144278145175
case TK_FUNCTION:
144279
- if( pExpr->pWin==0 ){
145176
+ if( !ExprHasProperty(pExpr, EP_WinFunc) ){
144280145177
break;
144281145178
}else{
144282145179
Window *pWin;
144283145180
for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
144284
- if( pExpr->pWin==pWin ){
145181
+ if( pExpr->y.pWin==pWin ){
144285145182
assert( pWin->pOwner==pExpr );
144286145183
return WRC_Prune;
144287145184
}
144288145185
}
144289145186
}
@@ -144396,11 +145293,11 @@
144396145293
** are invoked in the correct order as described under "SELECT REWRITING"
144397145294
** at the top of this file.
144398145295
*/
144399145296
SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
144400145297
int rc = SQLITE_OK;
144401
- if( p->pWin ){
145298
+ if( p->pWin && p->pPrior==0 ){
144402145299
Vdbe *v = sqlite3GetVdbe(pParse);
144403145300
sqlite3 *db = pParse->db;
144404145301
Select *pSub = 0; /* The subquery */
144405145302
SrcList *pSrc = p->pSrc;
144406145303
Expr *pWhere = p->pWhere;
@@ -144609,15 +145506,17 @@
144609145506
/*
144610145507
** Attach window object pWin to expression p.
144611145508
*/
144612145509
SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
144613145510
if( p ){
145511
+ assert( p->op==TK_FUNCTION );
144614145512
/* This routine is only called for the parser. If pWin was not
144615145513
** allocated due to an OOM, then the parser would fail before ever
144616145514
** invoking this routine */
144617145515
if( ALWAYS(pWin) ){
144618
- p->pWin = pWin;
145516
+ p->y.pWin = pWin;
145517
+ ExprSetProperty(p, EP_WinFunc);
144619145518
pWin->pOwner = p;
144620145519
if( p->flags & EP_Distinct ){
144621145520
sqlite3ErrorMsg(pParse,
144622145521
"DISTINCT is not supported for window functions");
144623145522
}
@@ -145776,11 +146675,11 @@
145776146675
** third argument. Set the Window.pOwner field of the new object to
145777146676
** pOwner.
145778146677
*/
145779146678
SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
145780146679
Window *pNew = 0;
145781
- if( p ){
146680
+ if( ALWAYS(p) ){
145782146681
pNew = sqlite3DbMallocZero(db, sizeof(Window));
145783146682
if( pNew ){
145784146683
pNew->zName = sqlite3DbStrDup(db, p->zName);
145785146684
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
145786146685
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
@@ -145928,10 +146827,11 @@
145928146827
**
145929146828
** The following is the concatenation of all %include directives from the
145930146829
** input grammar file:
145931146830
*/
145932146831
/* #include <stdio.h> */
146832
+/* #include <assert.h> */
145933146833
/************ Begin %include sections from the grammar ************************/
145934146834
145935146835
/* #include "sqliteInt.h" */
145936146836
145937146837
/*
@@ -146029,17 +146929,14 @@
146029146929
p->flags = EP_Leaf;
146030146930
p->iAgg = -1;
146031146931
p->pLeft = p->pRight = 0;
146032146932
p->x.pList = 0;
146033146933
p->pAggInfo = 0;
146034
- p->pTab = 0;
146934
+ p->y.pTab = 0;
146035146935
p->op2 = 0;
146036146936
p->iTable = 0;
146037146937
p->iColumn = 0;
146038
-#ifndef SQLITE_OMIT_WINDOWFUNC
146039
- p->pWin = 0;
146040
-#endif
146041146938
p->u.zToken = (char*)&p[1];
146042146939
memcpy(p->u.zToken, t.z, t.n);
146043146940
p->u.zToken[t.n] = 0;
146044146941
if( sqlite3Isquote(p->u.zToken[0]) ){
146045146942
if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
@@ -150227,14 +151124,13 @@
150227151124
#endif
150228151125
yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
150229151126
yymajor = YYNOCODE;
150230151127
}else{
150231151128
while( yypParser->yytos >= yypParser->yystack
150232
- && yymx != YYERRORSYMBOL
150233151129
&& (yyact = yy_find_reduce_action(
150234151130
yypParser->yytos->stateno,
150235
- YYERRORSYMBOL)) >= YY_MIN_REDUCE
151131
+ YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
150236151132
){
150237151133
yy_pop_parser_stack(yypParser);
150238151134
}
150239151135
if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
150240151136
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
@@ -151197,10 +152093,77 @@
151197152093
while( IdChar(z[i]) ){ i++; }
151198152094
*tokenType = TK_ID;
151199152095
return i;
151200152096
}
151201152097
152098
+#ifdef SQLITE_ENABLE_NORMALIZE
152099
+/*
152100
+** Return the length (in bytes) of the token that begins at z[0].
152101
+** Store the token type in *tokenType before returning. If flags has
152102
+** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
152103
+** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was
152104
+** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags
152105
+** if the token was recognized as a keyword; this is useful when the
152106
+** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
152107
+** to differentiate between a keyword being treated as an identifier
152108
+** (for normalization purposes) and an actual identifier.
152109
+*/
152110
+SQLITE_PRIVATE int sqlite3GetTokenNormalized(
152111
+ const unsigned char *z,
152112
+ int *tokenType,
152113
+ int *flags
152114
+){
152115
+ int n;
152116
+ unsigned char iClass = aiClass[*z];
152117
+ if( iClass==CC_KYWD ){
152118
+ int i;
152119
+ for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
152120
+ if( IdChar(z[i]) ){
152121
+ /* This token started out using characters that can appear in keywords,
152122
+ ** but z[i] is a character not allowed within keywords, so this must
152123
+ ** be an identifier instead */
152124
+ i++;
152125
+ while( IdChar(z[i]) ){ i++; }
152126
+ *tokenType = TK_ID;
152127
+ return i;
152128
+ }
152129
+ *tokenType = TK_ID;
152130
+ n = keywordCode((char*)z, i, tokenType);
152131
+ /* If the token is no longer considered to be an identifier, then it is a
152132
+ ** keyword of some kind. Make the token back into an identifier and then
152133
+ ** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are
152134
+ ** used verbatim, including IN, IS, NOT, and NULL. */
152135
+ switch( *tokenType ){
152136
+ case TK_ID: {
152137
+ /* do nothing, handled by caller */
152138
+ break;
152139
+ }
152140
+ case TK_IN:
152141
+ case TK_IS:
152142
+ case TK_NOT:
152143
+ case TK_NULL: {
152144
+ *flags |= SQLITE_TOKEN_KEYWORD;
152145
+ break;
152146
+ }
152147
+ default: {
152148
+ *tokenType = TK_ID;
152149
+ *flags |= SQLITE_TOKEN_KEYWORD;
152150
+ break;
152151
+ }
152152
+ }
152153
+ }else{
152154
+ n = sqlite3GetToken(z, tokenType);
152155
+ /* If the token is considered to be an identifier and the character class
152156
+ ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
152157
+ if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
152158
+ *flags |= SQLITE_TOKEN_QUOTED;
152159
+ }
152160
+ }
152161
+ return n;
152162
+}
152163
+#endif /* SQLITE_ENABLE_NORMALIZE */
152164
+
151202152165
/*
151203152166
** Run the parser on the given SQL string. The parser structure is
151204152167
** passed in. An SQLITE_ status code is returned. If an error occurs
151205152168
** then an and attempt is made to write an error message into
151206152169
** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
@@ -152594,10 +153557,11 @@
152594153557
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
152595153558
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
152596153559
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
152597153560
{ SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
152598153561
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
153562
+ { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
152599153563
};
152600153564
unsigned int i;
152601153565
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
152602153566
for(i=0; i<ArraySize(aFlagOp); i++){
152603153567
if( aFlagOp[i].op==op ){
@@ -154821,10 +155785,13 @@
154821155785
| SQLITE_Fts3Tokenizer
154822155786
#endif
154823155787
#if defined(SQLITE_ENABLE_QPSG)
154824155788
| SQLITE_EnableQPSG
154825155789
#endif
155790
+#if defined(SQLITE_DEFAULT_DEFENSIVE)
155791
+ | SQLITE_Defensive
155792
+#endif
154826155793
;
154827155794
sqlite3HashInit(&db->aCollSeq);
154828155795
#ifndef SQLITE_OMIT_VIRTUALTABLE
154829155796
sqlite3HashInit(&db->aModule);
154830155797
#endif
@@ -155708,18 +156675,29 @@
155708156675
break;
155709156676
}
155710156677
155711156678
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
155712156679
**
155713
- ** If parameter onoff is non-zero, configure the wrappers so that all
155714
- ** subsequent calls to localtime() and variants fail. If onoff is zero,
155715
- ** undo this setting.
156680
+ ** If parameter onoff is non-zero, subsequent calls to localtime()
156681
+ ** and its variants fail. If onoff is zero, undo this setting.
155716156682
*/
155717156683
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
155718156684
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
155719156685
break;
155720156686
}
156687
+
156688
+ /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
156689
+ **
156690
+ ** If parameter onoff is non-zero, internal-use-only SQL functions
156691
+ ** are visible to ordinary SQL. This is useful for testing but is
156692
+ ** unsafe because invalid parameters to those internal-use-only functions
156693
+ ** can result in crashes or segfaults.
156694
+ */
156695
+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
156696
+ sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
156697
+ break;
156698
+ }
155721156699
155722156700
/* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
155723156701
**
155724156702
** Set or clear a flag that indicates that the database file is always well-
155725156703
** formed and never corrupt. This flag is clear by default, indicating that
@@ -159159,11 +160137,11 @@
159159160137
){
159160160138
int rc = SQLITE_OK; /* Return code */
159161160139
const char *zCsr = zNode; /* Cursor to iterate through node */
159162160140
const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
159163160141
char *zBuffer = 0; /* Buffer to load terms into */
159164
- int nAlloc = 0; /* Size of allocated buffer */
160142
+ i64 nAlloc = 0; /* Size of allocated buffer */
159165160143
int isFirstTerm = 1; /* True when processing first term on page */
159166160144
sqlite3_int64 iChild; /* Block id of child node to descend to */
159167160145
159168160146
/* Skip over the 'height' varint that occurs at the start of every
159169160147
** interior node. Then load the blockid of the left-child of the b-tree
@@ -159197,18 +160175,18 @@
159197160175
}
159198160176
isFirstTerm = 0;
159199160177
zCsr += fts3GetVarint32(zCsr, &nSuffix);
159200160178
159201160179
assert( nPrefix>=0 && nSuffix>=0 );
159202
- if( &zCsr[nSuffix]>zEnd ){
160180
+ if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
159203160181
rc = FTS_CORRUPT_VTAB;
159204160182
goto finish_scan;
159205160183
}
159206
- if( nPrefix+nSuffix>nAlloc ){
160184
+ if( (i64)nPrefix+nSuffix>nAlloc ){
159207160185
char *zNew;
159208
- nAlloc = (nPrefix+nSuffix) * 2;
159209
- zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
160186
+ nAlloc = ((i64)nPrefix+nSuffix) * 2;
160187
+ zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
159210160188
if( !zNew ){
159211160189
rc = SQLITE_NOMEM;
159212160190
goto finish_scan;
159213160191
}
159214160192
zBuffer = zNew;
@@ -161183,13 +162161,28 @@
161183162161
assert( p->mxSavepoint >= iSavepoint );
161184162162
TESTONLY( p->mxSavepoint = iSavepoint );
161185162163
sqlite3Fts3PendingTermsClear(p);
161186162164
return SQLITE_OK;
161187162165
}
162166
+
162167
+/*
162168
+** Return true if zName is the extension on one of the shadow tables used
162169
+** by this module.
162170
+*/
162171
+static int fts3ShadowName(const char *zName){
162172
+ static const char *azName[] = {
162173
+ "content", "docsize", "segdir", "segments", "stat",
162174
+ };
162175
+ unsigned int i;
162176
+ for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
162177
+ if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
162178
+ }
162179
+ return 0;
162180
+}
161188162181
161189162182
static const sqlite3_module fts3Module = {
161190
- /* iVersion */ 2,
162183
+ /* iVersion */ 3,
161191162184
/* xCreate */ fts3CreateMethod,
161192162185
/* xConnect */ fts3ConnectMethod,
161193162186
/* xBestIndex */ fts3BestIndexMethod,
161194162187
/* xDisconnect */ fts3DisconnectMethod,
161195162188
/* xDestroy */ fts3DestroyMethod,
@@ -161208,10 +162201,11 @@
161208162201
/* xFindFunction */ fts3FindFunctionMethod,
161209162202
/* xRename */ fts3RenameMethod,
161210162203
/* xSavepoint */ fts3SavepointMethod,
161211162204
/* xRelease */ fts3ReleaseMethod,
161212162205
/* xRollbackTo */ fts3RollbackToMethod,
162206
+ /* xShadowName */ fts3ShadowName,
161213162207
};
161214162208
161215162209
/*
161216162210
** This function is registered as the module destructor (called when an
161217162211
** FTS3 enabled database connection is closed). It frees the memory
@@ -161488,10 +162482,11 @@
161488162482
}
161489162483
161490162484
return rc;
161491162485
}
161492162486
162487
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
161493162488
/*
161494162489
** This function is called on each phrase after the position lists for
161495162490
** any deferred tokens have been loaded into memory. It updates the phrases
161496162491
** current position list to include only those positions that are really
161497162492
** instances of the phrase (after considering deferred tokens). If this
@@ -161591,10 +162586,11 @@
161591162586
}
161592162587
}
161593162588
161594162589
return SQLITE_OK;
161595162590
}
162591
+#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
161596162592
161597162593
/*
161598162594
** Maximum number of tokens a phrase may have to be considered for the
161599162595
** incremental doclists strategy.
161600162596
*/
@@ -163839,11 +164835,12 @@
163839164835
0, /* xRollback */
163840164836
0, /* xFindFunction */
163841164837
0, /* xRename */
163842164838
0, /* xSavepoint */
163843164839
0, /* xRelease */
163844
- 0 /* xRollbackTo */
164840
+ 0, /* xRollbackTo */
164841
+ 0 /* xShadowName */
163845164842
};
163846164843
int rc; /* Return code */
163847164844
163848164845
rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
163849164846
return rc;
@@ -167398,11 +168395,12 @@
167398168395
0, /* xRollback */
167399168396
0, /* xFindFunction */
167400168397
0, /* xRename */
167401168398
0, /* xSavepoint */
167402168399
0, /* xRelease */
167403
- 0 /* xRollbackTo */
168400
+ 0, /* xRollbackTo */
168401
+ 0 /* xShadowName */
167404168402
};
167405168403
int rc; /* Return code */
167406168404
167407168405
rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
167408168406
return rc;
@@ -168786,19 +169784,23 @@
168786169784
168787169785
/* Because of the FTS3_NODE_PADDING bytes of padding, the following is
168788169786
** safe (no risk of overread) even if the node data is corrupted. */
168789169787
pNext += fts3GetVarint32(pNext, &nPrefix);
168790169788
pNext += fts3GetVarint32(pNext, &nSuffix);
168791
- if( nPrefix<0 || nSuffix<=0
168792
- || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
169789
+ if( nSuffix<=0
169790
+ || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
169791
+ || nPrefix>pReader->nTermAlloc
168793169792
){
168794169793
return FTS_CORRUPT_VTAB;
168795169794
}
168796169795
168797
- if( nPrefix+nSuffix>pReader->nTermAlloc ){
168798
- int nNew = (nPrefix+nSuffix)*2;
168799
- char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
169796
+ /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
169797
+ ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
169798
+ ** overflow - hence the (i64) casts. */
169799
+ if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
169800
+ i64 nNew = ((i64)nPrefix+nSuffix)*2;
169801
+ char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
168800169802
if( !zNew ){
168801169803
return SQLITE_NOMEM;
168802169804
}
168803169805
pReader->zTerm = zNew;
168804169806
pReader->nTermAlloc = nNew;
@@ -168816,11 +169818,11 @@
168816169818
168817169819
/* Check that the doclist does not appear to extend past the end of the
168818169820
** b-tree node. And that the final byte of the doclist is 0x00. If either
168819169821
** of these statements is untrue, then the data structure is corrupt.
168820169822
*/
168821
- if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
169823
+ if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
168822169824
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
168823169825
){
168824169826
return FTS_CORRUPT_VTAB;
168825169827
}
168826169828
return SQLITE_OK;
@@ -171142,25 +172144,30 @@
171142172144
if( bFirst==0 ){
171143172145
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
171144172146
}
171145172147
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
171146172148
172149
+ if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
172150
+ return SQLITE_CORRUPT_VTAB;
172151
+ }
171147172152
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
171148172153
if( rc==SQLITE_OK ){
171149172154
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
171150172155
p->term.n = nPrefix+nSuffix;
171151172156
p->iOff += nSuffix;
171152172157
if( p->iChild==0 ){
171153172158
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
172159
+ if( (p->nNode-p->iOff)<p->nDoclist ){
172160
+ return SQLITE_CORRUPT_VTAB;
172161
+ }
171154172162
p->aDoclist = &p->aNode[p->iOff];
171155172163
p->iOff += p->nDoclist;
171156172164
}
171157172165
}
171158172166
}
171159172167
171160172168
assert( p->iOff<=p->nNode );
171161
-
171162172169
return rc;
171163172170
}
171164172171
171165172172
/*
171166172173
** Release all dynamic resources held by node-reader object *p.
@@ -177566,10 +178573,13 @@
177566178573
#define JEACH_ATOM 3
177567178574
#define JEACH_ID 4
177568178575
#define JEACH_PARENT 5
177569178576
#define JEACH_FULLKEY 6
177570178577
#define JEACH_PATH 7
178578
+/* The xBestIndex method assumes that the JSON and ROOT columns are
178579
+** the last two columns in the table. Should this ever changes, be
178580
+** sure to update the xBestIndex method. */
177571178581
#define JEACH_JSON 8
177572178582
#define JEACH_ROOT 9
177573178583
177574178584
UNUSED_PARAM(pzErr);
177575178585
UNUSED_PARAM(argv);
@@ -177823,39 +178833,58 @@
177823178833
*/
177824178834
static int jsonEachBestIndex(
177825178835
sqlite3_vtab *tab,
177826178836
sqlite3_index_info *pIdxInfo
177827178837
){
177828
- int i;
177829
- int jsonIdx = -1;
177830
- int rootIdx = -1;
178838
+ int i; /* Loop counter or computed array index */
178839
+ int aIdx[2]; /* Index of constraints for JSON and ROOT */
178840
+ int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */
178841
+ int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */
177831178842
const struct sqlite3_index_constraint *pConstraint;
177832178843
178844
+ /* This implementation assumes that JSON and ROOT are the last two
178845
+ ** columns in the table */
178846
+ assert( JEACH_ROOT == JEACH_JSON+1 );
177833178847
UNUSED_PARAM(tab);
178848
+ aIdx[0] = aIdx[1] = -1;
177834178849
pConstraint = pIdxInfo->aConstraint;
177835178850
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
177836
- if( pConstraint->usable==0 ) continue;
177837
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
177838
- switch( pConstraint->iColumn ){
177839
- case JEACH_JSON: jsonIdx = i; break;
177840
- case JEACH_ROOT: rootIdx = i; break;
177841
- default: /* no-op */ break;
178851
+ int iCol;
178852
+ int iMask;
178853
+ if( pConstraint->iColumn < JEACH_JSON ) continue;
178854
+ iCol = pConstraint->iColumn - JEACH_JSON;
178855
+ assert( iCol==0 || iCol==1 );
178856
+ iMask = 1 << iCol;
178857
+ if( pConstraint->usable==0 ){
178858
+ unusableMask |= iMask;
178859
+ }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
178860
+ aIdx[iCol] = i;
178861
+ idxMask |= iMask;
177842178862
}
177843178863
}
177844
- if( jsonIdx<0 ){
178864
+ if( (unusableMask & ~idxMask)!=0 ){
178865
+ /* If there are any unusable constraints on JSON or ROOT, then reject
178866
+ ** this entire plan */
178867
+ return SQLITE_CONSTRAINT;
178868
+ }
178869
+ if( aIdx[0]<0 ){
178870
+ /* No JSON input. Leave estimatedCost at the huge value that it was
178871
+ ** initialized to to discourage the query planner from selecting this
178872
+ ** plan. */
177845178873
pIdxInfo->idxNum = 0;
177846
- pIdxInfo->estimatedCost = 1e99;
177847178874
}else{
177848178875
pIdxInfo->estimatedCost = 1.0;
177849
- pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
177850
- pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
177851
- if( rootIdx<0 ){
177852
- pIdxInfo->idxNum = 1;
178876
+ i = aIdx[0];
178877
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
178878
+ pIdxInfo->aConstraintUsage[i].omit = 1;
178879
+ if( aIdx[1]<0 ){
178880
+ pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
177853178881
}else{
177854
- pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
177855
- pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
177856
- pIdxInfo->idxNum = 3;
178882
+ i = aIdx[1];
178883
+ pIdxInfo->aConstraintUsage[i].argvIndex = 2;
178884
+ pIdxInfo->aConstraintUsage[i].omit = 1;
178885
+ pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
177857178886
}
177858178887
}
177859178888
return SQLITE_OK;
177860178889
}
177861178890
@@ -177960,11 +178989,12 @@
177960178989
0, /* xRollback */
177961178990
0, /* xFindMethod */
177962178991
0, /* xRename */
177963178992
0, /* xSavepoint */
177964178993
0, /* xRelease */
177965
- 0 /* xRollbackTo */
178994
+ 0, /* xRollbackTo */
178995
+ 0 /* xShadowName */
177966178996
};
177967178997
177968178998
/* The methods of the json_tree virtual table. */
177969178999
static sqlite3_module jsonTreeModule = {
177970179000
0, /* iVersion */
@@ -177987,11 +179017,12 @@
177987179017
0, /* xRollback */
177988179018
0, /* xFindMethod */
177989179019
0, /* xRename */
177990179020
0, /* xSavepoint */
177991179021
0, /* xRelease */
177992
- 0 /* xRollbackTo */
179022
+ 0, /* xRollbackTo */
179023
+ 0 /* xShadowName */
177993179024
};
177994179025
#endif /* SQLITE_OMIT_VIRTUALTABLE */
177995179026
177996179027
/****************************************************************************
177997179028
** The following routines are the only publically visible identifiers in this
@@ -181417,12 +182448,28 @@
181417182448
}
181418182449
181419182450
return rc;
181420182451
}
181421182452
182453
+
182454
+/*
182455
+** Return true if zName is the extension on one of the shadow tables used
182456
+** by this module.
182457
+*/
182458
+static int rtreeShadowName(const char *zName){
182459
+ static const char *azName[] = {
182460
+ "node", "parent", "rowid"
182461
+ };
182462
+ unsigned int i;
182463
+ for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
182464
+ if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
182465
+ }
182466
+ return 0;
182467
+}
182468
+
181422182469
static sqlite3_module rtreeModule = {
181423
- 2, /* iVersion */
182470
+ 3, /* iVersion */
181424182471
rtreeCreate, /* xCreate - create a table */
181425182472
rtreeConnect, /* xConnect - connect to an existing table */
181426182473
rtreeBestIndex, /* xBestIndex - Determine search strategy */
181427182474
rtreeDisconnect, /* xDisconnect - Disconnect from a table */
181428182475
rtreeDestroy, /* xDestroy - Drop a table */
@@ -181441,10 +182488,11 @@
181441182488
0, /* xFindFunction - function overloading */
181442182489
rtreeRename, /* xRename - rename the table */
181443182490
rtreeSavepoint, /* xSavepoint */
181444182491
0, /* xRelease */
181445182492
0, /* xRollbackTo */
182493
+ rtreeShadowName /* xShadowName */
181446182494
};
181447182495
181448182496
static int rtreeSqlInit(
181449182497
Rtree *pRtree,
181450182498
sqlite3 *db,
@@ -182431,17 +183479,27 @@
182431183479
** The on-disk representation consists of a 4-byte header followed by
182432183480
** the values. The 4-byte header is:
182433183481
**
182434183482
** encoding (1 byte) 0=big-endian, 1=little-endian
182435183483
** nvertex (3 bytes) Number of vertexes as a big-endian integer
183484
+**
183485
+** Enough space is allocated for 4 coordinates, to work around over-zealous
183486
+** warnings coming from some compiler (notably, clang). In reality, the size
183487
+** of each GeoPoly memory allocate is adjusted as necessary so that the
183488
+** GeoPoly.a[] array at the end is the appropriate size.
182436183489
*/
182437183490
typedef struct GeoPoly GeoPoly;
182438183491
struct GeoPoly {
182439183492
int nVertex; /* Number of vertexes */
182440183493
unsigned char hdr[4]; /* Header for on-disk representation */
182441
- GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */
183494
+ GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */
182442183495
};
183496
+
183497
+/* The size of a memory allocation needed for a GeoPoly object sufficient
183498
+** to hold N coordinate pairs.
183499
+*/
183500
+#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
182443183501
182444183502
/*
182445183503
** State of a parse of a GeoJSON input.
182446183504
*/
182447183505
typedef struct GeoParse GeoParse;
@@ -182463,11 +183521,11 @@
182463183521
a[2] = t;
182464183522
}
182465183523
182466183524
/* Skip whitespace. Return the next non-whitespace character. */
182467183525
static char geopolySkipSpace(GeoParse *p){
182468
- while( p->z[0] && safe_isspace(p->z[0]) ) p->z++;
183526
+ while( safe_isspace(p->z[0]) ) p->z++;
182469183527
return p->z[0];
182470183528
}
182471183529
182472183530
/* Parse out a number. Write the value into *pVal if pVal!=0.
182473183531
** return non-zero on success and zero if the next token is not a number.
@@ -182483,11 +183541,11 @@
182483183541
c = z[j];
182484183542
}
182485183543
if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
182486183544
for(;; j++){
182487183545
c = z[j];
182488
- if( c>='0' && c<='9' ) continue;
183546
+ if( safe_isdigit(c) ) continue;
182489183547
if( c=='.' ){
182490183548
if( z[j-1]=='-' ) return 0;
182491183549
if( seenDP ) return 0;
182492183550
seenDP = 1;
182493183551
continue;
@@ -182505,11 +183563,21 @@
182505183563
continue;
182506183564
}
182507183565
break;
182508183566
}
182509183567
if( z[j-1]<'0' ) return 0;
182510
- if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
183568
+ if( pVal ){
183569
+#ifdef SQLITE_AMALGAMATION
183570
+ /* The sqlite3AtoF() routine is much much faster than atof(), if it
183571
+ ** is available */
183572
+ double r;
183573
+ (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
183574
+ *pVal = r;
183575
+#else
183576
+ *pVal = (GeoCoord)atof((const char*)p->z);
183577
+#endif
183578
+ }
182511183579
p->z += j;
182512183580
return 1;
182513183581
}
182514183582
182515183583
/*
@@ -182563,16 +183631,14 @@
182563183631
&& s.nVertex>=4
182564183632
&& s.a[0]==s.a[s.nVertex*2-2]
182565183633
&& s.a[1]==s.a[s.nVertex*2-1]
182566183634
&& (s.z++, geopolySkipSpace(&s)==0)
182567183635
){
182568
- int nByte;
182569183636
GeoPoly *pOut;
182570183637
int x = 1;
182571183638
s.nVertex--; /* Remove the redundant vertex at the end */
182572
- nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
182573
- pOut = sqlite3_malloc64( nByte );
183639
+ pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
182574183640
x = 1;
182575183641
if( pOut==0 ) goto parse_json_err;
182576183642
pOut->nVertex = s.nVertex;
182577183643
memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
182578183644
pOut->hdr[0] = *(unsigned char*)&x;
@@ -182770,10 +183836,31 @@
182770183836
sqlite3_result_blob(context, p->hdr,
182771183837
4+8*p->nVertex, SQLITE_TRANSIENT);
182772183838
sqlite3_free(p);
182773183839
}
182774183840
}
183841
+
183842
+/*
183843
+** Compute the area enclosed by the polygon.
183844
+**
183845
+** This routine can also be used to detect polygons that rotate in
183846
+** the wrong direction. Polygons are suppose to be counter-clockwise (CCW).
183847
+** This routine returns a negative value for clockwise (CW) polygons.
183848
+*/
183849
+static double geopolyArea(GeoPoly *p){
183850
+ double rArea = 0.0;
183851
+ int ii;
183852
+ for(ii=0; ii<p->nVertex-1; ii++){
183853
+ rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
183854
+ * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
183855
+ * 0.5;
183856
+ }
183857
+ rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
183858
+ * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
183859
+ * 0.5;
183860
+ return rArea;
183861
+}
182775183862
182776183863
/*
182777183864
** Implementation of the geopoly_area(X) function.
182778183865
**
182779183866
** If the input is a well-formed Geopoly BLOB then return the area
@@ -182786,24 +183873,109 @@
182786183873
int argc,
182787183874
sqlite3_value **argv
182788183875
){
182789183876
GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
182790183877
if( p ){
182791
- double rArea = 0.0;
182792
- int ii;
182793
- for(ii=0; ii<p->nVertex-1; ii++){
182794
- rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
182795
- * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
182796
- * 0.5;
182797
- }
182798
- rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
182799
- * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
182800
- * 0.5;
182801
- sqlite3_result_double(context, rArea);
183878
+ sqlite3_result_double(context, geopolyArea(p));
183879
+ sqlite3_free(p);
183880
+ }
183881
+}
183882
+
183883
+/*
183884
+** Implementation of the geopoly_ccw(X) function.
183885
+**
183886
+** If the rotation of polygon X is clockwise (incorrect) instead of
183887
+** counter-clockwise (the correct winding order according to RFC7946)
183888
+** then reverse the order of the vertexes in polygon X.
183889
+**
183890
+** In other words, this routine returns a CCW polygon regardless of the
183891
+** winding order of its input.
183892
+**
183893
+** Use this routine to sanitize historical inputs that that sometimes
183894
+** contain polygons that wind in the wrong direction.
183895
+*/
183896
+static void geopolyCcwFunc(
183897
+ sqlite3_context *context,
183898
+ int argc,
183899
+ sqlite3_value **argv
183900
+){
183901
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
183902
+ if( p ){
183903
+ if( geopolyArea(p)<0.0 ){
183904
+ int ii, jj;
183905
+ for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){
183906
+ GeoCoord t = p->a[ii];
183907
+ p->a[ii] = p->a[jj];
183908
+ p->a[jj] = t;
183909
+ t = p->a[ii+1];
183910
+ p->a[ii+1] = p->a[jj+1];
183911
+ p->a[jj+1] = t;
183912
+ }
183913
+ }
183914
+ sqlite3_result_blob(context, p->hdr,
183915
+ 4+8*p->nVertex, SQLITE_TRANSIENT);
182802183916
sqlite3_free(p);
182803183917
}
182804183918
}
183919
+
183920
+#define GEOPOLY_PI 3.1415926535897932385
183921
+
183922
+/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
183923
+*/
183924
+static double geopolySine(double r){
183925
+ assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
183926
+ if( r>=1.5*GEOPOLY_PI ){
183927
+ r -= 2.0*GEOPOLY_PI;
183928
+ }
183929
+ if( r>=0.5*GEOPOLY_PI ){
183930
+ return -geopolySine(r-GEOPOLY_PI);
183931
+ }else{
183932
+ double r2 = r*r;
183933
+ double r3 = r2*r;
183934
+ double r5 = r3*r2;
183935
+ return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
183936
+ }
183937
+}
183938
+
183939
+/*
183940
+** Function: geopoly_regular(X,Y,R,N)
183941
+**
183942
+** Construct a simple, convex, regular polygon centered at X, Y
183943
+** with circumradius R and with N sides.
183944
+*/
183945
+static void geopolyRegularFunc(
183946
+ sqlite3_context *context,
183947
+ int argc,
183948
+ sqlite3_value **argv
183949
+){
183950
+ double x = sqlite3_value_double(argv[0]);
183951
+ double y = sqlite3_value_double(argv[1]);
183952
+ double r = sqlite3_value_double(argv[2]);
183953
+ int n = sqlite3_value_int(argv[3]);
183954
+ int i;
183955
+ GeoPoly *p;
183956
+
183957
+ if( n<3 || r<=0.0 ) return;
183958
+ if( n>1000 ) n = 1000;
183959
+ p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
183960
+ if( p==0 ){
183961
+ sqlite3_result_error_nomem(context);
183962
+ return;
183963
+ }
183964
+ i = 1;
183965
+ p->hdr[0] = *(unsigned char*)&i;
183966
+ p->hdr[1] = 0;
183967
+ p->hdr[2] = (n>>8)&0xff;
183968
+ p->hdr[3] = n&0xff;
183969
+ for(i=0; i<n; i++){
183970
+ double rAngle = 2.0*GEOPOLY_PI*i/n;
183971
+ p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
183972
+ p->a[i*2+1] = y + r*geopolySine(rAngle);
183973
+ }
183974
+ sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
183975
+ sqlite3_free(p);
183976
+}
182805183977
182806183978
/*
182807183979
** If pPoly is a polygon, compute its bounding box. Then:
182808183980
**
182809183981
** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
@@ -182845,11 +184017,11 @@
182845184017
else if( r>mxY ) mxY = (float)r;
182846184018
}
182847184019
if( pRc ) *pRc = SQLITE_OK;
182848184020
if( aCoord==0 ){
182849184021
geopolyBboxFill:
182850
- pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
184022
+ pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
182851184023
if( pOut==0 ){
182852184024
sqlite3_free(p);
182853184025
if( context ) sqlite3_result_error_nomem(context);
182854184026
if( pRc ) *pRc = SQLITE_NOMEM;
182855184027
return 0;
@@ -183873,11 +185045,20 @@
183873185045
sqlite3_bind_int64(pUp, 1, cell.iRowid);
183874185046
assert( pRtree->nAux>=1 );
183875185047
if( sqlite3_value_nochange(aData[2]) ){
183876185048
sqlite3_bind_null(pUp, 2);
183877185049
}else{
183878
- sqlite3_bind_value(pUp, 2, aData[2]);
185050
+ GeoPoly *p = 0;
185051
+ if( sqlite3_value_type(aData[2])==SQLITE_TEXT
185052
+ && (p = geopolyFuncParam(0, aData[2], &rc))!=0
185053
+ && rc==SQLITE_OK
185054
+ ){
185055
+ sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
185056
+ }else{
185057
+ sqlite3_bind_value(pUp, 2, aData[2]);
185058
+ }
185059
+ sqlite3_free(p);
183879185060
nChange = 1;
183880185061
}
183881185062
for(jj=1; jj<pRtree->nAux; jj++){
183882185063
nChange++;
183883185064
sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
@@ -183917,11 +185098,11 @@
183917185098
return 0;
183918185099
}
183919185100
183920185101
183921185102
static sqlite3_module geopolyModule = {
183922
- 2, /* iVersion */
185103
+ 3, /* iVersion */
183923185104
geopolyCreate, /* xCreate - create a table */
183924185105
geopolyConnect, /* xConnect - connect to an existing table */
183925185106
geopolyBestIndex, /* xBestIndex - Determine search strategy */
183926185107
rtreeDisconnect, /* xDisconnect - Disconnect from a table */
183927185108
rtreeDestroy, /* xDestroy - Drop a table */
@@ -183940,29 +185121,33 @@
183940185121
geopolyFindFunction, /* xFindFunction - function overloading */
183941185122
rtreeRename, /* xRename - rename the table */
183942185123
rtreeSavepoint, /* xSavepoint */
183943185124
0, /* xRelease */
183944185125
0, /* xRollbackTo */
185126
+ rtreeShadowName /* xShadowName */
183945185127
};
183946185128
183947185129
static int sqlite3_geopoly_init(sqlite3 *db){
183948185130
int rc = SQLITE_OK;
183949185131
static const struct {
183950185132
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
183951
- int nArg;
185133
+ signed char nArg;
185134
+ unsigned char bPure;
183952185135
const char *zName;
183953185136
} aFunc[] = {
183954
- { geopolyAreaFunc, 1, "geopoly_area" },
183955
- { geopolyBlobFunc, 1, "geopoly_blob" },
183956
- { geopolyJsonFunc, 1, "geopoly_json" },
183957
- { geopolySvgFunc, -1, "geopoly_svg" },
183958
- { geopolyWithinFunc, 2, "geopoly_within" },
183959
- { geopolyContainsPointFunc, 3, "geopoly_contains_point" },
183960
- { geopolyOverlapFunc, 2, "geopoly_overlap" },
183961
- { geopolyDebugFunc, 1, "geopoly_debug" },
183962
- { geopolyBBoxFunc, 1, "geopoly_bbox" },
183963
- { geopolyXformFunc, 7, "geopoly_xform" },
185137
+ { geopolyAreaFunc, 1, 1, "geopoly_area" },
185138
+ { geopolyBlobFunc, 1, 1, "geopoly_blob" },
185139
+ { geopolyJsonFunc, 1, 1, "geopoly_json" },
185140
+ { geopolySvgFunc, -1, 1, "geopoly_svg" },
185141
+ { geopolyWithinFunc, 2, 1, "geopoly_within" },
185142
+ { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" },
185143
+ { geopolyOverlapFunc, 2, 1, "geopoly_overlap" },
185144
+ { geopolyDebugFunc, 1, 0, "geopoly_debug" },
185145
+ { geopolyBBoxFunc, 1, 1, "geopoly_bbox" },
185146
+ { geopolyXformFunc, 7, 1, "geopoly_xform" },
185147
+ { geopolyRegularFunc, 4, 1, "geopoly_regular" },
185148
+ { geopolyCcwFunc, 1, 1, "geopoly_ccw" },
183964185149
};
183965185150
static const struct {
183966185151
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
183967185152
void (*xFinal)(sqlite3_context*);
183968185153
const char *zName;
@@ -183969,12 +185154,13 @@
183969185154
} aAgg[] = {
183970185155
{ geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" },
183971185156
};
183972185157
int i;
183973185158
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
185159
+ int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8;
183974185160
rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
183975
- SQLITE_UTF8, 0,
185161
+ enc, 0,
183976185162
aFunc[i].xFunc, 0, 0);
183977185163
}
183978185164
for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
183979185165
rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0,
183980185166
0, aAgg[i].xStep, aAgg[i].xFinal);
@@ -185997,11 +187183,12 @@
185997187183
struct rbu_vfs {
185998187184
sqlite3_vfs base; /* rbu VFS shim methods */
185999187185
sqlite3_vfs *pRealVfs; /* Underlying VFS */
186000187186
sqlite3_mutex *mutex; /* Mutex to protect pMain */
186001187187
sqlite3rbu *pRbu; /* Owner RBU object */
186002
- rbu_file *pMain; /* Linked list of main db files */
187188
+ rbu_file *pMain; /* List of main db files */
187189
+ rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */
186003187190
};
186004187191
186005187192
/*
186006187193
** Each file opened by an rbu VFS is represented by an instance of
186007187194
** the following structure.
@@ -186026,10 +187213,11 @@
186026187213
char *zDel; /* Delete this when closing file */
186027187214
186028187215
const char *zWal; /* Wal filename for this main db file */
186029187216
rbu_file *pWalFd; /* Wal file descriptor for this main db */
186030187217
rbu_file *pMainNext; /* Next MAIN_DB file */
187218
+ rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */
186031187219
};
186032187220
186033187221
/*
186034187222
** True for an RBU vacuum handle, or false otherwise.
186035187223
*/
@@ -189621,10 +190809,73 @@
189621190809
pFd->sz = nNew;
189622190810
assert( pRbu->szTemp>=0 );
189623190811
if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
189624190812
return SQLITE_OK;
189625190813
}
190814
+
190815
+/*
190816
+** Add an item to the main-db lists, if it is not already present.
190817
+**
190818
+** There are two main-db lists. One for all file descriptors, and one
190819
+** for all file descriptors with rbu_file.pDb!=0. If the argument has
190820
+** rbu_file.pDb!=0, then it is assumed to already be present on the
190821
+** main list and is only added to the pDb!=0 list.
190822
+*/
190823
+static void rbuMainlistAdd(rbu_file *p){
190824
+ rbu_vfs *pRbuVfs = p->pRbuVfs;
190825
+ rbu_file *pIter;
190826
+ assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
190827
+ sqlite3_mutex_enter(pRbuVfs->mutex);
190828
+ if( p->pRbu==0 ){
190829
+ for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
190830
+ p->pMainNext = pRbuVfs->pMain;
190831
+ pRbuVfs->pMain = p;
190832
+ }else{
190833
+ for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
190834
+ if( pIter==0 ){
190835
+ p->pMainRbuNext = pRbuVfs->pMainRbu;
190836
+ pRbuVfs->pMainRbu = p;
190837
+ }
190838
+ }
190839
+ sqlite3_mutex_leave(pRbuVfs->mutex);
190840
+}
190841
+
190842
+/*
190843
+** Remove an item from the main-db lists.
190844
+*/
190845
+static void rbuMainlistRemove(rbu_file *p){
190846
+ rbu_file **pp;
190847
+ sqlite3_mutex_enter(p->pRbuVfs->mutex);
190848
+ for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
190849
+ if( *pp ) *pp = p->pMainNext;
190850
+ p->pMainNext = 0;
190851
+ for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
190852
+ if( *pp ) *pp = p->pMainRbuNext;
190853
+ p->pMainRbuNext = 0;
190854
+ sqlite3_mutex_leave(p->pRbuVfs->mutex);
190855
+}
190856
+
190857
+/*
190858
+** Given that zWal points to a buffer containing a wal file name passed to
190859
+** either the xOpen() or xAccess() VFS method, search the main-db list for
190860
+** a file-handle opened by the same database connection on the corresponding
190861
+** database file.
190862
+**
190863
+** If parameter bRbu is true, only search for file-descriptors with
190864
+** rbu_file.pDb!=0.
190865
+*/
190866
+static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
190867
+ rbu_file *pDb;
190868
+ sqlite3_mutex_enter(pRbuVfs->mutex);
190869
+ if( bRbu ){
190870
+ for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
190871
+ }else{
190872
+ for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
190873
+ }
190874
+ sqlite3_mutex_leave(pRbuVfs->mutex);
190875
+ return pDb;
190876
+}
189626190877
189627190878
/*
189628190879
** Close an rbu file.
189629190880
*/
189630190881
static int rbuVfsClose(sqlite3_file *pFile){
@@ -189639,21 +190890,18 @@
189639190890
sqlite3_free(p->apShm);
189640190891
p->apShm = 0;
189641190892
sqlite3_free(p->zDel);
189642190893
189643190894
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
189644
- rbu_file **pp;
189645
- sqlite3_mutex_enter(p->pRbuVfs->mutex);
189646
- for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
189647
- *pp = p->pMainNext;
189648
- sqlite3_mutex_leave(p->pRbuVfs->mutex);
190895
+ rbuMainlistRemove(p);
189649190896
rbuUnlockShm(p);
189650190897
p->pReal->pMethods->xShmUnmap(p->pReal, 0);
189651190898
}
189652190899
else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
189653190900
rbuUpdateTempSize(p, 0);
189654190901
}
190902
+ assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
189655190903
189656190904
/* Close the underlying file handle */
189657190905
rc = p->pReal->pMethods->xClose(p->pReal);
189658190906
return rc;
189659190907
}
@@ -189908,10 +191156,13 @@
189908191156
rc = SQLITE_ERROR;
189909191157
pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
189910191158
}else if( rc==SQLITE_NOTFOUND ){
189911191159
pRbu->pTargetFd = p;
189912191160
p->pRbu = pRbu;
191161
+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
191162
+ rbuMainlistAdd(p);
191163
+ }
189913191164
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
189914191165
rc = SQLITE_OK;
189915191166
}
189916191167
}
189917191168
return rc;
@@ -190069,24 +191320,10 @@
190069191320
rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
190070191321
}
190071191322
return rc;
190072191323
}
190073191324
190074
-/*
190075
-** Given that zWal points to a buffer containing a wal file name passed to
190076
-** either the xOpen() or xAccess() VFS method, return a pointer to the
190077
-** file-handle opened by the same database connection on the corresponding
190078
-** database file.
190079
-*/
190080
-static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
190081
- rbu_file *pDb;
190082
- sqlite3_mutex_enter(pRbuVfs->mutex);
190083
- for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
190084
- sqlite3_mutex_leave(pRbuVfs->mutex);
190085
- return pDb;
190086
-}
190087
-
190088191325
/*
190089191326
** A main database named zName has just been opened. The following
190090191327
** function returns a pointer to a buffer owned by SQLite that contains
190091191328
** the name of the *-wal file this db connection will use. SQLite
190092191329
** happens to pass a pointer to this buffer when using xAccess()
@@ -190161,11 +191398,11 @@
190161191398
** happens to pass a pointer to this buffer when using xAccess()
190162191399
** or xOpen() to operate on the *-wal file. */
190163191400
pFd->zWal = rbuMainToWal(zName, flags);
190164191401
}
190165191402
else if( flags & SQLITE_OPEN_WAL ){
190166
- rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
191403
+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
190167191404
if( pDb ){
190168191405
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
190169191406
/* This call is to open a *-wal file. Intead, open the *-oal. This
190170191407
** code ensures that the string passed to xOpen() is terminated by a
190171191408
** pair of '\0' bytes in case the VFS attempts to extract a URI
@@ -190213,14 +191450,11 @@
190213191450
/* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
190214191451
** pointer and, if the file is a main database file, link it into the
190215191452
** mutex protected linked list of all such files. */
190216191453
pFile->pMethods = &rbuvfs_io_methods;
190217191454
if( flags & SQLITE_OPEN_MAIN_DB ){
190218
- sqlite3_mutex_enter(pRbuVfs->mutex);
190219
- pFd->pMainNext = pRbuVfs->pMain;
190220
- pRbuVfs->pMain = pFd;
190221
- sqlite3_mutex_leave(pRbuVfs->mutex);
191455
+ rbuMainlistAdd(pFd);
190222191456
}
190223191457
}else{
190224191458
sqlite3_free(pFd->zDel);
190225191459
}
190226191460
@@ -190264,11 +191498,11 @@
190264191498
** causing SQLite to call xOpen() to open it. This call will also
190265191499
** be intercepted (see the rbuVfsOpen() function) and the *-oal
190266191500
** file opened instead.
190267191501
*/
190268191502
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
190269
- rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
191503
+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
190270191504
if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
190271191505
if( *pResOut ){
190272191506
rc = SQLITE_CANTOPEN;
190273191507
}else{
190274191508
sqlite3_int64 sz = 0;
@@ -190677,21 +191911,19 @@
190677191911
** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
190678191912
*/
190679191913
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
190680191914
int i;
190681191915
190682
- pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
190683
-
190684191916
/* Look for a valid schema=? constraint. If found, change the idxNum to
190685191917
** 1 and request the value of that constraint be sent to xFilter. And
190686191918
** lower the cost estimate to encourage the constrained version to be
190687191919
** used.
190688191920
*/
190689191921
for(i=0; i<pIdxInfo->nConstraint; i++){
190690
- if( pIdxInfo->aConstraint[i].usable==0 ) continue;
190691
- if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
190692191922
if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
191923
+ if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
191924
+ if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
190693191925
pIdxInfo->idxNum = 1;
190694191926
pIdxInfo->estimatedCost = 1.0;
190695191927
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
190696191928
pIdxInfo->aConstraintUsage[i].omit = 1;
190697191929
break;
@@ -190737,18 +191969,24 @@
190737191969
190738191970
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
190739191971
return SQLITE_OK;
190740191972
}
190741191973
190742
-static void statClearPage(StatPage *p){
191974
+static void statClearCells(StatPage *p){
190743191975
int i;
190744191976
if( p->aCell ){
190745191977
for(i=0; i<p->nCell; i++){
190746191978
sqlite3_free(p->aCell[i].aOvfl);
190747191979
}
190748191980
sqlite3_free(p->aCell);
190749191981
}
191982
+ p->nCell = 0;
191983
+ p->aCell = 0;
191984
+}
191985
+
191986
+static void statClearPage(StatPage *p){
191987
+ statClearCells(p);
190750191988
sqlite3PagerUnref(p->pPg);
190751191989
sqlite3_free(p->zPath);
190752191990
memset(p, 0, sizeof(StatPage));
190753191991
}
190754191992
@@ -190807,26 +192045,37 @@
190807192045
190808192046
u8 *aData = sqlite3PagerGetData(p->pPg);
190809192047
u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
190810192048
190811192049
p->flags = aHdr[0];
192050
+ if( p->flags==0x0A || p->flags==0x0D ){
192051
+ isLeaf = 1;
192052
+ nHdr = 8;
192053
+ }else if( p->flags==0x05 || p->flags==0x02 ){
192054
+ isLeaf = 0;
192055
+ nHdr = 12;
192056
+ }else{
192057
+ goto statPageIsCorrupt;
192058
+ }
192059
+ if( p->iPgno==1 ) nHdr += 100;
190812192060
p->nCell = get2byte(&aHdr[3]);
190813192061
p->nMxPayload = 0;
190814
-
190815
- isLeaf = (p->flags==0x0A || p->flags==0x0D);
190816
- nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
192062
+ szPage = sqlite3BtreeGetPageSize(pBt);
190817192063
190818192064
nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
190819192065
nUnused += (int)aHdr[7];
190820192066
iOff = get2byte(&aHdr[1]);
190821192067
while( iOff ){
192068
+ int iNext;
192069
+ if( iOff>=szPage ) goto statPageIsCorrupt;
190822192070
nUnused += get2byte(&aData[iOff+2]);
190823
- iOff = get2byte(&aData[iOff]);
192071
+ iNext = get2byte(&aData[iOff]);
192072
+ if( iNext<iOff+4 && iNext>0 ) goto statPageIsCorrupt;
192073
+ iOff = iNext;
190824192074
}
190825192075
p->nUnused = nUnused;
190826192076
p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
190827
- szPage = sqlite3BtreeGetPageSize(pBt);
190828192077
190829192078
if( p->nCell ){
190830192079
int i; /* Used to iterate through cells */
190831192080
int nUsable; /* Usable bytes per page */
190832192081
@@ -190839,10 +192088,11 @@
190839192088
190840192089
for(i=0; i<p->nCell; i++){
190841192090
StatCell *pCell = &p->aCell[i];
190842192091
190843192092
iOff = get2byte(&aData[nHdr+i*2]);
192093
+ if( iOff<nHdr || iOff>=szPage ) goto statPageIsCorrupt;
190844192094
if( !isLeaf ){
190845192095
pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
190846192096
iOff += 4;
190847192097
}
190848192098
if( p->flags==0x05 ){
@@ -190855,17 +192105,18 @@
190855192105
u64 dummy;
190856192106
iOff += sqlite3GetVarint(&aData[iOff], &dummy);
190857192107
}
190858192108
if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
190859192109
getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
192110
+ if( nLocal<0 ) goto statPageIsCorrupt;
190860192111
pCell->nLocal = nLocal;
190861
- assert( nLocal>=0 );
190862192112
assert( nPayload>=(u32)nLocal );
190863192113
assert( nLocal<=(nUsable-35) );
190864192114
if( nPayload>(u32)nLocal ){
190865192115
int j;
190866192116
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
192117
+ if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
190867192118
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
190868192119
pCell->nOvfl = nOvfl;
190869192120
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
190870192121
if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
190871192122
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
@@ -190885,10 +192136,15 @@
190885192136
}
190886192137
}
190887192138
}
190888192139
190889192140
return SQLITE_OK;
192141
+
192142
+statPageIsCorrupt:
192143
+ p->flags = 0;
192144
+ statClearCells(p);
192145
+ return SQLITE_OK;
190890192146
}
190891192147
190892192148
/*
190893192149
** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
190894192150
** the current value of pCsr->iPageno.
@@ -191180,10 +192436,11 @@
191180192436
0, /* xFindMethod */
191181192437
0, /* xRename */
191182192438
0, /* xSavepoint */
191183192439
0, /* xRelease */
191184192440
0, /* xRollbackTo */
192441
+ 0 /* xShadowName */
191185192442
};
191186192443
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
191187192444
}
191188192445
#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
191189192446
SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191310,13 +192567,12 @@
191310192567
for(i=0; i<pIdxInfo->nConstraint; i++){
191311192568
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
191312192569
if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
191313192570
if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
191314192571
if( !p->usable ){
191315
- /* No solution. Use the default SQLITE_BIG_DBL cost */
191316
- pIdxInfo->estimatedRows = 0x7fffffff;
191317
- return SQLITE_OK;
192572
+ /* No solution. */
192573
+ return SQLITE_CONSTRAINT;
191318192574
}
191319192575
iPlan = 2;
191320192576
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
191321192577
pIdxInfo->aConstraintUsage[i].omit = 1;
191322192578
break;
@@ -191504,10 +192760,14 @@
191504192760
int iDb;
191505192761
Btree *pBt;
191506192762
Pager *pPager;
191507192763
int szPage;
191508192764
192765
+ if( pTab->db->flags & SQLITE_Defensive ){
192766
+ zErr = "read-only";
192767
+ goto update_fail;
192768
+ }
191509192769
if( argc==1 ){
191510192770
zErr = "cannot delete";
191511192771
goto update_fail;
191512192772
}
191513192773
pgno = sqlite3_value_int(argv[0]);
@@ -191594,10 +192854,11 @@
191594192854
0, /* xFindMethod */
191595192855
0, /* xRename */
191596192856
0, /* xSavepoint */
191597192857
0, /* xRelease */
191598192858
0, /* xRollbackTo */
192859
+ 0 /* xShadowName */
191599192860
};
191600192861
return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
191601192862
}
191602192863
#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
191603192864
SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191629,10 +192890,12 @@
191629192890
# define SESSIONS_STRM_CHUNK_SIZE 64
191630192891
# else
191631192892
# define SESSIONS_STRM_CHUNK_SIZE 1024
191632192893
# endif
191633192894
#endif
192895
+
192896
+static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
191634192897
191635192898
typedef struct SessionHook SessionHook;
191636192899
struct SessionHook {
191637192900
void *pCtx;
191638192901
int (*xOld)(void*,int,sqlite3_value**);
@@ -191692,10 +192955,11 @@
191692192955
*/
191693192956
struct sqlite3_changeset_iter {
191694192957
SessionInput in; /* Input buffer or stream */
191695192958
SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
191696192959
int bPatchset; /* True if this is a patchset */
192960
+ int bInvert; /* True to invert changeset */
191697192961
int rc; /* Iterator error code */
191698192962
sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
191699192963
char *zTab; /* Current table */
191700192964
int nCol; /* Number of columns in zTab */
191701192965
int op; /* Current operation */
@@ -191848,10 +193112,46 @@
191848193112
** and fields associated with modified columns contain the new column values.
191849193113
**
191850193114
** The records associated with INSERT changes are in the same format as for
191851193115
** changesets. It is not possible for a record associated with an INSERT
191852193116
** change to contain a field set to "undefined".
193117
+**
193118
+** REBASE BLOB FORMAT:
193119
+**
193120
+** A rebase blob may be output by sqlite3changeset_apply_v2() and its
193121
+** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
193122
+** existing changesets. A rebase blob contains one entry for each conflict
193123
+** resolved using either the OMIT or REPLACE strategies within the apply_v2()
193124
+** call.
193125
+**
193126
+** The format used for a rebase blob is very similar to that used for
193127
+** changesets. All entries related to a single table are grouped together.
193128
+**
193129
+** Each group of entries begins with a table header in changeset format:
193130
+**
193131
+** 1 byte: Constant 0x54 (capital 'T')
193132
+** Varint: Number of columns in the table.
193133
+** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
193134
+** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
193135
+**
193136
+** Followed by one or more entries associated with the table.
193137
+**
193138
+** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
193139
+** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
193140
+** record: (in the record format defined above).
193141
+**
193142
+** In a rebase blob, the first field is set to SQLITE_INSERT if the change
193143
+** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
193144
+** it was a DELETE. The second field is set to 0x01 if the conflict
193145
+** resolution strategy was REPLACE, or 0x00 if it was OMIT.
193146
+**
193147
+** If the change that caused the conflict was a DELETE, then the single
193148
+** record is a copy of the old.* record from the original changeset. If it
193149
+** was an INSERT, then the single record is a copy of the new.* record. If
193150
+** the conflicting change was an UPDATE, then the single record is a copy
193151
+** of the new.* record with the PK fields filled in based on the original
193152
+** old.* record.
191853193153
*/
191854193154
191855193155
/*
191856193156
** For each row modified during a session, there exists a single instance of
191857193157
** this structure stored in a SessionTable.aChange[] hash table.
@@ -193398,16 +194698,16 @@
193398194698
** set *pRc to SQLITE_NOMEM and return non-zero.
193399194699
*/
193400194700
static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
193401194701
if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
193402194702
u8 *aNew;
193403
- int nNew = p->nAlloc ? p->nAlloc : 128;
194703
+ i64 nNew = p->nAlloc ? p->nAlloc : 128;
193404194704
do {
193405194705
nNew = nNew*2;
193406
- }while( nNew<(p->nBuf+nByte) );
194706
+ }while( (nNew-p->nBuf)<nByte );
193407194707
193408
- aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
194708
+ aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
193409194709
if( 0==aNew ){
193410194710
*pRc = SQLITE_NOMEM;
193411194711
}else{
193412194712
p->aBuf = aNew;
193413194713
p->nAlloc = nNew;
@@ -194001,16 +195301,16 @@
194001195301
}
194002195302
if( rc==SQLITE_OK ){
194003195303
rc = sqlite3_reset(pSel);
194004195304
}
194005195305
194006
- /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
195306
+ /* If the buffer is now larger than sessions_strm_chunk_size, pass
194007195307
** its contents to the xOutput() callback. */
194008195308
if( xOutput
194009195309
&& rc==SQLITE_OK
194010195310
&& buf.nBuf>nNoop
194011
- && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE
195311
+ && buf.nBuf>sessions_strm_chunk_size
194012195312
){
194013195313
rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
194014195314
nNoop = -1;
194015195315
buf.nBuf = 0;
194016195316
}
@@ -194145,11 +195445,12 @@
194145195445
static int sessionChangesetStart(
194146195446
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
194147195447
int (*xInput)(void *pIn, void *pData, int *pnData),
194148195448
void *pIn,
194149195449
int nChangeset, /* Size of buffer pChangeset in bytes */
194150
- void *pChangeset /* Pointer to buffer containing changeset */
195450
+ void *pChangeset, /* Pointer to buffer containing changeset */
195451
+ int bInvert /* True to invert changeset */
194151195452
){
194152195453
sqlite3_changeset_iter *pRet; /* Iterator to return */
194153195454
int nByte; /* Number of bytes to allocate for iterator */
194154195455
194155195456
assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
@@ -194165,10 +195466,11 @@
194165195466
pRet->in.aData = (u8 *)pChangeset;
194166195467
pRet->in.nData = nChangeset;
194167195468
pRet->in.xInput = xInput;
194168195469
pRet->in.pIn = pIn;
194169195470
pRet->in.bEof = (xInput ? 0 : 1);
195471
+ pRet->bInvert = bInvert;
194170195472
194171195473
/* Populate the output variable and return success. */
194172195474
*pp = pRet;
194173195475
return SQLITE_OK;
194174195476
}
@@ -194179,11 +195481,20 @@
194179195481
SQLITE_API int sqlite3changeset_start(
194180195482
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
194181195483
int nChangeset, /* Size of buffer pChangeset in bytes */
194182195484
void *pChangeset /* Pointer to buffer containing changeset */
194183195485
){
194184
- return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
195486
+ return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
195487
+}
195488
+SQLITE_API int sqlite3changeset_start_v2(
195489
+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
195490
+ int nChangeset, /* Size of buffer pChangeset in bytes */
195491
+ void *pChangeset, /* Pointer to buffer containing changeset */
195492
+ int flags
195493
+){
195494
+ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
195495
+ return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
194185195496
}
194186195497
194187195498
/*
194188195499
** Streaming version of sqlite3changeset_start().
194189195500
*/
@@ -194190,19 +195501,28 @@
194190195501
SQLITE_API int sqlite3changeset_start_strm(
194191195502
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
194192195503
int (*xInput)(void *pIn, void *pData, int *pnData),
194193195504
void *pIn
194194195505
){
194195
- return sessionChangesetStart(pp, xInput, pIn, 0, 0);
195506
+ return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
195507
+}
195508
+SQLITE_API int sqlite3changeset_start_v2_strm(
195509
+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
195510
+ int (*xInput)(void *pIn, void *pData, int *pnData),
195511
+ void *pIn,
195512
+ int flags
195513
+){
195514
+ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
195515
+ return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
194196195516
}
194197195517
194198195518
/*
194199195519
** If the SessionInput object passed as the only argument is a streaming
194200195520
** object and the buffer is full, discard some data to free up space.
194201195521
*/
194202195522
static void sessionDiscardData(SessionInput *pIn){
194203
- if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
195523
+ if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
194204195524
int nMove = pIn->buf.nBuf - pIn->iNext;
194205195525
assert( nMove>=0 );
194206195526
if( nMove>0 ){
194207195527
memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
194208195528
}
@@ -194221,11 +195541,11 @@
194221195541
*/
194222195542
static int sessionInputBuffer(SessionInput *pIn, int nByte){
194223195543
int rc = SQLITE_OK;
194224195544
if( pIn->xInput ){
194225195545
while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
194226
- int nNew = SESSIONS_STRM_CHUNK_SIZE;
195546
+ int nNew = sessions_strm_chunk_size;
194227195547
194228195548
if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
194229195549
if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
194230195550
rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
194231195551
if( nNew==0 ){
@@ -194569,14 +195889,14 @@
194569195889
p->in.iCurrent = p->in.iNext;
194570195890
if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
194571195891
op = p->in.aData[p->in.iNext++];
194572195892
}
194573195893
194574
- if( p->zTab==0 ){
195894
+ if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
194575195895
/* The first record in the changeset is not a table header. Must be a
194576195896
** corrupt changeset. */
194577
- assert( p->in.iNext==1 );
195897
+ assert( p->in.iNext==1 || p->zTab );
194578195898
return (p->rc = SQLITE_CORRUPT_BKPT);
194579195899
}
194580195900
194581195901
p->op = op;
194582195902
p->bIndirect = p->in.aData[p->in.iNext++];
@@ -194597,37 +195917,43 @@
194597195917
p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
194598195918
if( p->rc!=SQLITE_OK ) return p->rc;
194599195919
*paRec = &p->in.aData[p->in.iNext];
194600195920
p->in.iNext += *pnRec;
194601195921
}else{
195922
+ sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
195923
+ sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
194602195924
194603195925
/* If this is an UPDATE or DELETE, read the old.* record. */
194604195926
if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
194605195927
u8 *abPK = p->bPatchset ? p->abPK : 0;
194606
- p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
195928
+ p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
194607195929
if( p->rc!=SQLITE_OK ) return p->rc;
194608195930
}
194609195931
194610195932
/* If this is an INSERT or UPDATE, read the new.* record. */
194611195933
if( p->op!=SQLITE_DELETE ){
194612
- p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
195934
+ p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
194613195935
if( p->rc!=SQLITE_OK ) return p->rc;
194614195936
}
194615195937
194616
- if( p->bPatchset && p->op==SQLITE_UPDATE ){
195938
+ if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
194617195939
/* If this is an UPDATE that is part of a patchset, then all PK and
194618195940
** modified fields are present in the new.* record. The old.* record
194619195941
** is currently completely empty. This block shifts the PK fields from
194620195942
** new.* to old.*, to accommodate the code that reads these arrays. */
194621195943
for(i=0; i<p->nCol; i++){
194622
- assert( p->apValue[i]==0 );
195944
+ assert( p->bPatchset==0 || p->apValue[i]==0 );
194623195945
if( p->abPK[i] ){
195946
+ assert( p->apValue[i]==0 );
194624195947
p->apValue[i] = p->apValue[i+p->nCol];
194625195948
if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
194626195949
p->apValue[i+p->nCol] = 0;
194627195950
}
194628195951
}
195952
+ }else if( p->bInvert ){
195953
+ if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
195954
+ else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
194629195955
}
194630195956
}
194631195957
194632195958
return SQLITE_ROW;
194633195959
}
@@ -194940,11 +196266,11 @@
194940196266
rc = SQLITE_CORRUPT_BKPT;
194941196267
goto finished_invert;
194942196268
}
194943196269
194944196270
assert( rc==SQLITE_OK );
194945
- if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
196271
+ if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
194946196272
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
194947196273
sOut.nBuf = 0;
194948196274
if( rc!=SQLITE_OK ) goto finished_invert;
194949196275
}
194950196276
}
@@ -195019,11 +196345,12 @@
195019196345
u8 *abPK; /* Boolean array - true if column is in PK */
195020196346
int bStat1; /* True if table is sqlite_stat1 */
195021196347
int bDeferConstraints; /* True to defer constraints */
195022196348
SessionBuffer constraints; /* Deferred constraints are stored here */
195023196349
SessionBuffer rebase; /* Rebase information (if any) here */
195024
- int bRebaseStarted; /* If table header is already in rebase */
196350
+ u8 bRebaseStarted; /* If table header is already in rebase */
196351
+ u8 bRebase; /* True to collect rebase information */
195025196352
};
195026196353
195027196354
/*
195028196355
** Formulate a statement to DELETE a row from database db. Assuming a table
195029196356
** structure like this:
@@ -195416,39 +196743,40 @@
195416196743
SessionApplyCtx *p, /* Apply context */
195417196744
int eType, /* Conflict resolution (OMIT or REPLACE) */
195418196745
sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
195419196746
){
195420196747
int rc = SQLITE_OK;
195421
- int i;
195422
- int eOp = pIter->op;
195423
- if( p->bRebaseStarted==0 ){
195424
- /* Append a table-header to the rebase buffer */
195425
- const char *zTab = pIter->zTab;
195426
- sessionAppendByte(&p->rebase, 'T', &rc);
195427
- sessionAppendVarint(&p->rebase, p->nCol, &rc);
195428
- sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
195429
- sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
195430
- p->bRebaseStarted = 1;
195431
- }
195432
-
195433
- assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
195434
- assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
195435
-
195436
- sessionAppendByte(&p->rebase,
195437
- (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
195438
- );
195439
- sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
195440
- for(i=0; i<p->nCol; i++){
195441
- sqlite3_value *pVal = 0;
195442
- if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
195443
- sqlite3changeset_old(pIter, i, &pVal);
195444
- }else{
195445
- sqlite3changeset_new(pIter, i, &pVal);
195446
- }
195447
- sessionAppendValue(&p->rebase, pVal, &rc);
195448
- }
195449
-
196748
+ if( p->bRebase ){
196749
+ int i;
196750
+ int eOp = pIter->op;
196751
+ if( p->bRebaseStarted==0 ){
196752
+ /* Append a table-header to the rebase buffer */
196753
+ const char *zTab = pIter->zTab;
196754
+ sessionAppendByte(&p->rebase, 'T', &rc);
196755
+ sessionAppendVarint(&p->rebase, p->nCol, &rc);
196756
+ sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
196757
+ sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
196758
+ p->bRebaseStarted = 1;
196759
+ }
196760
+
196761
+ assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
196762
+ assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
196763
+
196764
+ sessionAppendByte(&p->rebase,
196765
+ (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
196766
+ );
196767
+ sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
196768
+ for(i=0; i<p->nCol; i++){
196769
+ sqlite3_value *pVal = 0;
196770
+ if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
196771
+ sqlite3changeset_old(pIter, i, &pVal);
196772
+ }else{
196773
+ sqlite3changeset_new(pIter, i, &pVal);
196774
+ }
196775
+ sessionAppendValue(&p->rebase, pVal, &rc);
196776
+ }
196777
+ }
195450196778
return rc;
195451196779
}
195452196780
195453196781
/*
195454196782
** Invoke the conflict handler for the change that the changeset iterator
@@ -195787,11 +197115,11 @@
195787197115
while( pApply->constraints.nBuf ){
195788197116
sqlite3_changeset_iter *pIter2 = 0;
195789197117
SessionBuffer cons = pApply->constraints;
195790197118
memset(&pApply->constraints, 0, sizeof(SessionBuffer));
195791197119
195792
- rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
197120
+ rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
195793197121
if( rc==SQLITE_OK ){
195794197122
int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
195795197123
int rc2;
195796197124
pIter2->bPatchset = bPatchset;
195797197125
pIter2->zTab = (char*)zTab;
@@ -195853,10 +197181,11 @@
195853197181
195854197182
assert( xConflict!=0 );
195855197183
195856197184
pIter->in.bNoDiscard = 1;
195857197185
memset(&sApply, 0, sizeof(sApply));
197186
+ sApply.bRebase = (ppRebase && pnRebase);
195858197187
sqlite3_mutex_enter(sqlite3_db_mutex(db));
195859197188
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
195860197189
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
195861197190
}
195862197191
if( rc==SQLITE_OK ){
@@ -196003,11 +197332,12 @@
196003197332
sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
196004197333
sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
196005197334
}
196006197335
}
196007197336
196008
- if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
197337
+ assert( sApply.bRebase || sApply.rebase.nBuf==0 );
197338
+ if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
196009197339
*ppRebase = (void*)sApply.rebase.aBuf;
196010197340
*pnRebase = sApply.rebase.nBuf;
196011197341
sApply.rebase.aBuf = 0;
196012197342
}
196013197343
sqlite3_finalize(sApply.pInsert);
@@ -196041,11 +197371,12 @@
196041197371
void *pCtx, /* First argument passed to xConflict */
196042197372
void **ppRebase, int *pnRebase,
196043197373
int flags
196044197374
){
196045197375
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
196046
- int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
197376
+ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
197377
+ int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
196047197378
if( rc==SQLITE_OK ){
196048197379
rc = sessionChangesetApply(
196049197380
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
196050197381
);
196051197382
}
@@ -196098,11 +197429,12 @@
196098197429
void *pCtx, /* First argument passed to xConflict */
196099197430
void **ppRebase, int *pnRebase,
196100197431
int flags
196101197432
){
196102197433
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
196103
- int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
197434
+ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
197435
+ int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
196104197436
if( rc==SQLITE_OK ){
196105197437
rc = sessionChangesetApply(
196106197438
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
196107197439
);
196108197440
}
@@ -196471,17 +197803,16 @@
196471197803
SessionChange *p;
196472197804
for(p=pTab->apChange[i]; p; p=p->pNext){
196473197805
sessionAppendByte(&buf, p->op, &rc);
196474197806
sessionAppendByte(&buf, p->bIndirect, &rc);
196475197807
sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
197808
+ if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
197809
+ rc = xOutput(pOut, buf.aBuf, buf.nBuf);
197810
+ buf.nBuf = 0;
197811
+ }
196476197812
}
196477197813
}
196478
-
196479
- if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
196480
- rc = xOutput(pOut, buf.aBuf, buf.nBuf);
196481
- buf.nBuf = 0;
196482
- }
196483197814
}
196484197815
196485197816
if( rc==SQLITE_OK ){
196486197817
if( xOutput ){
196487197818
if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
@@ -196868,11 +198199,11 @@
196868198199
if( bDone==0 ){
196869198200
sessionAppendByte(&sOut, pIter->op, &rc);
196870198201
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
196871198202
sessionAppendBlob(&sOut, aRec, nRec, &rc);
196872198203
}
196873
- if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
198204
+ if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
196874198205
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
196875198206
sOut.nBuf = 0;
196876198207
}
196877198208
if( rc ) break;
196878198209
}
@@ -196978,10 +198309,31 @@
196978198309
if( p ){
196979198310
sessionDeleteTable(p->grp.pList);
196980198311
sqlite3_free(p);
196981198312
}
196982198313
}
198314
+
198315
+/*
198316
+** Global configuration
198317
+*/
198318
+SQLITE_API int sqlite3session_config(int op, void *pArg){
198319
+ int rc = SQLITE_OK;
198320
+ switch( op ){
198321
+ case SQLITE_SESSION_CONFIG_STRMSIZE: {
198322
+ int *pInt = (int*)pArg;
198323
+ if( *pInt>0 ){
198324
+ sessions_strm_chunk_size = *pInt;
198325
+ }
198326
+ *pInt = sessions_strm_chunk_size;
198327
+ break;
198328
+ }
198329
+ default:
198330
+ rc = SQLITE_MISUSE;
198331
+ break;
198332
+ }
198333
+ return rc;
198334
+}
196983198335
196984198336
#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
196985198337
196986198338
/************** End of sqlite3session.c **************************************/
196987198339
/************** Begin file fts5.c ********************************************/
@@ -198413,10 +199765,11 @@
198413199765
**
198414199766
** The following is the concatenation of all %include directives from the
198415199767
** input grammar file:
198416199768
*/
198417199769
/* #include <stdio.h> */
199770
+/* #include <assert.h> */
198418199771
/************ Begin %include sections from the grammar ************************/
198419199772
198420199773
/* #include "fts5Int.h" */
198421199774
/* #include "fts5parse.h" */
198422199775
@@ -199740,14 +201093,13 @@
199740201093
#endif
199741201094
fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
199742201095
fts5yymajor = fts5YYNOCODE;
199743201096
}else{
199744201097
while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
199745
- && fts5yymx != fts5YYERRORSYMBOL
199746201098
&& (fts5yyact = fts5yy_find_reduce_action(
199747201099
fts5yypParser->fts5yytos->stateno,
199748
- fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
201100
+ fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE
199749201101
){
199750201102
fts5yy_pop_parser_stack(fts5yypParser);
199751201103
}
199752201104
if( fts5yypParser->fts5yytos < fts5yypParser->fts5yystack || fts5yymajor==0 ){
199753201105
fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
@@ -210693,11 +212045,11 @@
210693212045
sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
210694212046
pRet = 0;
210695212047
fts5CloseReader(p);
210696212048
}
210697212049
210698
- *ppIter = &pRet->base;
212050
+ *ppIter = (Fts5IndexIter*)pRet;
210699212051
sqlite3Fts5BufferFree(&buf);
210700212052
}
210701212053
return fts5IndexReturn(p);
210702212054
}
210703212055
@@ -214442,16 +215794,31 @@
214442215794
int nArg, /* Number of args */
214443215795
sqlite3_value **apUnused /* Function arguments */
214444215796
){
214445215797
assert( nArg==0 );
214446215798
UNUSED_PARAM2(nArg, apUnused);
214447
- sqlite3_result_text(pCtx, "fts5: 2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7", -1, SQLITE_TRANSIENT);
215799
+ sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT);
215800
+}
215801
+
215802
+/*
215803
+** Return true if zName is the extension on one of the shadow tables used
215804
+** by this module.
215805
+*/
215806
+static int fts5ShadowName(const char *zName){
215807
+ static const char *azName[] = {
215808
+ "config", "content", "data", "docsize", "idx"
215809
+ };
215810
+ unsigned int i;
215811
+ for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
215812
+ if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
215813
+ }
215814
+ return 0;
214448215815
}
214449215816
214450215817
static int fts5Init(sqlite3 *db){
214451215818
static const sqlite3_module fts5Mod = {
214452
- /* iVersion */ 2,
215819
+ /* iVersion */ 3,
214453215820
/* xCreate */ fts5CreateMethod,
214454215821
/* xConnect */ fts5ConnectMethod,
214455215822
/* xBestIndex */ fts5BestIndexMethod,
214456215823
/* xDisconnect */ fts5DisconnectMethod,
214457215824
/* xDestroy */ fts5DestroyMethod,
@@ -214470,10 +215837,11 @@
214470215837
/* xFindFunction */ fts5FindFunctionMethod,
214471215838
/* xRename */ fts5RenameMethod,
214472215839
/* xSavepoint */ fts5SavepointMethod,
214473215840
/* xRelease */ fts5ReleaseMethod,
214474215841
/* xRollbackTo */ fts5RollbackToMethod,
215842
+ /* xShadowName */ fts5ShadowName
214475215843
};
214476215844
214477215845
int rc;
214478215846
Fts5Global *pGlobal = 0;
214479215847
@@ -218514,20 +219882,22 @@
218514219882
int rc = SQLITE_OK;
218515219883
Fts5IndexIter *pIter = pCsr->pIter;
218516219884
i64 *pp = &pCsr->iInstPos;
218517219885
int *po = &pCsr->iInstOff;
218518219886
219887
+ assert( sqlite3Fts5IterEof(pIter)==0 );
219888
+ assert( pCsr->bEof==0 );
218519219889
while( eDetail==FTS5_DETAIL_NONE
218520219890
|| sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
218521219891
){
218522219892
pCsr->iInstPos = 0;
218523219893
pCsr->iInstOff = 0;
218524219894
218525219895
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
218526219896
if( rc==SQLITE_OK ){
218527219897
rc = fts5VocabInstanceNewTerm(pCsr);
218528
- if( eDetail==FTS5_DETAIL_NONE ) break;
219898
+ if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
218529219899
}
218530219900
if( rc ){
218531219901
pCsr->bEof = 1;
218532219902
break;
218533219903
}
@@ -218838,17 +220208,16 @@
218838220208
/* xFindFunction */ 0,
218839220209
/* xRename */ 0,
218840220210
/* xSavepoint */ 0,
218841220211
/* xRelease */ 0,
218842220212
/* xRollbackTo */ 0,
220213
+ /* xShadowName */ 0
218843220214
};
218844220215
void *p = (void*)pGlobal;
218845220216
218846220217
return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
218847220218
}
218848
-
218849
-
218850220219
218851220220
218852220221
218853220222
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
218854220223
@@ -219120,10 +220489,11 @@
219120220489
0, /* xFindMethod */
219121220490
0, /* xRename */
219122220491
0, /* xSavepoint */
219123220492
0, /* xRelease */
219124220493
0, /* xRollbackTo */
220494
+ 0, /* xShadowName */
219125220495
};
219126220496
219127220497
#endif /* SQLITE_OMIT_VIRTUALTABLE */
219128220498
219129220499
SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){
@@ -219152,12 +220522,12 @@
219152220522
}
219153220523
#endif /* SQLITE_CORE */
219154220524
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
219155220525
219156220526
/************** End of stmt.c ************************************************/
219157
-#if __LINE__!=219157
220527
+#if __LINE__!=220527
219158220528
#undef SQLITE_SOURCE_ID
219159
-#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792alt2"
220529
+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2"
219160220530
#endif
219161220531
/* Return the source-id for this library */
219162220532
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
219163220533
/************************** End of sqlite3.c ******************************/
219164220534
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.25.2. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -257,10 +257,13 @@
257 #if SQLITE_ENABLE_FTS4
258 "ENABLE_FTS4",
259 #endif
260 #if SQLITE_ENABLE_FTS5
261 "ENABLE_FTS5",
 
 
 
262 #endif
263 #if SQLITE_ENABLE_HIDDEN_COLUMNS
264 "ENABLE_HIDDEN_COLUMNS",
265 #endif
266 #if SQLITE_ENABLE_ICU
@@ -287,10 +290,13 @@
287 #if SQLITE_ENABLE_MEMSYS5
288 "ENABLE_MEMSYS5",
289 #endif
290 #if SQLITE_ENABLE_MULTIPLEX
291 "ENABLE_MULTIPLEX",
 
 
 
292 #endif
293 #if SQLITE_ENABLE_NULL_TRIM
294 "ENABLE_NULL_TRIM",
295 #endif
296 #if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
@@ -1154,13 +1160,13 @@
1154 **
1155 ** See also: [sqlite3_libversion()],
1156 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1157 ** [sqlite_version()] and [sqlite_source_id()].
1158 */
1159 #define SQLITE_VERSION "3.25.2"
1160 #define SQLITE_VERSION_NUMBER 3025002
1161 #define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
1162
1163 /*
1164 ** CAPI3REF: Run-Time Library Version Numbers
1165 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1166 **
@@ -3048,10 +3054,11 @@
3048 ** the call worked. ^The [sqlite3_db_config()] interface will return a
3049 ** non-zero [error code] if a discontinued or unsupported configuration option
3050 ** is invoked.
3051 **
3052 ** <dl>
 
3053 ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
3054 ** <dd> ^This option takes three additional arguments that determine the
3055 ** [lookaside memory allocator] configuration for the [database connection].
3056 ** ^The first argument (the third parameter to [sqlite3_db_config()] is a
3057 ** pointer to a memory buffer to use for lookaside memory.
@@ -3070,10 +3077,11 @@
3070 ** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
3071 ** Any attempt to change the lookaside memory configuration when lookaside
3072 ** memory is in use leaves the configuration unchanged and returns
3073 ** [SQLITE_BUSY].)^</dd>
3074 **
 
3075 ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
3076 ** <dd> ^This option is used to enable or disable the enforcement of
3077 ** [foreign key constraints]. There should be two additional arguments.
3078 ** The first argument is an integer which is 0 to disable FK enforcement,
3079 ** positive to enable FK enforcement or negative to leave FK enforcement
@@ -3080,10 +3088,11 @@
3080 ** unchanged. The second parameter is a pointer to an integer into which
3081 ** is written 0 or 1 to indicate whether FK enforcement is off or on
3082 ** following this call. The second parameter may be a NULL pointer, in
3083 ** which case the FK enforcement setting is not reported back. </dd>
3084 **
 
3085 ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
3086 ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
3087 ** There should be two additional arguments.
3088 ** The first argument is an integer which is 0 to disable triggers,
3089 ** positive to enable triggers or negative to leave the setting unchanged.
@@ -3090,10 +3099,11 @@
3090 ** The second parameter is a pointer to an integer into which
3091 ** is written 0 or 1 to indicate whether triggers are disabled or enabled
3092 ** following this call. The second parameter may be a NULL pointer, in
3093 ** which case the trigger setting is not reported back. </dd>
3094 **
 
3095 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
3096 ** <dd> ^This option is used to enable or disable the two-argument
3097 ** version of the [fts3_tokenizer()] function which is part of the
3098 ** [FTS3] full-text search engine extension.
3099 ** There should be two additional arguments.
@@ -3103,10 +3113,11 @@
3103 ** The second parameter is a pointer to an integer into which
3104 ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
3105 ** following this call. The second parameter may be a NULL pointer, in
3106 ** which case the new setting is not reported back. </dd>
3107 **
 
3108 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
3109 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
3110 ** interface independently of the [load_extension()] SQL function.
3111 ** The [sqlite3_enable_load_extension()] API enables or disables both the
3112 ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -3120,19 +3131,20 @@
3120 ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
3121 ** is disabled or enabled following this call. The second parameter may
3122 ** be a NULL pointer, in which case the new setting is not reported back.
3123 ** </dd>
3124 **
3125 ** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
3126 ** <dd> ^This option is used to change the name of the "main" database
3127 ** schema. ^The sole argument is a pointer to a constant UTF8 string
3128 ** which will become the new schema name in place of "main". ^SQLite
3129 ** does not make a copy of the new main schema name string, so the application
3130 ** must ensure that the argument passed into this DBCONFIG option is unchanged
3131 ** until after the database connection closes.
3132 ** </dd>
3133 **
 
3134 ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
3135 ** <dd> Usually, when a database in wal mode is closed or detached from a
3136 ** database handle, SQLite checks if this will mean that there are now no
3137 ** connections at all to the database. If so, it performs a checkpoint
3138 ** operation before closing the connection. This option may be used to
@@ -3142,11 +3154,11 @@
3142 ** The second parameter is a pointer to an integer
3143 ** into which is written 0 or 1 to indicate whether checkpoints-on-close
3144 ** have been disabled - 0 if they are not disabled, 1 if they are.
3145 ** </dd>
3146 **
3147 ** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
3148 ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
3149 ** the [query planner stability guarantee] (QPSG). When the QPSG is active,
3150 ** a single SQL query statement will always use the same algorithm regardless
3151 ** of values of [bound parameters].)^ The QPSG disables some query optimizations
3152 ** that look at the values of bound parameters, which can make some queries
@@ -3158,11 +3170,11 @@
3158 ** unchanged. The second parameter is a pointer to an integer into which
3159 ** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
3160 ** following this call.
3161 ** </dd>
3162 **
3163 ** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
3164 ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
3165 ** include output for any operations performed by trigger programs. This
3166 ** option is used to set or clear (the default) a flag that governs this
3167 ** behavior. The first parameter passed to this operation is an integer -
3168 ** positive to enable output for trigger programs, or zero to disable it,
@@ -3170,11 +3182,11 @@
3170 ** The second parameter is a pointer to an integer into which is written
3171 ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
3172 ** it is not disabled, 1 if it is.
3173 ** </dd>
3174 **
3175 ** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
3176 ** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
3177 ** [VACUUM] in order to reset a database back to an empty database
3178 ** with no schema and no content. The following process works even for
3179 ** a badly corrupted database file:
3180 ** <ol>
@@ -3189,10 +3201,22 @@
3189 ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
3190 ** </ol>
3191 ** Because resetting a database is destructive and irreversible, the
3192 ** process requires the use of this obscure API and multiple steps to help
3193 ** ensure that it does not happen by accident.
 
 
 
 
 
 
 
 
 
 
 
 
3194 ** </dd>
3195 ** </dl>
3196 */
3197 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
3198 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -3202,11 +3226,12 @@
3202 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
3203 #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
3204 #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
3205 #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
3206 #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
3207 #define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
 
3208
3209 /*
3210 ** CAPI3REF: Enable Or Disable Extended Result Codes
3211 ** METHOD: sqlite3
3212 **
@@ -4640,13 +4665,23 @@
4640 ** be used just once or at most a few times and then destroyed using
4641 ** [sqlite3_finalize()] relatively soon. The current implementation acts
4642 ** on this hint by avoiding the use of [lookaside memory] so as not to
4643 ** deplete the limited store of lookaside memory. Future versions of
4644 ** SQLite may act on this hint differently.
 
 
 
 
 
 
 
 
 
4645 ** </dl>
4646 */
4647 #define SQLITE_PREPARE_PERSISTENT 0x01
 
4648
4649 /*
4650 ** CAPI3REF: Compiling An SQL Statement
4651 ** KEYWORDS: {SQL statement compiler}
4652 ** METHOD: sqlite3
@@ -4800,10 +4835,15 @@
4800 ** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
4801 ** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
4802 ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
4803 ** string containing the SQL text of prepared statement P with
4804 ** [bound parameters] expanded.
 
 
 
 
 
4805 **
4806 ** ^(For example, if a prepared statement is created using the SQL
4807 ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
4808 ** and parameter :xyz is unbound, then sqlite3_sql() will return
4809 ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -4815,18 +4855,20 @@
4815 **
4816 ** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
4817 ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
4818 ** option causes sqlite3_expanded_sql() to always return NULL.
4819 **
4820 ** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
4821 ** automatically freed when the prepared statement is finalized.
 
4822 ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
4823 ** is obtained from [sqlite3_malloc()] and must be free by the application
4824 ** by passing it to [sqlite3_free()].
4825 */
4826 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
4827 SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
 
4828
4829 /*
4830 ** CAPI3REF: Determine If An SQL Statement Writes The Database
4831 ** METHOD: sqlite3_stmt
4832 **
@@ -7312,10 +7354,13 @@
7312 /* The methods above are in version 1 of the sqlite_module object. Those
7313 ** below are for version 2 and greater. */
7314 int (*xSavepoint)(sqlite3_vtab *pVTab, int);
7315 int (*xRelease)(sqlite3_vtab *pVTab, int);
7316 int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
 
 
 
7317 };
7318
7319 /*
7320 ** CAPI3REF: Virtual Table Indexing Information
7321 ** KEYWORDS: sqlite3_index_info
@@ -8234,10 +8279,11 @@
8234 #define SQLITE_TESTCTRL_ALWAYS 13
8235 #define SQLITE_TESTCTRL_RESERVE 14
8236 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8237 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8238 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
 
8239 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
8240 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
8241 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
8242 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
8243 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -9646,10 +9692,11 @@
9646 ** These macros define the various options to the
9647 ** [sqlite3_vtab_config()] interface that [virtual table] implementations
9648 ** can use to customize and optimize their behavior.
9649 **
9650 ** <dl>
 
9651 ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
9652 ** <dd>Calls of the form
9653 ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
9654 ** where X is an integer. If X is zero, then the [virtual table] whose
9655 ** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -10415,11 +10462,11 @@
10415 int iLevel; /* Level of current node or entry */
10416 int mxLevel; /* The largest iLevel value in the tree */
10417 sqlite3_int64 iRowid; /* Rowid for current entry */
10418 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
10419 int eParentWithin; /* Visibility of parent node */
10420 int eWithin; /* OUT: Visiblity */
10421 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
10422 /* The following fields are only available in 3.8.11 and later */
10423 sqlite3_value **apSqlParam; /* Original SQL values of parameters */
10424 };
10425
@@ -10911,16 +10958,42 @@
10911 ** an application iterates through a changeset using an iterator created by
10912 ** this function, all changes that relate to a single table are visited
10913 ** consecutively. There is no chance that the iterator will visit a change
10914 ** the applies to table X, then one for table Y, and then later on visit
10915 ** another change for table X.
 
 
 
 
 
 
 
10916 */
10917 SQLITE_API int sqlite3changeset_start(
10918 sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
10919 int nChangeset, /* Size of changeset blob in bytes */
10920 void *pChangeset /* Pointer to blob containing changeset */
10921 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10922
10923
10924 /*
10925 ** CAPI3REF: Advance A Changeset Iterator
10926 ** METHOD: sqlite3_changeset_iter
@@ -11571,11 +11644,11 @@
11571 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
11572 sqlite3_changeset_iter *p /* Handle describing change and conflict */
11573 ),
11574 void *pCtx, /* First argument passed to xConflict */
11575 void **ppRebase, int *pnRebase, /* OUT: Rebase data */
11576 int flags /* Combination of SESSION_APPLY_* flags */
11577 );
11578
11579 /*
11580 ** CAPI3REF: Flags for sqlite3changeset_apply_v2
11581 **
@@ -11589,12 +11662,18 @@
11589 ** SAVEPOINT is committed if the changeset or patchset is successfully
11590 ** applied, or rolled back if an error occurs. Specifying this flag
11591 ** causes the sessions module to omit this savepoint. In this case, if the
11592 ** caller has an open transaction or savepoint when apply_v2() is called,
11593 ** it may revert the partially applied changeset by rolling it back.
 
 
 
 
 
11594 */
11595 #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
 
11596
11597 /*
11598 ** CAPI3REF: Constants Passed To The Conflict Handler
11599 **
11600 ** Values that may be passed as the second argument to a conflict-handler.
@@ -11983,10 +12062,16 @@
11983 );
11984 SQLITE_API int sqlite3changeset_start_strm(
11985 sqlite3_changeset_iter **pp,
11986 int (*xInput)(void *pIn, void *pData, int *pnData),
11987 void *pIn
 
 
 
 
 
 
11988 );
11989 SQLITE_API int sqlite3session_changeset_strm(
11990 sqlite3_session *pSession,
11991 int (*xOutput)(void *pOut, const void *pData, int nData),
11992 void *pOut
@@ -12010,10 +12095,49 @@
12010 void *pIn,
12011 int (*xOutput)(void *pOut, const void *pData, int nData),
12012 void *pOut
12013 );
12014
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12015
12016 /*
12017 ** Make sure we can call this stuff from C++.
12018 */
12019 #if 0
@@ -15275,22 +15399,21 @@
15275 SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
15276 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
15277 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
15278 SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
15279 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
15280 # ifdef SQLITE_DIRECT_OVERFLOW_READ
15281 SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno);
15282 # endif
15283 # ifdef SQLITE_ENABLE_SNAPSHOT
15284 SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
15285 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
15286 SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
15287 SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
15288 SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
15289 # endif
15290 #else
15291 # define sqlite3PagerUseWal(x,y) 0
 
 
15292 #endif
15293
15294 #ifdef SQLITE_ENABLE_ZIPVFS
15295 SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
15296 #endif
@@ -15530,10 +15653,14 @@
15530 SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
15531 SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
15532
15533 /* Number of dirty pages as a percentage of the configured cache size */
15534 SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
 
 
 
 
15535
15536 #endif /* _PCACHE_H_ */
15537
15538 /************** End of pcache.h **********************************************/
15539 /************** Continuing where we left off in sqliteInt.h ******************/
@@ -16036,16 +16163,18 @@
16036 /*
16037 ** A hash table for built-in function definitions. (Application-defined
16038 ** functions use a regular table table from hash.h.)
16039 **
16040 ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
16041 ** Collisions are on the FuncDef.u.pHash chain.
 
16042 */
16043 #define SQLITE_FUNC_HASH_SZ 23
16044 struct FuncDefHash {
16045 FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
16046 };
 
16047
16048 #ifdef SQLITE_USER_AUTHENTICATION
16049 /*
16050 ** Information held in the "sqlite3" database connection object and used
16051 ** to manage user authentication.
@@ -16102,11 +16231,11 @@
16102 CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
16103 sqlite3_mutex *mutex; /* Connection mutex */
16104 Db *aDb; /* All backends */
16105 int nDb; /* Number of backends currently in use */
16106 u32 mDbFlags; /* flags recording internal state */
16107 u32 flags; /* flags settable by pragmas. See below */
16108 i64 lastRowid; /* ROWID of most recent insert (see above) */
16109 i64 szMmap; /* Default mmap_size setting */
16110 u32 nSchemaLock; /* Do not reset the schema when non-zero */
16111 unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
16112 int errCode; /* Most recent error code (SQLITE_*) */
@@ -16268,18 +16397,21 @@
16268 #define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
16269 #define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
16270 #define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
16271 #define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
16272 #define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
 
 
16273
16274 /* Flags used only if debugging */
 
16275 #ifdef SQLITE_DEBUG
16276 #define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
16277 #define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */
16278 #define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */
16279 #define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */
16280 #define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
16281 #endif
16282
16283 /*
16284 ** Allowed values for sqlite3.mDbFlags
16285 */
@@ -16409,12 +16541,13 @@
16409 #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
16410 #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
16411 ** single query - might change over time */
16412 #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
16413 #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
16414 #define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */
16415 #define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
 
16416
16417 /*
16418 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
16419 ** used to create the initializers for the FuncDef structures.
16420 **
@@ -16486,14 +16619,17 @@
16486 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
16487 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
16488 #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
16489 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
16490 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
16491
16492 #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
16493 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
16494 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
 
 
 
 
16495
16496 /*
16497 ** All current savepoints are stored in a linked list starting at
16498 ** sqlite3.pSavepoint. The first element in the list is the most recently
16499 ** opened savepoint. Savepoints are added to the list by the vdbe
@@ -16674,10 +16810,13 @@
16674 ** by an instance of the following structure.
16675 */
16676 struct Table {
16677 char *zName; /* Name of the table or view */
16678 Column *aCol; /* Information about each column */
 
 
 
16679 Index *pIndex; /* List of SQL indexes on this table. */
16680 Select *pSelect; /* NULL for tables. Points to definition if a view. */
16681 FKey *pFKey; /* Linked list of all foreign keys in this table */
16682 char *zColAff; /* String defining the affinity of each column */
16683 ExprList *pCheck; /* All CHECK constraints */
@@ -16724,10 +16863,11 @@
16724 #define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
16725 #define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
16726 #define TF_StatsUsed 0x0100 /* Query planner decisions affected by
16727 ** Index.aiRowLogEst[] values */
16728 #define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
 
16729
16730 /*
16731 ** Test to see whether or not a table is a virtual table. This is
16732 ** done as a macro so that it will be optimized out when virtual
16733 ** table support is omitted from the build.
@@ -17010,10 +17150,16 @@
17010 tRowcnt *anEq; /* Est. number of rows where the key equals this sample */
17011 tRowcnt *anLt; /* Est. number of rows where key is less than this sample */
17012 tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
17013 };
17014
 
 
 
 
 
 
17015 /*
17016 ** Each token coming out of the lexer is an instance of
17017 ** this structure. Tokens are also used as part of an expression.
17018 **
17019 ** The memory that "z" points to is owned by other objects. Take care
@@ -17191,15 +17337,15 @@
17191 i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
17192 u8 op2; /* TK_REGISTER: original value of Expr.op
17193 ** TK_COLUMN: the value of p5 for OP_Column
17194 ** TK_AGG_FUNCTION: nesting depth */
17195 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
17196 Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
17197 ** for a column of an index on an expression */
17198 #ifndef SQLITE_OMIT_WINDOWFUNC
17199 Window *pWin; /* Window definition for window functions */
17200 #endif
17201 };
17202
17203 /*
17204 ** The following are the meanings of bits in the Expr.flags field.
17205 */
@@ -17225,10 +17371,11 @@
17225 #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
17226 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
17227 #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
17228 #define EP_Alias 0x400000 /* Is an alias for a result set column */
17229 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
 
17230
17231 /*
17232 ** The EP_Propagate mask is a set of properties that automatically propagate
17233 ** upwards into parent nodes.
17234 */
@@ -17910,10 +18057,11 @@
17910 ** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
17911 ** OPFLAG_AUXDELETE == BTREE_AUXDELETE
17912 */
17913 #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
17914 /* Also used in P2 (not P5) of OP_Delete */
 
17915 #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
17916 #define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
17917 #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
17918 #define OPFLAG_APPEND 0x08 /* This is likely to be an append */
17919 #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
@@ -18128,10 +18276,11 @@
18128 #endif
18129 #ifndef SQLITE_UNTESTABLE
18130 int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
18131 #endif
18132 int bLocaltimeFault; /* True to fail localtime() calls */
 
18133 int iOnceResetThreshold; /* When to reset OP_Once counters */
18134 u32 szSorterRef; /* Min size in bytes to use sorter-refs */
18135 };
18136
18137 /*
@@ -18381,10 +18530,11 @@
18381 /*
18382 ** Internal function prototypes
18383 */
18384 SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
18385 SQLITE_PRIVATE int sqlite3Strlen30(const char*);
 
18386 SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
18387 #define sqlite3StrNICmp sqlite3_strnicmp
18388
18389 SQLITE_PRIVATE int sqlite3MallocInit(void);
18390 SQLITE_PRIVATE void sqlite3MallocEnd(void);
@@ -18497,10 +18647,11 @@
18497
18498 #if defined(SQLITE_DEBUG)
18499 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
18500 SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
18501 SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
 
18502 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
18503 SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
18504 #ifndef SQLITE_OMIT_WINDOWFUNC
18505 SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
18506 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
@@ -18729,15 +18880,19 @@
18729 #endif
18730 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
18731 SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
18732 SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
18733 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
 
 
 
18734 SQLITE_PRIVATE void sqlite3GenerateRowDelete(
18735 Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
18736 SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
18737 SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
18738 SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
 
18739 SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
18740 u8,u8,int,int*,int*,Upsert*);
18741 #ifdef SQLITE_ENABLE_NULL_TRIM
18742 SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
18743 #else
@@ -18754,10 +18909,13 @@
18754 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
18755 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
18756 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
18757 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
18758 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
 
 
 
18759 SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
18760 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
18761 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
18762 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
18763 SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
@@ -18911,10 +19069,11 @@
18911 SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
18912 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
18913 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
18914 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
18915 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
 
18916 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
18917 SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
18918 SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
18919 SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
18920 SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64);
@@ -18957,10 +19116,13 @@
18957 SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
18958 SQLITE_PRIVATE void sqlite3AlterFunctions(void);
18959 SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
18960 SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
18961 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
 
 
 
18962 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
18963 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
18964 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
18965 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
18966 SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
@@ -19114,10 +19276,13 @@
19114 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
19115 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
19116 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
19117 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
19118 SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
 
 
 
19119 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
19120 SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
19121 SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
19122 SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
19123 SQLITE_PRIVATE const char *sqlite3JournalModename(int);
@@ -19575,10 +19740,11 @@
19575 #endif
19576 #ifndef SQLITE_UNTESTABLE
19577 0, /* xTestCallback */
19578 #endif
19579 0, /* bLocaltimeFault */
 
19580 0x7ffffffe, /* iOnceResetThreshold */
19581 SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
19582 };
19583
19584 /*
@@ -20066,10 +20232,13 @@
20066 bft bIsReader:1; /* True for statements that read */
20067 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
20068 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
20069 u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
20070 char *zSql; /* Text of the SQL statement that generated this */
 
 
 
20071 void *pFree; /* Free this when deleting the vdbe */
20072 VdbeFrame *pFrame; /* Parent frame */
20073 VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
20074 int nFrame; /* Number of frames in pFrame list */
20075 u32 expmask; /* Binding to these vars invalidates VM */
@@ -20128,11 +20297,13 @@
20128
20129 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
20130 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
20131 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
20132 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
 
20133 SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
 
20134 SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
20135 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
20136 SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
20137 SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
20138 SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
@@ -20167,11 +20338,13 @@
20167 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
20168 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
20169 #ifndef SQLITE_OMIT_WINDOWFUNC
20170 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
20171 #endif
 
20172 SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
 
20173 SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
20174 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
20175 SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
20176 #ifdef SQLITE_DEBUG
20177 SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
@@ -28294,10 +28467,46 @@
28294 }
28295 sqlite3TreeViewPop(pView);
28296 }
28297 }
28298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28299
28300 /*
28301 ** Generate a human-readable description of a Select object.
28302 */
28303 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
@@ -28348,43 +28557,13 @@
28348 }
28349 sqlite3TreeViewPop(pView);
28350 }
28351 #endif
28352 if( p->pSrc && p->pSrc->nSrc ){
28353 int i;
28354 pView = sqlite3TreeViewPush(pView, (n--)>0);
28355 sqlite3TreeViewLine(pView, "FROM");
28356 for(i=0; i<p->pSrc->nSrc; i++){
28357 struct SrcList_item *pItem = &p->pSrc->a[i];
28358 StrAccum x;
28359 char zLine[100];
28360 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
28361 sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
28362 if( pItem->zDatabase ){
28363 sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
28364 }else if( pItem->zName ){
28365 sqlite3_str_appendf(&x, " %s", pItem->zName);
28366 }
28367 if( pItem->pTab ){
28368 sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
28369 }
28370 if( pItem->zAlias ){
28371 sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
28372 }
28373 if( pItem->fg.jointype & JT_LEFT ){
28374 sqlite3_str_appendf(&x, " LEFT-JOIN");
28375 }
28376 sqlite3StrAccumFinish(&x);
28377 sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
28378 if( pItem->pSelect ){
28379 sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
28380 }
28381 if( pItem->fg.isTabFunc ){
28382 sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
28383 }
28384 sqlite3TreeViewPop(pView);
28385 }
28386 sqlite3TreeViewPop(pView);
28387 }
28388 if( p->pWhere ){
28389 sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
28390 sqlite3TreeViewExpr(pView, p->pWhere, 0);
@@ -28670,11 +28849,11 @@
28670 pFarg = 0;
28671 pWin = 0;
28672 }else{
28673 pFarg = pExpr->x.pList;
28674 #ifndef SQLITE_OMIT_WINDOWFUNC
28675 pWin = pExpr->pWin;
28676 #else
28677 pWin = 0;
28678 #endif
28679 }
28680 if( pExpr->op==TK_AGG_FUNCTION ){
@@ -31498,10 +31677,24 @@
31498 h += sqlite3UpperToLower[c];
31499 h *= 0x9e3779b1;
31500 }
31501 return h;
31502 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31503
31504
31505 /* Link pNew element into the hash table pH. If pEntry!=0 then also
31506 ** insert pNew into the pEntry hash bucket.
31507 */
@@ -31609,10 +31802,44 @@
31609 }
31610 elem = elem->next;
31611 }
31612 return &nullElement;
31613 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31614
31615 /* Remove a single entry from the hash table given a pointer to that
31616 ** element and a hash on the element's key.
31617 */
31618 static void removeElementGivenHash(
@@ -31653,10 +31880,18 @@
31653 SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
31654 assert( pH!=0 );
31655 assert( pKey!=0 );
31656 return findElementWithHash(pH, pKey, 0)->data;
31657 }
 
 
 
 
 
 
 
 
31658
31659 /* Insert an element into the hash table pH. The key is pKey
31660 ** and the data is "data".
31661 **
31662 ** If no element exists with a matching key, then a new
@@ -32035,16 +32270,14 @@
32035 ** Allowed values of unixFile.fsFlags
32036 */
32037 #define SQLITE_FSFLAGS_IS_MSDOS 0x1
32038
32039 /*
32040 ** If we are to be thread-safe, include the pthreads header and define
32041 ** the SQLITE_UNIX_THREADS macro.
32042 */
32043 #if SQLITE_THREADSAFE
32044 /* # include <pthread.h> */
32045 # define SQLITE_UNIX_THREADS 1
32046 #endif
32047
32048 /*
32049 ** Default permissions when creating a new file
32050 */
@@ -33216,12 +33449,11 @@
33216 #endif
33217 };
33218
33219 /*
33220 ** An instance of the following structure is allocated for each open
33221 ** inode. Or, on LinuxThreads, there is one of these structures for
33222 ** each inode opened by each thread.
33223 **
33224 ** A single inode can have multiple file descriptors, so each unixFile
33225 ** structure contains a pointer to an instance of this object and this
33226 ** object keeps a count of the number of unixFile pointing to it.
33227 **
@@ -33263,17 +33495,20 @@
33263 #endif
33264 };
33265
33266 /*
33267 ** A lists of all unixInodeInfo objects.
 
 
33268 */
33269 static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
33270
33271 #ifdef SQLITE_DEBUG
33272 /*
33273 ** True if the inode mutex is held, or not. Used only within assert()
33274 ** to help verify correct mutex usage.
 
33275 */
33276 int unixFileMutexHeld(unixFile *pFile){
33277 assert( pFile->pInode );
33278 return sqlite3_mutex_held(pFile->pInode->pLockMutex);
33279 }
@@ -33397,12 +33632,12 @@
33397 }
33398
33399 /*
33400 ** Release a unixInodeInfo structure previously allocated by findInodeInfo().
33401 **
33402 ** The mutex entered using the unixEnterMutex() function must be held
33403 ** when this function is called.
33404 */
33405 static void releaseInodeInfo(unixFile *pFile){
33406 unixInodeInfo *pInode = pFile->pInode;
33407 assert( unixMutexHeld() );
33408 assert( unixFileMutexNotheld(pFile) );
@@ -33433,12 +33668,11 @@
33433 /*
33434 ** Given a file descriptor, locate the unixInodeInfo object that
33435 ** describes that file descriptor. Create a new one if necessary. The
33436 ** return value might be uninitialized if an error occurs.
33437 **
33438 ** The mutex entered using the unixEnterMutex() function must be held
33439 ** when this function is called.
33440 **
33441 ** Return an appropriate error code.
33442 */
33443 static int findInodeInfo(
33444 unixFile *pFile, /* Unix file with file desc used in the key */
@@ -33495,10 +33729,11 @@
33495 #if OS_VXWORKS
33496 fileId.pId = pFile->pId;
33497 #else
33498 fileId.ino = (u64)statbuf.st_ino;
33499 #endif
 
33500 pInode = inodeList;
33501 while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
33502 pInode = pInode->pNext;
33503 }
33504 if( pInode==0 ){
@@ -33514,10 +33749,11 @@
33514 sqlite3_free(pInode);
33515 return SQLITE_NOMEM_BKPT;
33516 }
33517 }
33518 pInode->nRef = 1;
 
33519 pInode->pNext = inodeList;
33520 pInode->pPrev = 0;
33521 if( inodeList ) inodeList->pPrev = pInode;
33522 inodeList = pInode;
33523 }else{
@@ -36311,22 +36547,22 @@
36311 **
36312 ** nRef
36313 **
36314 ** The following fields are read-only after the object is created:
36315 **
36316 ** fid
36317 ** zFilename
36318 **
36319 ** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
36320 ** unixMutexHeld() is true when reading or writing any other field
36321 ** in this structure.
36322 */
36323 struct unixShmNode {
36324 unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
36325 sqlite3_mutex *mutex; /* Mutex to access this object */
36326 char *zFilename; /* Name of the mmapped file */
36327 int h; /* Open file descriptor */
36328 int szRegion; /* Size of shared-memory regions */
36329 u16 nRegion; /* Size of array apRegion */
36330 u8 isReadonly; /* True if read-only */
36331 u8 isUnlocked; /* True if no DMS lock held */
36332 char **apRegion; /* Array of mapped shared-memory regions */
@@ -36344,20 +36580,20 @@
36344 ** open shared memory connection.
36345 **
36346 ** The following fields are initialized when this object is created and
36347 ** are read-only thereafter:
36348 **
36349 ** unixShm.pFile
36350 ** unixShm.id
36351 **
36352 ** All other fields are read/write. The unixShm.pFile->mutex must be held
36353 ** while accessing any read/write fields.
36354 */
36355 struct unixShm {
36356 unixShmNode *pShmNode; /* The underlying unixShmNode object */
36357 unixShm *pNext; /* Next unixShm with the same unixShmNode */
36358 u8 hasMutex; /* True if holding the unixShmNode mutex */
36359 u8 id; /* Id of this connection within its unixShmNode */
36360 u16 sharedMask; /* Mask of shared locks held */
36361 u16 exclMask; /* Mask of exclusive locks held */
36362 };
36363
@@ -36383,25 +36619,26 @@
36383 struct flock f; /* The posix advisory locking structure */
36384 int rc = SQLITE_OK; /* Result code form fcntl() */
36385
36386 /* Access to the unixShmNode object is serialized by the caller */
36387 pShmNode = pFile->pInode->pShmNode;
36388 assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
 
36389
36390 /* Shared locks never span more than one byte */
36391 assert( n==1 || lockType!=F_RDLCK );
36392
36393 /* Locks are within range */
36394 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
36395
36396 if( pShmNode->h>=0 ){
36397 /* Initialize the locking parameters */
36398 f.l_type = lockType;
36399 f.l_whence = SEEK_SET;
36400 f.l_start = ofst;
36401 f.l_len = n;
36402 rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
36403 rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
36404 }
36405
36406 /* Update the global lock state and do debug tracing */
36407 #ifdef SQLITE_DEBUG
@@ -36469,22 +36706,22 @@
36469 assert( unixMutexHeld() );
36470 if( p && ALWAYS(p->nRef==0) ){
36471 int nShmPerMap = unixShmRegionPerMap();
36472 int i;
36473 assert( p->pInode==pFd->pInode );
36474 sqlite3_mutex_free(p->mutex);
36475 for(i=0; i<p->nRegion; i+=nShmPerMap){
36476 if( p->h>=0 ){
36477 osMunmap(p->apRegion[i], p->szRegion);
36478 }else{
36479 sqlite3_free(p->apRegion[i]);
36480 }
36481 }
36482 sqlite3_free(p->apRegion);
36483 if( p->h>=0 ){
36484 robust_close(pFd, p->h, __LINE__);
36485 p->h = -1;
36486 }
36487 p->pInode->pShmNode = 0;
36488 sqlite3_free(p);
36489 }
36490 }
@@ -36522,19 +36759,24 @@
36522 ** system crash, the database itself may also become corrupt. */
36523 lock.l_whence = SEEK_SET;
36524 lock.l_start = UNIX_SHM_DMS;
36525 lock.l_len = 1;
36526 lock.l_type = F_WRLCK;
36527 if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
36528 rc = SQLITE_IOERR_LOCK;
36529 }else if( lock.l_type==F_UNLCK ){
36530 if( pShmNode->isReadonly ){
36531 pShmNode->isUnlocked = 1;
36532 rc = SQLITE_READONLY_CANTINIT;
36533 }else{
36534 rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
36535 if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
 
 
 
 
 
36536 rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
36537 }
36538 }
36539 }else if( lock.l_type==F_WRLCK ){
36540 rc = SQLITE_BUSY;
@@ -36636,28 +36878,28 @@
36636 (u32)sStat.st_ino, (u32)sStat.st_dev);
36637 #else
36638 sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
36639 sqlite3FileSuffix3(pDbFd->zPath, zShm);
36640 #endif
36641 pShmNode->h = -1;
36642 pDbFd->pInode->pShmNode = pShmNode;
36643 pShmNode->pInode = pDbFd->pInode;
36644 if( sqlite3GlobalConfig.bCoreMutex ){
36645 pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
36646 if( pShmNode->mutex==0 ){
36647 rc = SQLITE_NOMEM_BKPT;
36648 goto shm_open_err;
36649 }
36650 }
36651
36652 if( pInode->bProcessLock==0 ){
36653 if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
36654 pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
36655 }
36656 if( pShmNode->h<0 ){
36657 pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
36658 if( pShmNode->h<0 ){
36659 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
36660 goto shm_open_err;
36661 }
36662 pShmNode->isReadonly = 1;
36663 }
@@ -36664,11 +36906,11 @@
36664
36665 /* If this process is running as root, make sure that the SHM file
36666 ** is owned by the same user that owns the original database. Otherwise,
36667 ** the original owner will not be able to connect.
36668 */
36669 robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
36670
36671 rc = unixLockSharedMemory(pDbFd, pShmNode);
36672 if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
36673 }
36674 }
@@ -36684,17 +36926,17 @@
36684
36685 /* The reference count on pShmNode has already been incremented under
36686 ** the cover of the unixEnterMutex() mutex and the pointer from the
36687 ** new (struct unixShm) object to the pShmNode has been set. All that is
36688 ** left to do is to link the new object into the linked list starting
36689 ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
36690 ** mutex.
36691 */
36692 sqlite3_mutex_enter(pShmNode->mutex);
36693 p->pNext = pShmNode->pFirst;
36694 pShmNode->pFirst = p;
36695 sqlite3_mutex_leave(pShmNode->mutex);
36696 return rc;
36697
36698 /* Jump here on any error */
36699 shm_open_err:
36700 unixShmPurge(pDbFd); /* This call frees pShmNode if required */
@@ -36742,20 +36984,20 @@
36742 if( rc!=SQLITE_OK ) return rc;
36743 }
36744
36745 p = pDbFd->pShm;
36746 pShmNode = p->pShmNode;
36747 sqlite3_mutex_enter(pShmNode->mutex);
36748 if( pShmNode->isUnlocked ){
36749 rc = unixLockSharedMemory(pDbFd, pShmNode);
36750 if( rc!=SQLITE_OK ) goto shmpage_out;
36751 pShmNode->isUnlocked = 0;
36752 }
36753 assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
36754 assert( pShmNode->pInode==pDbFd->pInode );
36755 assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
36756 assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
36757
36758 /* Minimum number of regions required to be mapped. */
36759 nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
36760
36761 if( pShmNode->nRegion<nReqRegion ){
@@ -36763,16 +37005,16 @@
36763 int nByte = nReqRegion*szRegion; /* Minimum required file size */
36764 struct stat sStat; /* Used by fstat() */
36765
36766 pShmNode->szRegion = szRegion;
36767
36768 if( pShmNode->h>=0 ){
36769 /* The requested region is not mapped into this processes address space.
36770 ** Check to see if it has been allocated (i.e. if the wal-index file is
36771 ** large enough to contain the requested region).
36772 */
36773 if( osFstat(pShmNode->h, &sStat) ){
36774 rc = SQLITE_IOERR_SHMSIZE;
36775 goto shmpage_out;
36776 }
36777
36778 if( sStat.st_size<nByte ){
@@ -36796,11 +37038,11 @@
36796
36797 /* Write to the last byte of each newly allocated or extended page */
36798 assert( (nByte % pgsz)==0 );
36799 for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
36800 int x = 0;
36801 if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
36802 const char *zFile = pShmNode->zFilename;
36803 rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
36804 goto shmpage_out;
36805 }
36806 }
@@ -36819,26 +37061,26 @@
36819 pShmNode->apRegion = apNew;
36820 while( pShmNode->nRegion<nReqRegion ){
36821 int nMap = szRegion*nShmPerMap;
36822 int i;
36823 void *pMem;
36824 if( pShmNode->h>=0 ){
36825 pMem = osMmap(0, nMap,
36826 pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
36827 MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
36828 );
36829 if( pMem==MAP_FAILED ){
36830 rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
36831 goto shmpage_out;
36832 }
36833 }else{
36834 pMem = sqlite3_malloc64(szRegion);
36835 if( pMem==0 ){
36836 rc = SQLITE_NOMEM_BKPT;
36837 goto shmpage_out;
36838 }
36839 memset(pMem, 0, szRegion);
36840 }
36841
36842 for(i=0; i<nShmPerMap; i++){
36843 pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
36844 }
@@ -36851,11 +37093,11 @@
36851 *pp = pShmNode->apRegion[iRegion];
36852 }else{
36853 *pp = 0;
36854 }
36855 if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
36856 sqlite3_mutex_leave(pShmNode->mutex);
36857 return rc;
36858 }
36859
36860 /*
36861 ** Change the lock state for a shared-memory segment.
@@ -36885,16 +37127,16 @@
36885 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
36886 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
36887 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
36888 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
36889 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
36890 assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
36891 assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
36892
36893 mask = (1<<(ofst+n)) - (1<<ofst);
36894 assert( n>1 || mask==(1<<ofst) );
36895 sqlite3_mutex_enter(pShmNode->mutex);
36896 if( flags & SQLITE_SHM_UNLOCK ){
36897 u16 allMask = 0; /* Mask of locks held by siblings */
36898
36899 /* See if any siblings hold this same lock */
36900 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
@@ -36963,11 +37205,11 @@
36963 assert( (p->sharedMask & mask)==0 );
36964 p->exclMask |= mask;
36965 }
36966 }
36967 }
36968 sqlite3_mutex_leave(pShmNode->mutex);
36969 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
36970 p->id, osGetpid(0), p->sharedMask, p->exclMask));
36971 return rc;
36972 }
36973
@@ -37013,27 +37255,27 @@
37013 assert( pShmNode==pDbFd->pInode->pShmNode );
37014 assert( pShmNode->pInode==pDbFd->pInode );
37015
37016 /* Remove connection p from the set of connections associated
37017 ** with pShmNode */
37018 sqlite3_mutex_enter(pShmNode->mutex);
37019 for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
37020 *pp = p->pNext;
37021
37022 /* Free the connection p */
37023 sqlite3_free(p);
37024 pDbFd->pShm = 0;
37025 sqlite3_mutex_leave(pShmNode->mutex);
37026
37027 /* If pShmNode->nRef has reached 0, then close the underlying
37028 ** shared-memory file, too */
37029 assert( unixFileMutexNotheld(pDbFd) );
37030 unixEnterMutex();
37031 assert( pShmNode->nRef>0 );
37032 pShmNode->nRef--;
37033 if( pShmNode->nRef==0 ){
37034 if( deleteFlag && pShmNode->h>=0 ){
37035 osUnlink(pShmNode->zFilename);
37036 }
37037 unixShmPurge(pDbFd);
37038 }
37039 unixLeaveMutex();
@@ -40447,12 +40689,11 @@
40447 #endif
40448 #if SQLITE_MAX_MMAP_SIZE>0
40449 int nFetchOut; /* Number of outstanding xFetch references */
40450 HANDLE hMap; /* Handle for accessing memory mapping */
40451 void *pMapRegion; /* Area memory mapped */
40452 sqlite3_int64 mmapSize; /* Usable size of mapped region */
40453 sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
40454 sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
40455 #endif
40456 };
40457
40458 /*
@@ -43069,10 +43310,30 @@
43069 winFile *pFile = (winFile*)id; /* File handle object */
43070 int rc = SQLITE_OK; /* Return code for this function */
43071 DWORD lastErrno;
43072 #if SQLITE_MAX_MMAP_SIZE>0
43073 sqlite3_int64 oldMmapSize;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43074 #endif
43075
43076 assert( pFile );
43077 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
43078 OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
@@ -44497,13 +44758,13 @@
44497 */
44498 #if SQLITE_MAX_MMAP_SIZE>0
44499 static int winUnmapfile(winFile *pFile){
44500 assert( pFile!=0 );
44501 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
44502 "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
44503 osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
44504 pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
44505 if( pFile->pMapRegion ){
44506 if( !osUnmapViewOfFile(pFile->pMapRegion) ){
44507 pFile->lastErrno = osGetLastError();
44508 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
44509 "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
@@ -44511,11 +44772,10 @@
44511 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
44512 "winUnmapfile1", pFile->zPath);
44513 }
44514 pFile->pMapRegion = 0;
44515 pFile->mmapSize = 0;
44516 pFile->mmapSizeActual = 0;
44517 }
44518 if( pFile->hMap!=NULL ){
44519 if( !osCloseHandle(pFile->hMap) ){
44520 pFile->lastErrno = osGetLastError();
44521 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
@@ -44622,11 +44882,10 @@
44622 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
44623 return SQLITE_OK;
44624 }
44625 pFd->pMapRegion = pNew;
44626 pFd->mmapSize = nMap;
44627 pFd->mmapSizeActual = nMap;
44628 }
44629
44630 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
44631 osGetCurrentProcessId(), pFd));
44632 return SQLITE_OK;
@@ -45424,11 +45683,10 @@
45424 pFile->zPath = zName;
45425 #if SQLITE_MAX_MMAP_SIZE>0
45426 pFile->hMap = NULL;
45427 pFile->pMapRegion = 0;
45428 pFile->mmapSize = 0;
45429 pFile->mmapSizeActual = 0;
45430 pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
45431 #endif
45432
45433 OpenCounter(+1);
45434 return rc;
@@ -47321,11 +47579,11 @@
47321 ** pDirtyTail to the last (oldest).
47322 **
47323 ** The PCache.pSynced variable is used to optimize searching for a dirty
47324 ** page to eject from the cache mid-transaction. It is better to eject
47325 ** a page that does not require a journal sync than one that does.
47326 ** Therefore, pSynced is maintained to that it *almost* always points
47327 ** to either the oldest page in the pDirty/pDirtyTail list that has a
47328 ** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
47329 ** (so that the right page to eject can be found by following pDirtyPrev
47330 ** pointers).
47331 */
@@ -48144,10 +48402,19 @@
48144 int nDirty = 0;
48145 int nCache = numberOfCachePages(pCache);
48146 for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
48147 return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
48148 }
 
 
 
 
 
 
 
 
 
48149
48150 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
48151 /*
48152 ** For all dirty pages currently in the cache, invoke the specified
48153 ** callback. This is only used if the SQLITE_CHECK_PAGES macro is
@@ -48268,11 +48535,12 @@
48268 PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
48269 PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
48270 };
48271
48272 /*
48273 ** A page is pinned if it is no on the LRU list
 
48274 */
48275 #define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
48276 #define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
48277
48278 /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
@@ -50908,23 +51176,34 @@
50908 **
50909 ** if( pPager->jfd->pMethods ){ ...
50910 */
50911 #define isOpen(pFd) ((pFd)->pMethods!=0)
50912
 
50913 /*
50914 ** Return true if this pager uses a write-ahead log to read page pgno.
50915 ** Return false if the pager reads pgno directly from the database.
 
 
 
 
50916 */
50917 #if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
50918 SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
50919 u32 iRead = 0;
50920 int rc;
50921 if( pPager->pWal==0 ) return 0;
50922 rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
50923 return rc || iRead;
 
 
 
 
 
50924 }
50925 #endif
 
50926 #ifndef SQLITE_OMIT_WAL
50927 # define pagerUseWal(x) ((x)->pWal!=0)
50928 #else
50929 # define pagerUseWal(x) 0
50930 # define pagerRollbackWal(x) 0
@@ -57104,11 +57383,15 @@
57104 void *(*xCodec)(void*,void*,Pgno,int),
57105 void (*xCodecSizeChng)(void*,int,int),
57106 void (*xCodecFree)(void*),
57107 void *pCodec
57108 ){
57109 if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
 
 
 
 
57110 pPager->xCodec = pPager->memDb ? 0 : xCodec;
57111 pPager->xCodecSizeChng = xCodecSizeChng;
57112 pPager->xCodecFree = xCodecFree;
57113 pPager->pCodec = pCodec;
57114 setGetterMethod(pPager);
@@ -65764,11 +66047,11 @@
65764 freeTempSpace(pBt);
65765 rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
65766 pageSize-usableSize);
65767 return rc;
65768 }
65769 if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
65770 rc = SQLITE_CORRUPT_BKPT;
65771 goto page1_init_failed;
65772 }
65773 /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
65774 ** be less than 480. In other words, if the page size is 512, then the
@@ -66238,10 +66521,11 @@
66238
66239 assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
66240 eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
66241 assert( sqlite3_mutex_held(pBt->mutex) );
66242 assert( pDbPage->pBt==pBt );
 
66243
66244 /* Move page iDbPage from its current location to page number iFreePage */
66245 TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
66246 iDbPage, iFreePage, iPtrPage, eType));
66247 rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
@@ -67409,13 +67693,10 @@
67409 offset -= ovflSize;
67410 }else{
67411 /* Need to read this page properly. It contains some of the
67412 ** range of data that is being read (eOp==0) or written (eOp!=0).
67413 */
67414 #ifdef SQLITE_DIRECT_OVERFLOW_READ
67415 sqlite3_file *fd; /* File from which to do direct overflow read */
67416 #endif
67417 int a = amt;
67418 if( a + offset > ovflSize ){
67419 a = ovflSize - offset;
67420 }
67421
@@ -67422,11 +67703,11 @@
67422 #ifdef SQLITE_DIRECT_OVERFLOW_READ
67423 /* If all the following are true:
67424 **
67425 ** 1) this is a read operation, and
67426 ** 2) data is required from the start of this overflow page, and
67427 ** 3) there is no open write-transaction, and
67428 ** 4) the database is file-backed, and
67429 ** 5) the page is not in the WAL file
67430 ** 6) at least 4 bytes have already been read into the output buffer
67431 **
67432 ** then data can be read directly from the database file into the
@@ -67433,15 +67714,14 @@
67433 ** output buffer, bypassing the page-cache altogether. This speeds
67434 ** up loading large records that span many overflow pages.
67435 */
67436 if( eOp==0 /* (1) */
67437 && offset==0 /* (2) */
67438 && pBt->inTransaction==TRANS_READ /* (3) */
67439 && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */
67440 && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */
67441 && &pBuf[-4]>=pBufStart /* (6) */
67442 ){
 
67443 u8 aSave[4];
67444 u8 *aWrite = &pBuf[-4];
67445 assert( aWrite>=pBufStart ); /* due to (6) */
67446 memcpy(aSave, aWrite, 4);
67447 rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
@@ -74033,11 +74313,12 @@
74033 sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
74034 }else{
74035 assert( fg & MEM_Real );
74036 sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
74037 }
74038 pMem->n = sqlite3Strlen30(pMem->z);
 
74039 pMem->enc = SQLITE_UTF8;
74040 pMem->flags |= MEM_Str|MEM_Term;
74041 if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
74042 sqlite3VdbeChangeEncoding(pMem, enc);
74043 return SQLITE_OK;
@@ -75608,10 +75889,17 @@
75608 if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
75609 p->expmask = 0;
75610 }
75611 assert( p->zSql==0 );
75612 p->zSql = sqlite3DbStrNDup(p->db, z, n);
 
 
 
 
 
 
 
75613 }
75614
75615 /*
75616 ** Swap all content between two VDBE structures.
75617 */
@@ -75629,10 +75917,15 @@
75629 pA->pPrev = pB->pPrev;
75630 pB->pPrev = pTmp;
75631 zTmp = pA->zSql;
75632 pA->zSql = pB->zSql;
75633 pB->zSql = zTmp;
 
 
 
 
 
75634 pB->expmask = pA->expmask;
75635 pB->prepFlags = pA->prepFlags;
75636 memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
75637 pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
75638 }
@@ -78700,10 +78993,13 @@
78700 sqlite3DbFree(db, p->pFree);
78701 }
78702 vdbeFreeOpArray(db, p->aOp, p->nOp);
78703 sqlite3DbFree(db, p->aColName);
78704 sqlite3DbFree(db, p->zSql);
 
 
 
78705 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
78706 {
78707 int i;
78708 for(i=0; i<p->nScan; i++){
78709 sqlite3DbFree(db, p->aScan[i].zName);
@@ -80101,11 +80397,13 @@
80101
80102 /* The index entry must begin with a header size */
80103 (void)getVarint32((u8*)m.z, szHdr);
80104 testcase( szHdr==3 );
80105 testcase( szHdr==m.n );
80106 if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
 
 
80107 goto idx_rowid_corruption;
80108 }
80109
80110 /* The last field of the index should be an integer - the ROWID.
80111 ** Verify that the last entry really is an integer. */
@@ -82112,10 +82410,20 @@
82112 }
82113 return z;
82114 #endif
82115 }
82116
 
 
 
 
 
 
 
 
 
 
82117 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
82118 /*
82119 ** Allocate and populate an UnpackedRecord structure based on the serialized
82120 ** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
82121 ** if successful, or a NULL pointer if an OOM error is encountered.
@@ -85551,21 +85859,29 @@
85551 nVarint = sqlite3VarintLen(nHdr);
85552 nHdr += nVarint;
85553 if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
85554 }
85555 nByte = nHdr+nData;
85556 if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
85557 goto too_big;
85558 }
85559
85560 /* Make sure the output register has a buffer large enough to store
85561 ** the new record. The output register (pOp->p3) is not allowed to
85562 ** be one of the input registers (because the following call to
85563 ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
85564 */
85565 if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
85566 goto no_mem;
 
 
 
 
 
 
 
 
 
 
 
85567 }
85568 zNewRecord = (u8 *)pOut->z;
85569
85570 /* Write the record */
85571 i = putVarint32(zNewRecord, nHdr);
@@ -88417,11 +88733,11 @@
88417 }else
88418 #endif
88419 {
88420 zMaster = MASTER_NAME;
88421 initData.db = db;
88422 initData.iDb = pOp->p1;
88423 initData.pzErrMsg = &p->zErrMsg;
88424 initData.mInitFlags = 0;
88425 zSql = sqlite3MPrintf(db,
88426 "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
88427 db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
@@ -89614,14 +89930,15 @@
89614 ** Store in register P3 the value of the P2-th column of
89615 ** the current row of the virtual-table of cursor P1.
89616 **
89617 ** If the VColumn opcode is being used to fetch the value of
89618 ** an unchanging column during an UPDATE operation, then the P5
89619 ** value is 1. Otherwise, P5 is 0. The P5 value is returned
89620 ** by sqlite3_vtab_nochange() routine and can be used
89621 ** by virtual table implementations to return special "no-change"
89622 ** marks which can be more efficient, depending on the virtual table.
 
89623 */
89624 case OP_VColumn: {
89625 sqlite3_vtab *pVtab;
89626 const sqlite3_module *pModule;
89627 Mem *pDest;
@@ -89639,11 +89956,12 @@
89639 pVtab = pCur->uc.pVCur->pVtab;
89640 pModule = pVtab->pModule;
89641 assert( pModule->xColumn );
89642 memset(&sContext, 0, sizeof(sContext));
89643 sContext.pOut = pDest;
89644 if( pOp->p5 ){
 
89645 sqlite3VdbeMemSetNull(pDest);
89646 pDest->flags = MEM_Null|MEM_Zero;
89647 pDest->u.nZero = 0;
89648 }else{
89649 MemSetTypeFlag(pDest, MEM_Null);
@@ -93998,12 +94316,12 @@
93998 if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
93999 }else if( pExpr->x.pList ){
94000 if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
94001 }
94002 #ifndef SQLITE_OMIT_WINDOWFUNC
94003 if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
94004 Window *pWin = pExpr->pWin;
94005 if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
94006 if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
94007 if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
94008 }
94009 #endif
@@ -94272,11 +94590,11 @@
94272 **
94273 ** pExpr->iDb Set the index in db->aDb[] of the database X
94274 ** (even if X is implied).
94275 ** pExpr->iTable Set to the cursor number for the table obtained
94276 ** from pSrcList.
94277 ** pExpr->pTab Points to the Table structure of X.Y (even if
94278 ** X and/or Y are implied.)
94279 ** pExpr->iColumn Set to the column number within the table.
94280 ** pExpr->op Set to TK_COLUMN.
94281 ** pExpr->pLeft Any expression this points to is deleted
94282 ** pExpr->pRight Any expression this points to is deleted.
@@ -94316,11 +94634,10 @@
94316 assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
94317 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
94318
94319 /* Initialize the node to no-match */
94320 pExpr->iTable = -1;
94321 pExpr->pTab = 0;
94322 ExprSetVVAProperty(pExpr, EP_NoReduce);
94323
94324 /* Translate the schema name in zDb into a pointer to the corresponding
94325 ** schema. If not found, pSchema will remain NULL and nothing will match
94326 ** resulting in an appropriate error message toward the end of this routine
@@ -94378,11 +94695,11 @@
94378 assert( zTabName!=0 );
94379 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
94380 continue;
94381 }
94382 if( IN_RENAME_OBJECT && pItem->zAlias ){
94383 sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
94384 }
94385 }
94386 if( 0==(cntTab++) ){
94387 pMatch = pItem;
94388 }
@@ -94404,17 +94721,17 @@
94404 }
94405 }
94406 }
94407 if( pMatch ){
94408 pExpr->iTable = pMatch->iCursor;
94409 pExpr->pTab = pMatch->pTab;
94410 /* RIGHT JOIN not (yet) supported */
94411 assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
94412 if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
94413 ExprSetProperty(pExpr, EP_CanBeNull);
94414 }
94415 pSchema = pExpr->pTab->pSchema;
94416 }
94417 } /* if( pSrcList ) */
94418
94419 #if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
94420 /* If we have not already resolved the name, then maybe
@@ -94467,11 +94784,11 @@
94467 #ifndef SQLITE_OMIT_UPSERT
94468 if( pExpr->iTable==2 ){
94469 testcase( iCol==(-1) );
94470 if( IN_RENAME_OBJECT ){
94471 pExpr->iColumn = iCol;
94472 pExpr->pTab = pTab;
94473 eNewExprOp = TK_COLUMN;
94474 }else{
94475 pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
94476 eNewExprOp = TK_REGISTER;
94477 ExprSetProperty(pExpr, EP_Alias);
@@ -94489,11 +94806,11 @@
94489 }else{
94490 testcase( iCol==31 );
94491 testcase( iCol==32 );
94492 pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
94493 }
94494 pExpr->pTab = pTab;
94495 pExpr->iColumn = (i16)iCol;
94496 eNewExprOp = TK_TRIGGER;
94497 #endif /* SQLITE_OMIT_TRIGGER */
94498 }
94499 }
@@ -94589,11 +94906,11 @@
94589 */
94590 if( cnt==0 && zTab==0 ){
94591 assert( pExpr->op==TK_ID );
94592 if( ExprHasProperty(pExpr,EP_DblQuoted) ){
94593 pExpr->op = TK_STRING;
94594 pExpr->pTab = 0;
94595 return WRC_Prune;
94596 }
94597 if( sqlite3ExprIdToTrueFalse(pExpr) ){
94598 return WRC_Prune;
94599 }
@@ -94667,13 +94984,13 @@
94667 */
94668 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
94669 Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
94670 if( p ){
94671 struct SrcList_item *pItem = &pSrc->a[iSrc];
94672 p->pTab = pItem->pTab;
94673 p->iTable = pItem->iCursor;
94674 if( p->pTab->iPKey==iCol ){
94675 p->iColumn = -1;
94676 }else{
94677 p->iColumn = (ynVar)iCol;
94678 testcase( iCol==BMS );
94679 testcase( iCol==BMS-1 );
@@ -94759,11 +95076,11 @@
94759 struct SrcList_item *pItem;
94760 assert( pSrcList && pSrcList->nSrc==1 );
94761 pItem = pSrcList->a;
94762 assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
94763 pExpr->op = TK_COLUMN;
94764 pExpr->pTab = pItem->pTab;
94765 pExpr->iTable = pItem->iCursor;
94766 pExpr->iColumn = -1;
94767 pExpr->affinity = SQLITE_AFF_INTEGER;
94768 break;
94769 }
@@ -94803,13 +95120,11 @@
94803 }
94804 zTable = pLeft->u.zToken;
94805 zColumn = pRight->u.zToken;
94806 if( IN_RENAME_OBJECT ){
94807 sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
94808 }
94809 if( IN_RENAME_OBJECT ){
94810 sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
94811 }
94812 }
94813 return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
94814 }
94815
@@ -94887,30 +95202,39 @@
94887 ** sqlite_version() that might change over time cannot be used
94888 ** in an index. */
94889 notValid(pParse, pNC, "non-deterministic functions",
94890 NC_IdxExpr|NC_PartIdx);
94891 }
 
 
 
 
 
 
 
 
 
94892 }
94893
94894 if( 0==IN_RENAME_OBJECT ){
94895 #ifndef SQLITE_OMIT_WINDOWFUNC
94896 assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
94897 || (pDef->xValue==0 && pDef->xInverse==0)
94898 || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
94899 );
94900 if( pDef && pDef->xValue==0 && pExpr->pWin ){
94901 sqlite3ErrorMsg(pParse,
94902 "%.*s() may not be used as a window function", nId, zId
94903 );
94904 pNC->nErr++;
94905 }else if(
94906 (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
94907 || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
94908 || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
94909 ){
94910 const char *zType;
94911 if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
94912 zType = "window";
94913 }else{
94914 zType = "aggregate";
94915 }
94916 sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
@@ -94936,30 +95260,30 @@
94936 nId, zId);
94937 pNC->nErr++;
94938 }
94939 if( is_agg ){
94940 #ifndef SQLITE_OMIT_WINDOWFUNC
94941 pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
94942 #else
94943 pNC->ncFlags &= ~NC_AllowAgg;
94944 #endif
94945 }
94946 }
94947 sqlite3WalkExprList(pWalker, pList);
94948 if( is_agg ){
94949 #ifndef SQLITE_OMIT_WINDOWFUNC
94950 if( pExpr->pWin ){
94951 Select *pSel = pNC->pWinSelect;
94952 sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
94953 sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
94954 sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
94955 sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
94956 if( 0==pSel->pWin
94957 || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin)
94958 ){
94959 pExpr->pWin->pNextWin = pSel->pWin;
94960 pSel->pWin = pExpr->pWin;
94961 }
94962 pNC->ncFlags |= NC_AllowWin;
94963 }else
94964 #endif /* SQLITE_OMIT_WINDOWFUNC */
94965 {
@@ -95378,17 +95702,17 @@
95378 return 1;
95379 }
95380 for(j=0; j<pSelect->pEList->nExpr; j++){
95381 if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
95382 #ifndef SQLITE_OMIT_WINDOWFUNC
95383 if( pE->pWin ){
95384 /* Since this window function is being changed into a reference
95385 ** to the same window function the result set, remove the instance
95386 ** of this window function from the Select.pWin list. */
95387 Window **pp;
95388 for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
95389 if( *pp==pE->pWin ){
95390 *pp = (*pp)->pNextWin;
95391 }
95392 }
95393 }
95394 #endif
@@ -95847,12 +96171,12 @@
95847 if( op==TK_CAST ){
95848 assert( !ExprHasProperty(pExpr, EP_IntValue) );
95849 return sqlite3AffinityType(pExpr->u.zToken, 0);
95850 }
95851 #endif
95852 if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
95853 return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
95854 }
95855 if( op==TK_SELECT_COLUMN ){
95856 assert( pExpr->pLeft->flags&EP_xIsSelect );
95857 return sqlite3ExprAffinity(
95858 pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
@@ -95932,17 +96256,17 @@
95932 while( p ){
95933 int op = p->op;
95934 if( p->flags & EP_Generic ) break;
95935 if( (op==TK_AGG_COLUMN || op==TK_COLUMN
95936 || op==TK_REGISTER || op==TK_TRIGGER)
95937 && p->pTab!=0
95938 ){
95939 /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
95940 ** a TK_COLUMN but was previously evaluated and cached in a register */
95941 int j = p->iColumn;
95942 if( j>=0 ){
95943 const char *zColl = p->pTab->aCol[j].zColl;
95944 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
95945 }
95946 break;
95947 }
95948 if( op==TK_CAST || op==TK_UPLUS ){
@@ -96841,10 +97165,14 @@
96841 */
96842 static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
96843 assert( p!=0 );
96844 /* Sanity check: Assert that the IntValue is non-negative if it exists */
96845 assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
 
 
 
 
96846 #ifdef SQLITE_DEBUG
96847 if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
96848 assert( p->pLeft==0 );
96849 assert( p->pRight==0 );
96850 assert( p->x.pSelect==0 );
@@ -96859,12 +97187,13 @@
96859 }else if( ExprHasProperty(p, EP_xIsSelect) ){
96860 sqlite3SelectDelete(db, p->x.pSelect);
96861 }else{
96862 sqlite3ExprListDelete(db, p->x.pList);
96863 }
96864 if( !ExprHasProperty(p, EP_Reduced) ){
96865 sqlite3WindowDelete(db, p->pWin);
 
96866 }
96867 }
96868 if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
96869 if( !ExprHasProperty(p, EP_Static) ){
96870 sqlite3DbFreeNN(db, p);
@@ -96924,11 +97253,11 @@
96924 assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
96925 assert( EXPR_FULLSIZE<=0xfff );
96926 assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
96927 if( 0==flags || p->op==TK_SELECT_COLUMN
96928 #ifndef SQLITE_OMIT_WINDOWFUNC
96929 || p->pWin
96930 #endif
96931 ){
96932 nSize = EXPR_FULLSIZE;
96933 }else{
96934 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -96951,11 +97280,11 @@
96951 ** string is defined.)
96952 */
96953 static int dupedExprNodeSize(Expr *p, int flags){
96954 int nByte = dupedExprStructSize(p, flags) & 0xfff;
96955 if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
96956 nByte += sqlite3Strlen30(p->u.zToken)+1;
96957 }
96958 return ROUND8(nByte);
96959 }
96960
96961 /*
@@ -97054,26 +97383,28 @@
97054 pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
97055 }
97056 }
97057
97058 /* Fill in pNew->pLeft and pNew->pRight. */
97059 zAlloc += dupedExprNodeSize(p, dupFlags);
97060 if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
97061 if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
97062 pNew->pLeft = p->pLeft ?
97063 exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
97064 pNew->pRight = p->pRight ?
97065 exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
97066 }
97067 }else{
97068 #ifndef SQLITE_OMIT_WINDOWFUNC
97069 if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
97070 pNew->pWin = 0;
97071 }else{
97072 pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
97073 }
97074 #endif /* SQLITE_OMIT_WINDOWFUNC */
 
 
 
 
97075 if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
97076 if( pNew->op==TK_SELECT_COLUMN ){
97077 pNew->pLeft = p->pLeft;
97078 assert( p->iColumn==0 || p->pRight==0 );
97079 assert( p->pRight==0 || p->pRight==p->pLeft );
@@ -97081,13 +97412,10 @@
97081 pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
97082 }
97083 pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
97084 }
97085 }
97086 if( pzBuffer ){
97087 *pzBuffer = zAlloc;
97088 }
97089 }
97090 return pNew;
97091 }
97092
97093 /*
@@ -97878,12 +98206,12 @@
97878 case TK_FLOAT:
97879 case TK_BLOB:
97880 return 0;
97881 case TK_COLUMN:
97882 return ExprHasProperty(p, EP_CanBeNull) ||
97883 p->pTab==0 || /* Reference to column of index on expression */
97884 (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
97885 default:
97886 return 1;
97887 }
97888 }
97889
@@ -97934,10 +98262,18 @@
97934 if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
97935 if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
97936 if( sqlite3StrICmp(z, "OID")==0 ) return 1;
97937 return 0;
97938 }
 
 
 
 
 
 
 
 
97939
97940 /*
97941 ** pX is the RHS of an IN operator. If pX is a SELECT statement
97942 ** that can be simplified to a direct table access, then return
97943 ** a pointer to the SELECT statement. If pX is not a SELECT statement,
@@ -99167,11 +99503,11 @@
99167 ** expresssion. However, make sure the constant has the correct
99168 ** datatype by applying the Affinity of the table column to the
99169 ** constant.
99170 */
99171 int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
99172 int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
99173 if( aff!=SQLITE_AFF_BLOB ){
99174 static const char zAff[] = "B\000C\000D\000E";
99175 assert( SQLITE_AFF_BLOB=='A' );
99176 assert( SQLITE_AFF_TEXT=='B' );
99177 if( iReg!=target ){
@@ -99191,11 +99527,11 @@
99191 /* Coding an expression that is part of an index where column names
99192 ** in the index refer to the table to which the index belongs */
99193 iTab = pParse->iSelfTab - 1;
99194 }
99195 }
99196 return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
99197 pExpr->iColumn, iTab, target,
99198 pExpr->op2);
99199 }
99200 case TK_INTEGER: {
99201 codeInteger(pParse, pExpr, 0, target);
@@ -99405,12 +99741,12 @@
99405 sqlite3 *db = pParse->db; /* The database connection */
99406 u8 enc = ENC(db); /* The text encoding used by this database */
99407 CollSeq *pColl = 0; /* A collating sequence */
99408
99409 #ifndef SQLITE_OMIT_WINDOWFUNC
99410 if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
99411 return pExpr->pWin->regResult;
99412 }
99413 #endif
99414
99415 if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
99416 /* SQL functions can be expensive. So try to move constant functions
@@ -99649,11 +99985,11 @@
99649 **
99650 ** p1==0 -> old.rowid p1==3 -> new.rowid
99651 ** p1==1 -> old.a p1==4 -> new.a
99652 ** p1==2 -> old.b p1==5 -> new.b
99653 */
99654 Table *pTab = pExpr->pTab;
99655 int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
99656
99657 assert( pExpr->iTable==0 || pExpr->iTable==1 );
99658 assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
99659 assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
@@ -99660,11 +99996,11 @@
99660 assert( p1>=0 && p1<(pTab->nCol*2+2) );
99661
99662 sqlite3VdbeAddOp2(v, OP_Param, p1, target);
99663 VdbeComment((v, "r[%d]=%s.%s", target,
99664 (pExpr->iTable ? "new" : "old"),
99665 (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
99666 ));
99667
99668 #ifndef SQLITE_OMIT_FLOATING_POINT
99669 /* If the column has REAL affinity, it may currently be stored as an
99670 ** integer. Use OP_RealAffinity to make sure it is really real.
@@ -100511,10 +100847,24 @@
100511 return 2;
100512 }
100513 if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
100514 if( pA->op==TK_FUNCTION ){
100515 if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100516 }else if( pA->op==TK_COLLATE ){
100517 if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
100518 }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
100519 return 2;
100520 }
@@ -100530,25 +100880,10 @@
100530 if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
100531 if( pA->iColumn!=pB->iColumn ) return 2;
100532 if( pA->iTable!=pB->iTable
100533 && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
100534 }
100535 #ifndef SQLITE_OMIT_WINDOWFUNC
100536 /* Justification for the assert():
100537 ** window functions have p->op==TK_FUNCTION but aggregate functions
100538 ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
100539 ** function and a window function should have failed before reaching
100540 ** this point. And, it is not possible to have a window function and
100541 ** a scalar function with the same name and number of arguments. So
100542 ** if we reach this point, either A and B both window functions or
100543 ** neither are a window functions. */
100544 assert( (pA->pWin==0)==(pB->pWin==0) );
100545
100546 if( pA->pWin!=0 ){
100547 if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
100548 }
100549 #endif
100550 }
100551 return 0;
100552 }
100553
100554 /*
@@ -100685,12 +101020,12 @@
100685 testcase( pExpr->op==TK_NE );
100686 testcase( pExpr->op==TK_LT );
100687 testcase( pExpr->op==TK_LE );
100688 testcase( pExpr->op==TK_GT );
100689 testcase( pExpr->op==TK_GE );
100690 if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
100691 || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
100692 ){
100693 return WRC_Prune;
100694 }
100695 default:
100696 return WRC_Continue;
@@ -100917,11 +101252,11 @@
100917 }
100918 if( (k>=pAggInfo->nColumn)
100919 && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
100920 ){
100921 pCol = &pAggInfo->aCol[k];
100922 pCol->pTab = pExpr->pTab;
100923 pCol->iTable = pExpr->iTable;
100924 pCol->iColumn = pExpr->iColumn;
100925 pCol->iMem = ++pParse->nMem;
100926 pCol->iSorterColumn = -1;
100927 pCol->pExpr = pExpr;
@@ -101800,14 +102135,20 @@
101800 #else
101801 # define renameTokenCheckAll(x,y)
101802 #endif
101803
101804 /*
101805 ** Add a new RenameToken object mapping parse tree element pPtr into
101806 ** token *pToken to the Parse object currently under construction.
101807 **
101808 ** Return a copy of pPtr.
 
 
 
 
 
 
101809 */
101810 SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
101811 RenameToken *pNew;
101812 assert( pPtr || pParse->db->mallocFailed );
101813 renameTokenCheckAll(pParse, pPtr);
@@ -101936,11 +102277,11 @@
101936 && pWalker->pParse->pTriggerTab==p->pTab
101937 ){
101938 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
101939 }else if( pExpr->op==TK_COLUMN
101940 && pExpr->iColumn==p->iCol
101941 && p->pTab==pExpr->pTab
101942 ){
101943 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
101944 }
101945 return WRC_Continue;
101946 }
@@ -102194,13 +102535,18 @@
102194 assert( pNew->pTabSchema );
102195 pParse->pTriggerTab = sqlite3FindTable(db, pNew->table,
102196 db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
102197 );
102198 pParse->eTriggerOp = pNew->op;
 
 
 
 
 
102199
102200 /* Resolve symbols in WHEN clause */
102201 if( pNew->pWhen ){
102202 rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
102203 }
102204
102205 for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
102206 if( pStep->pSelect ){
@@ -102310,19 +102656,12 @@
102310 ** Do a column rename operation on the CREATE statement given in zSql.
102311 ** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
102312 ** into zNew. The name should be quoted if bQuote is true.
102313 **
102314 ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
102315 ** Though accessible to application code, it is not intended for use by
102316 ** applications. The existance of this function, and the way it works,
102317 ** is subject to change without notice.
102318 **
102319 ** If any of the parameters are out-of-bounds, then simply return NULL.
102320 ** An out-of-bounds parameter can only occur when the application calls
102321 ** this function directly. The parameters will always be well-formed when
102322 ** this routine is invoked by the bytecode for a legitimate ALTER TABLE
102323 ** statement.
102324 */
102325 static void renameColumnFunc(
102326 sqlite3_context *context,
102327 int NotUsed,
102328 sqlite3_value **argv
@@ -102474,12 +102813,12 @@
102474 /*
102475 ** Walker expression callback used by "RENAME TABLE".
102476 */
102477 static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
102478 RenameCtx *p = pWalker->u.pRename;
102479 if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
102480 renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
102481 }
102482 return WRC_Continue;
102483 }
102484
102485 /*
@@ -102572,11 +102911,11 @@
102572 sqlite3WalkSelect(&sWalker, pTab->pSelect);
102573 }
102574 }else{
102575 /* Modify any FK definitions to point to the new table. */
102576 #ifndef SQLITE_OMIT_FOREIGN_KEY
102577 if( db->flags & SQLITE_ForeignKeys ){
102578 FKey *pFKey;
102579 for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
102580 if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
102581 renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
102582 }
@@ -102726,13 +103065,13 @@
102726 /*
102727 ** Register built-in functions used to help implement ALTER TABLE
102728 */
102729 SQLITE_PRIVATE void sqlite3AlterFunctions(void){
102730 static FuncDef aAlterTableFuncs[] = {
102731 FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc),
102732 FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc),
102733 FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest),
102734 };
102735 sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
102736 }
102737 #endif /* SQLITE_ALTER_TABLE */
102738
@@ -104777,11 +105116,11 @@
104777 if( pVfs==0 ) return;
104778 pNew = &db->aDb[db->init.iDb];
104779 if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
104780 pNew->pBt = 0;
104781 pNew->pSchema = 0;
104782 rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
104783 }else{
104784 /* This is a real ATTACH
104785 **
104786 ** Check for the following errors:
104787 **
@@ -105457,10 +105796,11 @@
105457 int iSrc; /* Index in pTabList->a[] of table being read */
105458 int iDb; /* The index of the database the expression refers to */
105459 int iCol; /* Index of column in table */
105460
105461 assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
 
105462 if( db->xAuth==0 ) return;
105463 iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
105464 if( iDb<0 ){
105465 /* An attempt to read a column out of a subquery or other
105466 ** temporary table. */
@@ -105513,10 +105853,11 @@
105513 int rc;
105514
105515 /* Don't do any authorization checks if the database is initialising
105516 ** or if the parser is being invoked from within sqlite3_declare_vtab.
105517 */
 
105518 if( db->init.busy || IN_SPECIAL_PARSE ){
105519 return SQLITE_OK;
105520 }
105521
105522 if( db->xAuth==0 ){
@@ -105936,21 +106277,19 @@
105936
105937 p = sqlite3FindTable(db, zName, zDbase);
105938 if( p==0 ){
105939 const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
105940 #ifndef SQLITE_OMIT_VIRTUALTABLE
105941 if( sqlite3FindDbName(db, zDbase)<1 ){
105942 /* If zName is the not the name of a table in the schema created using
105943 ** CREATE, then check to see if it is the name of an virtual table that
105944 ** can be an eponymous virtual table. */
105945 Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
105946 if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
105947 pMod = sqlite3PragmaVtabRegister(db, zName);
105948 }
105949 if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
105950 return pMod->pEpoTab;
105951 }
105952 }
105953 #endif
105954 if( (flags & LOCATE_NOERR)==0 ){
105955 if( zDbase ){
105956 sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
@@ -106126,21 +106465,26 @@
106126 ** "main" and "temp") for a single database connection.
106127 */
106128 SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
106129 int i;
106130 sqlite3BtreeEnterAll(db);
106131 assert( db->nSchemaLock==0 );
106132 for(i=0; i<db->nDb; i++){
106133 Db *pDb = &db->aDb[i];
106134 if( pDb->pSchema ){
106135 sqlite3SchemaClear(pDb->pSchema);
 
 
 
 
106136 }
106137 }
106138 db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
106139 sqlite3VtabUnlockList(db);
106140 sqlite3BtreeLeaveAll(db);
106141 sqlite3CollapseDatabaseArray(db);
 
 
106142 }
106143
106144 /*
106145 ** This routine is called when a commit occurs.
106146 */
@@ -106213,10 +106557,16 @@
106213 /* Delete any foreign keys attached to this table. */
106214 sqlite3FkDelete(db, pTable);
106215
106216 /* Delete the Table structure itself.
106217 */
 
 
 
 
 
 
106218 sqlite3DeleteColumnNames(db, pTable);
106219 sqlite3DbFree(db, pTable->zName);
106220 sqlite3DbFree(db, pTable->zColAff);
106221 sqlite3SelectDelete(db, pTable->pSelect);
106222 sqlite3ExprListDelete(db, pTable->pCheck);
@@ -106370,10 +106720,24 @@
106370 iDb = db->init.iDb;
106371 *pUnqual = pName1;
106372 }
106373 return iDb;
106374 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106375
106376 /*
106377 ** This routine is used to check if the UTF-8 string zName is a legal
106378 ** unqualified name for a new schema object (table, index, view or
106379 ** trigger). All names are legal except those that begin with the string
@@ -106380,11 +106744,11 @@
106380 ** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
106381 ** is reserved for internal use.
106382 */
106383 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
106384 if( !pParse->db->init.busy && pParse->nested==0
106385 && (pParse->db->flags & SQLITE_WriteSchema)==0
106386 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
106387 sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
106388 return SQLITE_ERROR;
106389 }
106390 return SQLITE_OK;
@@ -107456,10 +107820,40 @@
107456 pPk->nColumn = pTab->nCol;
107457 }
107458 recomputeColumnsNotIndexed(pPk);
107459 }
107460
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107461 /*
107462 ** This routine is called to report the final ")" that terminates
107463 ** a CREATE TABLE statement.
107464 **
107465 ** The table structure that other action routines have been building
@@ -107494,10 +107888,14 @@
107494 return;
107495 }
107496 assert( !db->mallocFailed );
107497 p = pParse->pNewTable;
107498 if( p==0 ) return;
 
 
 
 
107499
107500 /* If the db->init.busy is 1 it means we are reading the SQL off the
107501 ** "sqlite_master" or "sqlite_temp_master" table on the disk.
107502 ** So do not write to the disk again. Extract the root page number
107503 ** for the table from the db->init.newTnum field. (The page number
@@ -108002,11 +108400,11 @@
108002 ** erasing iTable (this can happen with an auto-vacuum database).
108003 */
108004 static void destroyRootPage(Parse *pParse, int iTable, int iDb){
108005 Vdbe *v = sqlite3GetVdbe(pParse);
108006 int r1 = sqlite3GetTempReg(pParse);
108007 assert( iTable>1 );
108008 sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
108009 sqlite3MayAbort(pParse);
108010 #ifndef SQLITE_OMIT_AUTOVACUUM
108011 /* OP_Destroy stores an in integer r1. If this integer
108012 ** is non-zero, then it is the root page number of a table moved to
@@ -110457,10 +110855,25 @@
110457 return p;
110458 }
110459 }
110460 return 0;
110461 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110462
110463 /*
110464 ** Insert a new FuncDef into a FuncDefHash hash table.
110465 */
110466 SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
@@ -110470,11 +110883,11 @@
110470 int i;
110471 for(i=0; i<nDef; i++){
110472 FuncDef *pOther;
110473 const char *zName = aDef[i].zName;
110474 int nName = sqlite3Strlen30(zName);
110475 int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
110476 assert( zName[0]>='a' && zName[0]<='z' );
110477 pOther = functionSearch(h, zName);
110478 if( pOther ){
110479 assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
110480 aDef[i].pNext = pOther->pNext;
@@ -110549,11 +110962,11 @@
110549 ** new function. But the FuncDefs for built-in functions are read-only.
110550 ** So we must not search for built-ins when creating a new function.
110551 */
110552 if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
110553 bestScore = 0;
110554 h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
110555 p = functionSearch(h, zName);
110556 while( p ){
110557 int score = matchQuality(p, nArg, enc);
110558 if( score>bestScore ){
110559 pBest = p;
@@ -110696,37 +111109,54 @@
110696 if( sqlite3IndexedByLookup(pParse, pItem) ){
110697 pTab = 0;
110698 }
110699 return pTab;
110700 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110701
110702 /*
110703 ** Check to make sure the given table is writable. If it is not
110704 ** writable, generate an error message and return 1. If it is
110705 ** writable return 0;
110706 */
110707 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
110708 /* A table is not writable under the following circumstances:
110709 **
110710 ** 1) It is a virtual table and no implementation of the xUpdate method
110711 ** has been provided, or
110712 ** 2) It is a system table (i.e. sqlite_master), this call is not
110713 ** part of a nested parse and writable_schema pragma has not
110714 ** been specified.
110715 **
110716 ** In either case leave an error message in pParse and return non-zero.
110717 */
110718 if( ( IsVirtual(pTab)
110719 && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
110720 || ( (pTab->tabFlags & TF_Readonly)!=0
110721 && (pParse->db->flags & SQLITE_WriteSchema)==0
110722 && pParse->nested==0 )
110723 ){
110724 sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
110725 return 1;
110726 }
110727
110728 #ifndef SQLITE_OMIT_VIEW
110729 if( !viewOk && pTab->pSelect ){
110730 sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
110731 return 1;
110732 }
@@ -114126,11 +114556,11 @@
114126 int iCursor, /* The open cursor on the table */
114127 i16 iCol /* The column that is wanted */
114128 ){
114129 Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
114130 if( pExpr ){
114131 pExpr->pTab = pTab;
114132 pExpr->iTable = iCursor;
114133 pExpr->iColumn = iCol;
114134 }
114135 return pExpr;
114136 }
@@ -115202,11 +115632,12 @@
115202 do{
115203 zColAff[i--] = 0;
115204 }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
115205 pTab->zColAff = zColAff;
115206 }
115207 i = sqlite3Strlen30(zColAff);
 
115208 if( i ){
115209 if( iReg ){
115210 sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
115211 }else{
115212 sqlite3VdbeChangeP4(v, -1, zColAff, i);
@@ -116182,18 +116613,19 @@
116182 #ifdef tmask
116183 #undef tmask
116184 #endif
116185
116186 /*
116187 ** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
 
116188 */
116189 #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
116190 #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
116191
116192 /* This is the Walker callback from checkConstraintUnchanged(). Set
116193 ** bit 0x01 of pWalker->eCode if
116194 ** pWalker->eCode to 0 if this expression node references any of the
116195 ** columns that are being modifed by an UPDATE statement.
116196 */
116197 static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
116198 if( pExpr->op==TK_COLUMN ){
116199 assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
@@ -116211,16 +116643,25 @@
116211 /*
116212 ** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The
116213 ** only columns that are modified by the UPDATE are those for which
116214 ** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
116215 **
116216 ** Return true if CHECK constraint pExpr does not use any of the
116217 ** changing columns (or the rowid if it is changing). In other words,
116218 ** return true if this CHECK constraint can be skipped when validating
116219 ** the new row in the UPDATE statement.
 
 
 
 
 
116220 */
116221 static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
 
 
 
 
116222 Walker w;
116223 memset(&w, 0, sizeof(w));
116224 w.eCode = 0;
116225 w.xExprCallback = checkConstraintExprNode;
116226 w.u.aiCol = aiChng;
@@ -116231,11 +116672,11 @@
116231 }
116232 testcase( w.eCode==0 );
116233 testcase( w.eCode==CKCNSTRNT_COLUMN );
116234 testcase( w.eCode==CKCNSTRNT_ROWID );
116235 testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
116236 return !w.eCode;
116237 }
116238
116239 /*
116240 ** Generate code to do constraint checks prior to an INSERT or an UPDATE
116241 ** on table pTab.
@@ -116437,11 +116878,17 @@
116437 pParse->iSelfTab = -(regNewData+1);
116438 onError = overrideError!=OE_Default ? overrideError : OE_Abort;
116439 for(i=0; i<pCheck->nExpr; i++){
116440 int allOk;
116441 Expr *pExpr = pCheck->a[i].pExpr;
116442 if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
 
 
 
 
 
 
116443 allOk = sqlite3VdbeMakeLabel(v);
116444 sqlite3VdbeVerifyAbortable(v, onError);
116445 sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
116446 if( onError==OE_Ignore ){
116447 sqlite3VdbeGoto(v, ignoreDest);
@@ -117938,16 +118385,19 @@
117938 void (*str_appendchar)(sqlite3_str*, int N, char C);
117939 void (*str_reset)(sqlite3_str*);
117940 int (*str_errcode)(sqlite3_str*);
117941 int (*str_length)(sqlite3_str*);
117942 char *(*str_value)(sqlite3_str*);
 
117943 int (*create_window_function)(sqlite3*,const char*,int,int,void*,
117944 void (*xStep)(sqlite3_context*,int,sqlite3_value**),
117945 void (*xFinal)(sqlite3_context*),
117946 void (*xValue)(sqlite3_context*),
117947 void (*xInv)(sqlite3_context*,int,sqlite3_value**),
117948 void(*xDestroy)(void*));
 
 
117949 };
117950
117951 /*
117952 ** This is the function signature used for all extension entry points. It
117953 ** is also defined in the file "loadext.c".
@@ -118231,10 +118681,12 @@
118231 #define sqlite3_str_errcode sqlite3_api->str_errcode
118232 #define sqlite3_str_length sqlite3_api->str_length
118233 #define sqlite3_str_value sqlite3_api->str_value
118234 /* Version 3.25.0 and later */
118235 #define sqlite3_create_window_function sqlite3_api->create_window_function
 
 
118236 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
118237
118238 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
118239 /* This case when the file really is being compiled as a loadable
118240 ** extension */
@@ -118319,10 +118771,11 @@
118319 # define sqlite3_create_module 0
118320 # define sqlite3_create_module_v2 0
118321 # define sqlite3_declare_vtab 0
118322 # define sqlite3_vtab_config 0
118323 # define sqlite3_vtab_on_conflict 0
 
118324 #endif
118325
118326 #ifdef SQLITE_OMIT_SHARED_CACHE
118327 # define sqlite3_enable_shared_cache 0
118328 #endif
@@ -118686,11 +119139,17 @@
118686 sqlite3_str_reset,
118687 sqlite3_str_errcode,
118688 sqlite3_str_length,
118689 sqlite3_str_value,
118690 /* Version 3.25.0 and later */
118691 sqlite3_create_window_function
 
 
 
 
 
 
118692 };
118693
118694 /*
118695 ** Attempt to load an SQLite extension library contained in the file
118696 ** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -119136,14 +119595,13 @@
119136 #define PragTyp_WAL_AUTOCHECKPOINT 38
119137 #define PragTyp_WAL_CHECKPOINT 39
119138 #define PragTyp_ACTIVATE_EXTENSIONS 40
119139 #define PragTyp_HEXKEY 41
119140 #define PragTyp_KEY 42
119141 #define PragTyp_REKEY 43
119142 #define PragTyp_LOCK_STATUS 44
119143 #define PragTyp_PARSER_TRACE 45
119144 #define PragTyp_STATS 46
119145
119146 /* Property flags associated with various pragma. */
119147 #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
119148 #define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
119149 #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
@@ -119156,72 +119614,71 @@
119156 /* Names of columns for pragmas that return multi-column result
119157 ** or that return single-column results where the name of the
119158 ** result column is different from the name of the pragma
119159 */
119160 static const char *const pragCName[] = {
119161 /* 0 */ "cache_size", /* Used by: default_cache_size */
119162 /* 1 */ "cid", /* Used by: table_info */
119163 /* 2 */ "name",
119164 /* 3 */ "type",
119165 /* 4 */ "notnull",
119166 /* 5 */ "dflt_value",
119167 /* 6 */ "pk",
119168 /* 7 */ "tbl", /* Used by: stats */
119169 /* 8 */ "idx",
119170 /* 9 */ "wdth",
119171 /* 10 */ "hght",
119172 /* 11 */ "flgs",
119173 /* 12 */ "seqno", /* Used by: index_info */
119174 /* 13 */ "cid",
119175 /* 14 */ "name",
 
119176 /* 15 */ "seqno", /* Used by: index_xinfo */
119177 /* 16 */ "cid",
119178 /* 17 */ "name",
119179 /* 18 */ "desc",
119180 /* 19 */ "coll",
119181 /* 20 */ "key",
119182 /* 21 */ "seq", /* Used by: index_list */
119183 /* 22 */ "name",
119184 /* 23 */ "unique",
119185 /* 24 */ "origin",
119186 /* 25 */ "partial",
119187 /* 26 */ "seq", /* Used by: database_list */
119188 /* 27 */ "name",
119189 /* 28 */ "file",
119190 /* 29 */ "name", /* Used by: function_list */
119191 /* 30 */ "builtin",
119192 /* 31 */ "name", /* Used by: module_list pragma_list */
119193 /* 32 */ "seq", /* Used by: collation_list */
119194 /* 33 */ "name",
119195 /* 34 */ "id", /* Used by: foreign_key_list */
119196 /* 35 */ "seq",
119197 /* 36 */ "table",
119198 /* 37 */ "from",
119199 /* 38 */ "to",
119200 /* 39 */ "on_update",
119201 /* 40 */ "on_delete",
119202 /* 41 */ "match",
119203 /* 42 */ "table", /* Used by: foreign_key_check */
119204 /* 43 */ "rowid",
119205 /* 44 */ "parent",
119206 /* 45 */ "fkid",
119207 /* 46 */ "busy", /* Used by: wal_checkpoint */
119208 /* 47 */ "log",
119209 /* 48 */ "checkpointed",
119210 /* 49 */ "timeout", /* Used by: busy_timeout */
119211 /* 50 */ "database", /* Used by: lock_status */
119212 /* 51 */ "status",
119213 };
119214
119215 /* Definitions of all built-in pragmas */
119216 typedef struct PragmaName {
119217 const char *const zName; /* Name of pragma */
119218 u8 ePragTyp; /* PragTyp_XXX value */
119219 u8 mPragFlg; /* Zero or more PragFlg_XXX values */
119220 u8 iPragCName; /* Start of column names in pragCName[] */
119221 u8 nPragCName; /* Num of col names. 0 means use pragma name */
119222 u32 iArg; /* Extra argument */
119223 } PragmaName;
119224 static const PragmaName aPragmaName[] = {
119225 #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
119226 {/* zName: */ "activate_extensions",
119227 /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
@@ -119253,11 +119710,11 @@
119253 #endif
119254 #endif
119255 {/* zName: */ "busy_timeout",
119256 /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
119257 /* ePragFlg: */ PragFlg_Result0,
119258 /* ColNames: */ 49, 1,
119259 /* iArg: */ 0 },
119260 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119261 {/* zName: */ "cache_size",
119262 /* ePragTyp: */ PragTyp_CACHE_SIZE,
119263 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
@@ -119290,11 +119747,11 @@
119290 #endif
119291 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119292 {/* zName: */ "collation_list",
119293 /* ePragTyp: */ PragTyp_COLLATION_LIST,
119294 /* ePragFlg: */ PragFlg_Result0,
119295 /* ColNames: */ 32, 2,
119296 /* iArg: */ 0 },
119297 #endif
119298 #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
119299 {/* zName: */ "compile_options",
119300 /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
@@ -119325,18 +119782,18 @@
119325 #endif
119326 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119327 {/* zName: */ "database_list",
119328 /* ePragTyp: */ PragTyp_DATABASE_LIST,
119329 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
119330 /* ColNames: */ 26, 3,
119331 /* iArg: */ 0 },
119332 #endif
119333 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
119334 {/* zName: */ "default_cache_size",
119335 /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
119336 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
119337 /* ColNames: */ 0, 1,
119338 /* iArg: */ 0 },
119339 #endif
119340 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119341 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119342 {/* zName: */ "defer_foreign_keys",
@@ -119362,18 +119819,18 @@
119362 #endif
119363 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119364 {/* zName: */ "foreign_key_check",
119365 /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
119366 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
119367 /* ColNames: */ 42, 4,
119368 /* iArg: */ 0 },
119369 #endif
119370 #if !defined(SQLITE_OMIT_FOREIGN_KEY)
119371 {/* zName: */ "foreign_key_list",
119372 /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
119373 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119374 /* ColNames: */ 34, 8,
119375 /* iArg: */ 0 },
119376 #endif
119377 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119378 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119379 {/* zName: */ "foreign_keys",
@@ -119405,25 +119862,25 @@
119405 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119406 #if defined(SQLITE_INTROSPECTION_PRAGMAS)
119407 {/* zName: */ "function_list",
119408 /* ePragTyp: */ PragTyp_FUNCTION_LIST,
119409 /* ePragFlg: */ PragFlg_Result0,
119410 /* ColNames: */ 29, 2,
119411 /* iArg: */ 0 },
119412 #endif
119413 #endif
119414 #if defined(SQLITE_HAS_CODEC)
119415 {/* zName: */ "hexkey",
119416 /* ePragTyp: */ PragTyp_HEXKEY,
119417 /* ePragFlg: */ 0,
119418 /* ColNames: */ 0, 0,
119419 /* iArg: */ 0 },
119420 {/* zName: */ "hexrekey",
119421 /* ePragTyp: */ PragTyp_HEXKEY,
119422 /* ePragFlg: */ 0,
119423 /* ColNames: */ 0, 0,
119424 /* iArg: */ 0 },
119425 #endif
119426 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119427 #if !defined(SQLITE_OMIT_CHECK)
119428 {/* zName: */ "ignore_check_constraints",
119429 /* ePragTyp: */ PragTyp_FLAG,
@@ -119441,16 +119898,16 @@
119441 #endif
119442 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119443 {/* zName: */ "index_info",
119444 /* ePragTyp: */ PragTyp_INDEX_INFO,
119445 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119446 /* ColNames: */ 12, 3,
119447 /* iArg: */ 0 },
119448 {/* zName: */ "index_list",
119449 /* ePragTyp: */ PragTyp_INDEX_LIST,
119450 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119451 /* ColNames: */ 21, 5,
119452 /* iArg: */ 0 },
119453 {/* zName: */ "index_xinfo",
119454 /* ePragTyp: */ PragTyp_INDEX_INFO,
119455 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119456 /* ColNames: */ 15, 6,
@@ -119503,11 +119960,11 @@
119503 #endif
119504 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
119505 {/* zName: */ "lock_status",
119506 /* ePragTyp: */ PragTyp_LOCK_STATUS,
119507 /* ePragFlg: */ PragFlg_Result0,
119508 /* ColNames: */ 50, 2,
119509 /* iArg: */ 0 },
119510 #endif
119511 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119512 {/* zName: */ "locking_mode",
119513 /* ePragTyp: */ PragTyp_LOCKING_MODE,
@@ -119529,11 +119986,11 @@
119529 #if !defined(SQLITE_OMIT_VIRTUALTABLE)
119530 #if defined(SQLITE_INTROSPECTION_PRAGMAS)
119531 {/* zName: */ "module_list",
119532 /* ePragTyp: */ PragTyp_MODULE_LIST,
119533 /* ePragFlg: */ PragFlg_Result0,
119534 /* ColNames: */ 31, 1,
119535 /* iArg: */ 0 },
119536 #endif
119537 #endif
119538 #endif
119539 {/* zName: */ "optimize",
@@ -119562,11 +120019,11 @@
119562 #endif
119563 #if defined(SQLITE_INTROSPECTION_PRAGMAS)
119564 {/* zName: */ "pragma_list",
119565 /* ePragTyp: */ PragTyp_PRAGMA_LIST,
119566 /* ePragFlg: */ PragFlg_Result0,
119567 /* ColNames: */ 31, 1,
119568 /* iArg: */ 0 },
119569 #endif
119570 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119571 {/* zName: */ "query_only",
119572 /* ePragTyp: */ PragTyp_FLAG,
@@ -119593,14 +120050,14 @@
119593 /* ColNames: */ 0, 0,
119594 /* iArg: */ SQLITE_RecTriggers },
119595 #endif
119596 #if defined(SQLITE_HAS_CODEC)
119597 {/* zName: */ "rekey",
119598 /* ePragTyp: */ PragTyp_REKEY,
119599 /* ePragFlg: */ 0,
119600 /* ColNames: */ 0, 0,
119601 /* iArg: */ 0 },
119602 #endif
119603 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119604 {/* zName: */ "reverse_unordered_selects",
119605 /* ePragTyp: */ PragTyp_FLAG,
119606 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119649,11 +120106,11 @@
119649 #endif
119650 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
119651 {/* zName: */ "stats",
119652 /* ePragTyp: */ PragTyp_STATS,
119653 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
119654 /* ColNames: */ 7, 5,
119655 /* iArg: */ 0 },
119656 #endif
119657 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119658 {/* zName: */ "synchronous",
119659 /* ePragTyp: */ PragTyp_SYNCHRONOUS,
@@ -119663,12 +120120,17 @@
119663 #endif
119664 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119665 {/* zName: */ "table_info",
119666 /* ePragTyp: */ PragTyp_TABLE_INFO,
119667 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119668 /* ColNames: */ 1, 6,
119669 /* iArg: */ 0 },
 
 
 
 
 
119670 #endif
119671 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119672 {/* zName: */ "temp_store",
119673 /* ePragTyp: */ PragTyp_TEMP_STORE,
119674 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119677,10 +120139,22 @@
119677 {/* zName: */ "temp_store_directory",
119678 /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
119679 /* ePragFlg: */ PragFlg_NoColumns1,
119680 /* ColNames: */ 0, 0,
119681 /* iArg: */ 0 },
 
 
 
 
 
 
 
 
 
 
 
 
119682 #endif
119683 {/* zName: */ "threads",
119684 /* ePragTyp: */ PragTyp_THREADS,
119685 /* ePragFlg: */ PragFlg_Result0,
119686 /* ColNames: */ 0, 0,
@@ -119728,22 +120202,22 @@
119728 /* ColNames: */ 0, 0,
119729 /* iArg: */ 0 },
119730 {/* zName: */ "wal_checkpoint",
119731 /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
119732 /* ePragFlg: */ PragFlg_NeedSchema,
119733 /* ColNames: */ 46, 3,
119734 /* iArg: */ 0 },
119735 #endif
119736 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119737 {/* zName: */ "writable_schema",
119738 /* ePragTyp: */ PragTyp_FLAG,
119739 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
119740 /* ColNames: */ 0, 0,
119741 /* iArg: */ SQLITE_WriteSchema },
119742 #endif
119743 };
119744 /* Number of pragmas: 61 on by default, 78 total. */
119745
119746 /************** End of pragma.h **********************************************/
119747 /************** Continuing where we left off in pragma.c *********************/
119748
119749 /*
@@ -120751,11 +121225,11 @@
120751 case PragTyp_FLAG: {
120752 if( zRight==0 ){
120753 setPragmaResultColumnNames(v, pPragma);
120754 returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
120755 }else{
120756 int mask = pPragma->iArg; /* Mask of bits to set or clear. */
120757 if( db->autoCommit==0 ){
120758 /* Foreign key support may not be enabled or disabled while not
120759 ** in auto-commit mode. */
120760 mask &= ~(SQLITE_ForeignKeys);
120761 }
@@ -120800,19 +121274,21 @@
120800 */
120801 case PragTyp_TABLE_INFO: if( zRight ){
120802 Table *pTab;
120803 pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
120804 if( pTab ){
 
120805 int i, k;
120806 int nHidden = 0;
120807 Column *pCol;
120808 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
120809 pParse->nMem = 6;
120810 sqlite3CodeVerifySchema(pParse, iDb);
120811 sqlite3ViewGetColumnNames(pParse, pTab);
120812 for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
120813 if( IsHiddenColumn(pCol) ){
 
120814 nHidden++;
120815 continue;
120816 }
120817 if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
120818 k = 0;
@@ -120820,17 +121296,18 @@
120820 k = 1;
120821 }else{
120822 for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
120823 }
120824 assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
120825 sqlite3VdbeMultiLoad(v, 1, "issisi",
120826 i-nHidden,
120827 pCol->zName,
120828 sqlite3ColumnType(pCol,""),
120829 pCol->notNull ? 1 : 0,
120830 pCol->pDflt ? pCol->pDflt->u.zToken : 0,
120831 k);
 
120832 }
120833 }
120834 }
120835 break;
120836
@@ -120864,10 +121341,11 @@
120864 case PragTyp_INDEX_INFO: if( zRight ){
120865 Index *pIdx;
120866 Table *pTab;
120867 pIdx = sqlite3FindIndex(db, zRight, zDb);
120868 if( pIdx ){
 
120869 int i;
120870 int mx;
120871 if( pPragma->iArg ){
120872 /* PRAGMA index_xinfo (newer version with more rows and columns) */
120873 mx = pIdx->nColumn;
@@ -120876,11 +121354,11 @@
120876 /* PRAGMA index_info (legacy version) */
120877 mx = pIdx->nKeyCol;
120878 pParse->nMem = 3;
120879 }
120880 pTab = pIdx->pTable;
120881 sqlite3CodeVerifySchema(pParse, iDb);
120882 assert( pParse->nMem<=pPragma->nPragCName );
120883 for(i=0; i<mx; i++){
120884 i16 cnum = pIdx->aiColumn[i];
120885 sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum,
120886 cnum<0 ? 0 : pTab->aCol[cnum].zName);
@@ -120900,12 +121378,13 @@
120900 Index *pIdx;
120901 Table *pTab;
120902 int i;
120903 pTab = sqlite3FindTable(db, zRight, zDb);
120904 if( pTab ){
 
120905 pParse->nMem = 5;
120906 sqlite3CodeVerifySchema(pParse, iDb);
120907 for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
120908 const char *azOrigin[] = { "c", "u", "pk" };
120909 sqlite3VdbeMultiLoad(v, 1, "isisi",
120910 i,
120911 pIdx->zName,
@@ -120948,10 +121427,11 @@
120948 HashElem *j;
120949 FuncDef *p;
120950 pParse->nMem = 2;
120951 for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
120952 for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
 
120953 sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
120954 }
120955 }
120956 for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
120957 p = (FuncDef*)sqliteHashData(j);
@@ -120989,13 +121469,14 @@
120989 Table *pTab;
120990 pTab = sqlite3FindTable(db, zRight, zDb);
120991 if( pTab ){
120992 pFK = pTab->pFKey;
120993 if( pFK ){
 
120994 int i = 0;
120995 pParse->nMem = 8;
120996 sqlite3CodeVerifySchema(pParse, iDb);
120997 while(pFK){
120998 int j;
120999 for(j=0; j<pFK->nCol; j++){
121000 sqlite3VdbeMultiLoad(v, 1, "iissssss",
121001 i,
@@ -121036,36 +121517,38 @@
121036
121037 regResult = pParse->nMem+1;
121038 pParse->nMem += 4;
121039 regKey = ++pParse->nMem;
121040 regRow = ++pParse->nMem;
121041 sqlite3CodeVerifySchema(pParse, iDb);
121042 k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
121043 while( k ){
 
121044 if( zRight ){
121045 pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
121046 k = 0;
121047 }else{
121048 pTab = (Table*)sqliteHashData(k);
121049 k = sqliteHashNext(k);
121050 }
121051 if( pTab==0 || pTab->pFKey==0 ) continue;
121052 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
 
 
121053 if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
121054 sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
121055 sqlite3VdbeLoadString(v, regResult, pTab->zName);
121056 for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
121057 pParent = sqlite3FindTable(db, pFK->zTo, zDb);
121058 if( pParent==0 ) continue;
121059 pIdx = 0;
121060 sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
121061 x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
121062 if( x==0 ){
121063 if( pIdx==0 ){
121064 sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
121065 }else{
121066 sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
121067 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
121068 }
121069 }else{
121070 k = 0;
121071 break;
@@ -121830,16 +122313,28 @@
121830 break;
121831 }
121832 #endif
121833
121834 #ifdef SQLITE_HAS_CODEC
 
 
 
 
 
 
 
 
 
121835 case PragTyp_KEY: {
121836 if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
121837 break;
121838 }
121839 case PragTyp_REKEY: {
121840 if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
 
 
 
121841 break;
121842 }
121843 case PragTyp_HEXKEY: {
121844 if( zRight ){
121845 u8 iByte;
@@ -121847,11 +122342,11 @@
121847 char zKey[40];
121848 for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
121849 iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
121850 if( (i&1)!=0 ) zKey[i/2] = iByte;
121851 }
121852 if( (zLeft[3] & 0xf)==0xb ){
121853 sqlite3_key_v2(db, zDb, zKey, i/2);
121854 }else{
121855 sqlite3_rekey_v2(db, zDb, zKey, i/2);
121856 }
121857 }
@@ -122177,11 +122672,12 @@
122177 0, /* xRollback - rollback transaction */
122178 0, /* xFindFunction - function overloading */
122179 0, /* xRename - rename the table */
122180 0, /* xSavepoint */
122181 0, /* xRelease */
122182 0 /* xRollbackTo */
 
122183 };
122184
122185 /*
122186 ** Check to see if zTabName is really the name of a pragma. If it is,
122187 ** then register an eponymous virtual table for that pragma and return
@@ -122530,12 +123026,12 @@
122530 }
122531 if( db->mallocFailed ){
122532 rc = SQLITE_NOMEM_BKPT;
122533 sqlite3ResetAllSchemasOfConnection(db);
122534 }
122535 if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
122536 /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
122537 ** the schema loaded, even if errors occurred. In this situation the
122538 ** current sqlite3_prepare() operation will fail, but the following one
122539 ** will attempt to compile the supplied statement against whatever subset
122540 ** of the schema was loaded before the error occurred. The primary
122541 ** purpose of this is to allow access to the sqlite_master table
@@ -122912,10 +123408,298 @@
122912 assert( (rc&db->errMask)==rc );
122913 sqlite3_mutex_leave(db->mutex);
122914 return rc;
122915 }
122916
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122917 /*
122918 ** Rerun the compilation of a statement after a schema change.
122919 **
122920 ** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
122921 ** if the statement cannot be recompiled because another connection has
@@ -123924,11 +124708,11 @@
123924 ExprList *pExtra = 0;
123925 for(i=0; i<pEList->nExpr; i++){
123926 struct ExprList_item *pItem = &pEList->a[i];
123927 if( pItem->u.x.iOrderByCol==0 ){
123928 Expr *pExpr = pItem->pExpr;
123929 Table *pTab = pExpr->pTab;
123930 if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
123931 && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
123932 ){
123933 int j;
123934 for(j=0; j<nDefer; j++){
@@ -123947,16 +124731,16 @@
123947 }
123948 for(k=0; k<nKey; k++){
123949 Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
123950 if( pNew ){
123951 pNew->iTable = pExpr->iTable;
123952 pNew->pTab = pExpr->pTab;
123953 pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
123954 pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
123955 }
123956 }
123957 pSort->aDefer[nDefer].pTab = pExpr->pTab;
123958 pSort->aDefer[nDefer].iCsr = pExpr->iTable;
123959 pSort->aDefer[nDefer].nKey = nKey;
123960 nDefer++;
123961 }
123962 }
@@ -124801,11 +125585,11 @@
124801 ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
124802 ** branch below. */
124803 break;
124804 }
124805
124806 assert( pTab && pExpr->pTab==pTab );
124807 if( pS ){
124808 /* The "table" is actually a sub-select or a view in the FROM clause
124809 ** of the SELECT statement. Return the declaration type and origin
124810 ** data for the result-set column of the sub-select.
124811 */
@@ -124986,19 +125770,19 @@
124986 for(i=0; i<pEList->nExpr; i++){
124987 Expr *p = pEList->a[i].pExpr;
124988
124989 assert( p!=0 );
124990 assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
124991 assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
124992 if( pEList->a[i].zName ){
124993 /* An AS clause always takes first priority */
124994 char *zName = pEList->a[i].zName;
124995 sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
124996 }else if( srcName && p->op==TK_COLUMN ){
124997 char *zCol;
124998 int iCol = p->iColumn;
124999 pTab = p->pTab;
125000 assert( pTab!=0 );
125001 if( iCol<0 ) iCol = pTab->iPKey;
125002 assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
125003 if( iCol<0 ){
125004 zCol = "rowid";
@@ -125085,11 +125869,11 @@
125085 }
125086 assert( pColExpr->op!=TK_AGG_COLUMN );
125087 if( pColExpr->op==TK_COLUMN ){
125088 /* For columns use the column name name */
125089 int iCol = pColExpr->iColumn;
125090 Table *pTab = pColExpr->pTab;
125091 assert( pTab!=0 );
125092 if( iCol<0 ) iCol = pTab->iPKey;
125093 zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
125094 }else if( pColExpr->op==TK_ID ){
125095 assert( !ExprHasProperty(pColExpr, EP_IntValue) );
@@ -125438,10 +126222,17 @@
125438 int i; /* Loop counter */
125439 int rc; /* Result code */
125440 ExprList *pOrderBy; /* The ORDER BY clause */
125441 Expr *pLimit; /* Saved LIMIT and OFFSET */
125442 int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
 
 
 
 
 
 
 
125443
125444 /* Obtain authorization to do a recursive query */
125445 if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
125446
125447 /* Process the LIMIT and OFFSET clauses, if they exist */
@@ -127188,11 +127979,11 @@
127188 return 1;
127189 }
127190 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
127191
127192 /*
127193 ** A structure to keep track of all of the column values that fixed to
127194 ** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
127195 */
127196 typedef struct WhereConst WhereConst;
127197 struct WhereConst {
127198 Parse *pParse; /* Parsing context */
@@ -127200,17 +127991,32 @@
127200 int nChng; /* Number of times a constant is propagated */
127201 Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
127202 };
127203
127204 /*
127205 ** Add a new entry to the pConst object
 
127206 */
127207 static void constInsert(
127208 WhereConst *pConst,
127209 Expr *pColumn,
127210 Expr *pValue
127211 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127212
127213 pConst->nConst++;
127214 pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
127215 pConst->nConst*2*sizeof(Expr*));
127216 if( pConst->apExpr==0 ){
@@ -131187,10 +131993,61 @@
131187 if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
131188 sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
131189 }
131190 #endif
131191 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131192
131193 /*
131194 ** Process an UPDATE statement.
131195 **
131196 ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
@@ -131411,23 +132268,22 @@
131411 hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
131412
131413 /* There is one entry in the aRegIdx[] array for each index on the table
131414 ** being updated. Fill in aRegIdx[] with a register number that will hold
131415 ** the key for accessing each index.
131416 **
131417 ** FIXME: Be smarter about omitting indexes that use expressions.
131418 */
131419 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
131420 int reg;
131421 if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
 
 
131422 reg = ++pParse->nMem;
131423 pParse->nMem += pIdx->nColumn;
131424 }else{
131425 reg = 0;
131426 for(i=0; i<pIdx->nKeyCol; i++){
131427 i16 iIdxCol = pIdx->aiColumn[i];
131428 if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
131429 reg = ++pParse->nMem;
131430 pParse->nMem += pIdx->nColumn;
131431 if( (onError==OE_Replace)
131432 || (onError==OE_Default && pIdx->onError==OE_Replace)
131433 ){
@@ -131972,11 +132828,11 @@
131972 for(i=0; i<pTab->nCol; i++){
131973 if( aXRef[i]>=0 ){
131974 sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
131975 }else{
131976 sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
131977 sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
131978 }
131979 }
131980 if( HasRowid(pTab) ){
131981 sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
131982 if( pRowid ){
@@ -132473,11 +133329,12 @@
132473 saved_nChange = db->nChange;
132474 saved_nTotalChange = db->nTotalChange;
132475 saved_mTrace = db->mTrace;
132476 db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
132477 db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
132478 db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
 
132479 db->mTrace = 0;
132480
132481 zDbMain = db->aDb[iDb].zDbSName;
132482 pMain = db->aDb[iDb].pBt;
132483 isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
@@ -133015,22 +133872,19 @@
133015 Token *pName1, /* Name of new table, or database name */
133016 Token *pName2, /* Name of new table or NULL */
133017 Token *pModuleName, /* Name of the module for the virtual table */
133018 int ifNotExists /* No error if the table already exists */
133019 ){
133020 int iDb; /* The database the table is being created in */
133021 Table *pTable; /* The new virtual table */
133022 sqlite3 *db; /* Database connection */
133023
133024 sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
133025 pTable = pParse->pNewTable;
133026 if( pTable==0 ) return;
133027 assert( 0==pTable->pIndex );
133028
133029 db = pParse->db;
133030 iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
133031 assert( iDb>=0 );
133032
133033 assert( pTable->nModuleArg==0 );
133034 addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
133035 addModuleArgument(db, pTable, 0);
133036 addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
@@ -133046,10 +133900,12 @@
133046 ** The first invocation, to obtain permission to INSERT a row into the
133047 ** sqlite_master table, has already been made by sqlite3StartTable().
133048 ** The second call, to obtain permission to create the table, is made now.
133049 */
133050 if( pTable->azModuleArg ){
 
 
133051 sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
133052 pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
133053 }
133054 #endif
133055 }
@@ -133740,11 +134596,11 @@
133740 int rc = 0;
133741
133742 /* Check to see the left operand is a column in a virtual table */
133743 if( NEVER(pExpr==0) ) return pDef;
133744 if( pExpr->op!=TK_COLUMN ) return pDef;
133745 pTab = pExpr->pTab;
133746 if( pTab==0 ) return pDef;
133747 if( !IsVirtual(pTab) ) return pDef;
133748 pVtab = sqlite3GetVTable(db, pTab)->pVtab;
133749 assert( pVtab!=0 );
133750 assert( pVtab->pModule!=0 );
@@ -134360,15 +135216,36 @@
134360 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
134361 UnpackedRecord *pRec; /* Probe for stat4 (if required) */
134362 int nRecValid; /* Number of valid fields currently in pRec */
134363 #endif
134364 unsigned int bldFlags; /* SQLITE_BLDF_* flags */
 
134365 };
134366
134367 /* Allowed values for WhereLoopBuider.bldFlags */
134368 #define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
134369 #define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134370
134371 /*
134372 ** The WHERE clause processing routine has two halves. The
134373 ** first part does the start of the WHERE loop and the second
134374 ** half does the tail of the WHERE loop. An instance of
@@ -134927,11 +135804,11 @@
134927 Select *pSelect; /* Pointer to the SELECT on the RHS */
134928
134929 for(i=iEq; i<pLoop->nLTerm; i++){
134930 if( pLoop->aLTerm[i]->pExpr==pX ){
134931 int iField = pLoop->aLTerm[i]->iField - 1;
134932 assert( pOrigRhs->a[iField].pExpr!=0 );
134933 pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
134934 pOrigRhs->a[iField].pExpr = 0;
134935 assert( pOrigLhs->a[iField].pExpr!=0 );
134936 pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
134937 pOrigLhs->a[iField].pExpr = 0;
@@ -135619,11 +136496,11 @@
135619 IdxExprTrans *pX = p->u.pIdxTrans;
135620 if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
135621 pExpr->op = TK_COLUMN;
135622 pExpr->iTable = pX->iIdxCur;
135623 pExpr->iColumn = pX->iIdxCol;
135624 pExpr->pTab = 0;
135625 return WRC_Prune;
135626 }else{
135627 return WRC_Continue;
135628 }
135629 }
@@ -137019,11 +137896,11 @@
137019 || zNew[0]=='-'
137020 || (zNew[0]+1=='0' && iTo==1)
137021 ){
137022 if( pLeft->op!=TK_COLUMN
137023 || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
137024 || IsVirtual(pLeft->pTab) /* Value might be numeric */
137025 ){
137026 sqlite3ExprDelete(db, pPrefix);
137027 sqlite3ValueFree(pVal);
137028 return 0;
137029 }
@@ -137120,11 +137997,11 @@
137120 **
137121 ** vtab_column MATCH expression
137122 ** MATCH(expression,vtab_column)
137123 */
137124 pCol = pList->a[1].pExpr;
137125 if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
137126 for(i=0; i<ArraySize(aOp); i++){
137127 if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
137128 *peOp2 = aOp[i].eOp2;
137129 *ppRight = pList->a[0].pExpr;
137130 *ppLeft = pCol;
@@ -137142,16 +138019,16 @@
137142 ** Historically, xFindFunction expected to see lower-case function
137143 ** names. But for this use case, xFindFunction is expected to deal
137144 ** with function names in an arbitrary case.
137145 */
137146 pCol = pList->a[0].pExpr;
137147 if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
137148 sqlite3_vtab *pVtab;
137149 sqlite3_module *pMod;
137150 void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
137151 void *pNotUsed;
137152 pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
137153 assert( pVtab!=0 );
137154 assert( pVtab->pModule!=0 );
137155 pMod = (sqlite3_module *)pVtab->pModule;
137156 if( pMod->xFindFunction!=0 ){
137157 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
@@ -137165,14 +138042,14 @@
137165 }
137166 }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
137167 int res = 0;
137168 Expr *pLeft = pExpr->pLeft;
137169 Expr *pRight = pExpr->pRight;
137170 if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
137171 res++;
137172 }
137173 if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
137174 res++;
137175 SWAP(Expr*, pLeft, pRight);
137176 }
137177 *ppLeft = pLeft;
137178 *ppRight = pRight;
@@ -138120,10 +138997,11 @@
138120 ** Note that the virtual term must be tagged with TERM_VNULL.
138121 */
138122 if( pExpr->op==TK_NOTNULL
138123 && pExpr->pLeft->op==TK_COLUMN
138124 && pExpr->pLeft->iColumn>=0
 
138125 && OptimizationEnabled(db, SQLITE_Stat34)
138126 ){
138127 Expr *pNewExpr;
138128 Expr *pLeft = pExpr->pLeft;
138129 int idxNew;
@@ -138311,10 +139189,11 @@
138311 pTab = pItem->pTab;
138312 assert( pTab!=0 );
138313 pArgs = pItem->u1.pFuncArg;
138314 if( pArgs==0 ) return;
138315 for(j=k=0; j<pArgs->nExpr; j++){
 
138316 while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
138317 if( k>=pTab->nCol ){
138318 sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
138319 pTab->zName, j);
138320 return;
@@ -138321,13 +139200,14 @@
138321 }
138322 pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
138323 if( pColRef==0 ) return;
138324 pColRef->iTable = pItem->iCursor;
138325 pColRef->iColumn = k++;
138326 pColRef->pTab = pTab;
138327 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
138328 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
 
138329 whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
138330 }
138331 }
138332
138333 /************** End of whereexpr.c *******************************************/
@@ -139186,11 +140066,10 @@
139186 sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
139187 testcase( pParse->db->mallocFailed );
139188 translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
139189 pTabItem->regResult, 1);
139190 sqlite3VdbeGoto(v, addrTop);
139191 pTabItem->fg.viaCoroutine = 0;
139192 }else{
139193 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
139194 }
139195 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
139196 sqlite3VdbeJumpHere(v, addrTop);
@@ -139364,13 +140243,15 @@
139364 ** The table object reference passed as the second argument to this function
139365 ** must represent a virtual table. This function invokes the xBestIndex()
139366 ** method of the virtual table with the sqlite3_index_info object that
139367 ** comes in as the 3rd argument to this function.
139368 **
139369 ** If an error occurs, pParse is populated with an error message and a
139370 ** non-zero value is returned. Otherwise, 0 is returned and the output
139371 ** part of the sqlite3_index_info structure is left populated.
 
 
139372 **
139373 ** Whether or not an error is returned, it is the responsibility of the
139374 ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
139375 ** that this is required.
139376 */
@@ -139380,11 +140261,11 @@
139380
139381 TRACE_IDX_INPUTS(p);
139382 rc = pVtab->pModule->xBestIndex(pVtab, p);
139383 TRACE_IDX_OUTPUTS(p);
139384
139385 if( rc!=SQLITE_OK ){
139386 if( rc==SQLITE_NOMEM ){
139387 sqlite3OomFault(pParse->db);
139388 }else if( !pVtab->zErrMsg ){
139389 sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
139390 }else{
@@ -139391,23 +140272,11 @@
139391 sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
139392 }
139393 }
139394 sqlite3_free(pVtab->zErrMsg);
139395 pVtab->zErrMsg = 0;
139396
139397 #if 0
139398 /* This error is now caught by the caller.
139399 ** Search for "xBestIndex malfunction" below */
139400 for(i=0; i<p->nConstraint; i++){
139401 if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
139402 sqlite3ErrorMsg(pParse,
139403 "table %s: xBestIndex returned an invalid plan", pTab->zName);
139404 }
139405 }
139406 #endif
139407
139408 return pParse->nErr;
139409 }
139410 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
139411
139412 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
139413 /*
@@ -140457,10 +141326,18 @@
140457 static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
140458 WhereLoop **ppPrev, *p;
140459 WhereInfo *pWInfo = pBuilder->pWInfo;
140460 sqlite3 *db = pWInfo->pParse->db;
140461 int rc;
 
 
 
 
 
 
 
 
140462
140463 /* If pBuilder->pOrSet is defined, then only keep track of the costs
140464 ** and prereqs.
140465 */
140466 if( pBuilder->pOrSet!=0 ){
@@ -141468,11 +142345,21 @@
141468 pIdxInfo->idxFlags = 0;
141469 pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
141470
141471 /* Invoke the virtual table xBestIndex() method */
141472 rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
141473 if( rc ) return rc;
 
 
 
 
 
 
 
 
 
 
141474
141475 mxTerm = -1;
141476 assert( pNew->nLSlot>=nConstraint );
141477 for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
141478 pNew->u.vtab.omitMask = 0;
@@ -141864,13 +142751,15 @@
141864 u8 priorJointype = 0;
141865
141866 /* Loop over the tables in the join, from left to right */
141867 pNew = pBuilder->pNew;
141868 whereLoopInit(pNew);
 
141869 for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
141870 Bitmask mUnusable = 0;
141871 pNew->iTab = iTab;
 
141872 pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
141873 if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
141874 /* This condition is true when pItem is the FROM clause term on the
141875 ** right-hand-side of a LEFT or CROSS JOIN. */
141876 mPrereq = mPrior;
@@ -141892,11 +142781,19 @@
141892 }
141893 if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
141894 rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
141895 }
141896 mPrior |= pNew->maskSelf;
141897 if( rc || db->mallocFailed ) break;
 
 
 
 
 
 
 
 
141898 }
141899
141900 whereLoopClear(db, pNew);
141901 return rc;
141902 }
@@ -144274,16 +145171,16 @@
144274 }
144275
144276 switch( pExpr->op ){
144277
144278 case TK_FUNCTION:
144279 if( pExpr->pWin==0 ){
144280 break;
144281 }else{
144282 Window *pWin;
144283 for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
144284 if( pExpr->pWin==pWin ){
144285 assert( pWin->pOwner==pExpr );
144286 return WRC_Prune;
144287 }
144288 }
144289 }
@@ -144396,11 +145293,11 @@
144396 ** are invoked in the correct order as described under "SELECT REWRITING"
144397 ** at the top of this file.
144398 */
144399 SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
144400 int rc = SQLITE_OK;
144401 if( p->pWin ){
144402 Vdbe *v = sqlite3GetVdbe(pParse);
144403 sqlite3 *db = pParse->db;
144404 Select *pSub = 0; /* The subquery */
144405 SrcList *pSrc = p->pSrc;
144406 Expr *pWhere = p->pWhere;
@@ -144609,15 +145506,17 @@
144609 /*
144610 ** Attach window object pWin to expression p.
144611 */
144612 SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
144613 if( p ){
 
144614 /* This routine is only called for the parser. If pWin was not
144615 ** allocated due to an OOM, then the parser would fail before ever
144616 ** invoking this routine */
144617 if( ALWAYS(pWin) ){
144618 p->pWin = pWin;
 
144619 pWin->pOwner = p;
144620 if( p->flags & EP_Distinct ){
144621 sqlite3ErrorMsg(pParse,
144622 "DISTINCT is not supported for window functions");
144623 }
@@ -145776,11 +146675,11 @@
145776 ** third argument. Set the Window.pOwner field of the new object to
145777 ** pOwner.
145778 */
145779 SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
145780 Window *pNew = 0;
145781 if( p ){
145782 pNew = sqlite3DbMallocZero(db, sizeof(Window));
145783 if( pNew ){
145784 pNew->zName = sqlite3DbStrDup(db, p->zName);
145785 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
145786 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
@@ -145928,10 +146827,11 @@
145928 **
145929 ** The following is the concatenation of all %include directives from the
145930 ** input grammar file:
145931 */
145932 /* #include <stdio.h> */
 
145933 /************ Begin %include sections from the grammar ************************/
145934
145935 /* #include "sqliteInt.h" */
145936
145937 /*
@@ -146029,17 +146929,14 @@
146029 p->flags = EP_Leaf;
146030 p->iAgg = -1;
146031 p->pLeft = p->pRight = 0;
146032 p->x.pList = 0;
146033 p->pAggInfo = 0;
146034 p->pTab = 0;
146035 p->op2 = 0;
146036 p->iTable = 0;
146037 p->iColumn = 0;
146038 #ifndef SQLITE_OMIT_WINDOWFUNC
146039 p->pWin = 0;
146040 #endif
146041 p->u.zToken = (char*)&p[1];
146042 memcpy(p->u.zToken, t.z, t.n);
146043 p->u.zToken[t.n] = 0;
146044 if( sqlite3Isquote(p->u.zToken[0]) ){
146045 if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
@@ -150227,14 +151124,13 @@
150227 #endif
150228 yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
150229 yymajor = YYNOCODE;
150230 }else{
150231 while( yypParser->yytos >= yypParser->yystack
150232 && yymx != YYERRORSYMBOL
150233 && (yyact = yy_find_reduce_action(
150234 yypParser->yytos->stateno,
150235 YYERRORSYMBOL)) >= YY_MIN_REDUCE
150236 ){
150237 yy_pop_parser_stack(yypParser);
150238 }
150239 if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
150240 yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
@@ -151197,10 +152093,77 @@
151197 while( IdChar(z[i]) ){ i++; }
151198 *tokenType = TK_ID;
151199 return i;
151200 }
151201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151202 /*
151203 ** Run the parser on the given SQL string. The parser structure is
151204 ** passed in. An SQLITE_ status code is returned. If an error occurs
151205 ** then an and attempt is made to write an error message into
151206 ** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
@@ -152594,10 +153557,11 @@
152594 { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
152595 { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
152596 { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
152597 { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
152598 { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
 
152599 };
152600 unsigned int i;
152601 rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
152602 for(i=0; i<ArraySize(aFlagOp); i++){
152603 if( aFlagOp[i].op==op ){
@@ -154821,10 +155785,13 @@
154821 | SQLITE_Fts3Tokenizer
154822 #endif
154823 #if defined(SQLITE_ENABLE_QPSG)
154824 | SQLITE_EnableQPSG
154825 #endif
 
 
 
154826 ;
154827 sqlite3HashInit(&db->aCollSeq);
154828 #ifndef SQLITE_OMIT_VIRTUALTABLE
154829 sqlite3HashInit(&db->aModule);
154830 #endif
@@ -155708,18 +156675,29 @@
155708 break;
155709 }
155710
155711 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
155712 **
155713 ** If parameter onoff is non-zero, configure the wrappers so that all
155714 ** subsequent calls to localtime() and variants fail. If onoff is zero,
155715 ** undo this setting.
155716 */
155717 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
155718 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
155719 break;
155720 }
 
 
 
 
 
 
 
 
 
 
 
 
155721
155722 /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
155723 **
155724 ** Set or clear a flag that indicates that the database file is always well-
155725 ** formed and never corrupt. This flag is clear by default, indicating that
@@ -159159,11 +160137,11 @@
159159 ){
159160 int rc = SQLITE_OK; /* Return code */
159161 const char *zCsr = zNode; /* Cursor to iterate through node */
159162 const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
159163 char *zBuffer = 0; /* Buffer to load terms into */
159164 int nAlloc = 0; /* Size of allocated buffer */
159165 int isFirstTerm = 1; /* True when processing first term on page */
159166 sqlite3_int64 iChild; /* Block id of child node to descend to */
159167
159168 /* Skip over the 'height' varint that occurs at the start of every
159169 ** interior node. Then load the blockid of the left-child of the b-tree
@@ -159197,18 +160175,18 @@
159197 }
159198 isFirstTerm = 0;
159199 zCsr += fts3GetVarint32(zCsr, &nSuffix);
159200
159201 assert( nPrefix>=0 && nSuffix>=0 );
159202 if( &zCsr[nSuffix]>zEnd ){
159203 rc = FTS_CORRUPT_VTAB;
159204 goto finish_scan;
159205 }
159206 if( nPrefix+nSuffix>nAlloc ){
159207 char *zNew;
159208 nAlloc = (nPrefix+nSuffix) * 2;
159209 zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
159210 if( !zNew ){
159211 rc = SQLITE_NOMEM;
159212 goto finish_scan;
159213 }
159214 zBuffer = zNew;
@@ -161183,13 +162161,28 @@
161183 assert( p->mxSavepoint >= iSavepoint );
161184 TESTONLY( p->mxSavepoint = iSavepoint );
161185 sqlite3Fts3PendingTermsClear(p);
161186 return SQLITE_OK;
161187 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161188
161189 static const sqlite3_module fts3Module = {
161190 /* iVersion */ 2,
161191 /* xCreate */ fts3CreateMethod,
161192 /* xConnect */ fts3ConnectMethod,
161193 /* xBestIndex */ fts3BestIndexMethod,
161194 /* xDisconnect */ fts3DisconnectMethod,
161195 /* xDestroy */ fts3DestroyMethod,
@@ -161208,10 +162201,11 @@
161208 /* xFindFunction */ fts3FindFunctionMethod,
161209 /* xRename */ fts3RenameMethod,
161210 /* xSavepoint */ fts3SavepointMethod,
161211 /* xRelease */ fts3ReleaseMethod,
161212 /* xRollbackTo */ fts3RollbackToMethod,
 
161213 };
161214
161215 /*
161216 ** This function is registered as the module destructor (called when an
161217 ** FTS3 enabled database connection is closed). It frees the memory
@@ -161488,10 +162482,11 @@
161488 }
161489
161490 return rc;
161491 }
161492
 
161493 /*
161494 ** This function is called on each phrase after the position lists for
161495 ** any deferred tokens have been loaded into memory. It updates the phrases
161496 ** current position list to include only those positions that are really
161497 ** instances of the phrase (after considering deferred tokens). If this
@@ -161591,10 +162586,11 @@
161591 }
161592 }
161593
161594 return SQLITE_OK;
161595 }
 
161596
161597 /*
161598 ** Maximum number of tokens a phrase may have to be considered for the
161599 ** incremental doclists strategy.
161600 */
@@ -163839,11 +164835,12 @@
163839 0, /* xRollback */
163840 0, /* xFindFunction */
163841 0, /* xRename */
163842 0, /* xSavepoint */
163843 0, /* xRelease */
163844 0 /* xRollbackTo */
 
163845 };
163846 int rc; /* Return code */
163847
163848 rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
163849 return rc;
@@ -167398,11 +168395,12 @@
167398 0, /* xRollback */
167399 0, /* xFindFunction */
167400 0, /* xRename */
167401 0, /* xSavepoint */
167402 0, /* xRelease */
167403 0 /* xRollbackTo */
 
167404 };
167405 int rc; /* Return code */
167406
167407 rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
167408 return rc;
@@ -168786,19 +169784,23 @@
168786
168787 /* Because of the FTS3_NODE_PADDING bytes of padding, the following is
168788 ** safe (no risk of overread) even if the node data is corrupted. */
168789 pNext += fts3GetVarint32(pNext, &nPrefix);
168790 pNext += fts3GetVarint32(pNext, &nSuffix);
168791 if( nPrefix<0 || nSuffix<=0
168792 || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
 
168793 ){
168794 return FTS_CORRUPT_VTAB;
168795 }
168796
168797 if( nPrefix+nSuffix>pReader->nTermAlloc ){
168798 int nNew = (nPrefix+nSuffix)*2;
168799 char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
 
 
 
168800 if( !zNew ){
168801 return SQLITE_NOMEM;
168802 }
168803 pReader->zTerm = zNew;
168804 pReader->nTermAlloc = nNew;
@@ -168816,11 +169818,11 @@
168816
168817 /* Check that the doclist does not appear to extend past the end of the
168818 ** b-tree node. And that the final byte of the doclist is 0x00. If either
168819 ** of these statements is untrue, then the data structure is corrupt.
168820 */
168821 if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
168822 || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
168823 ){
168824 return FTS_CORRUPT_VTAB;
168825 }
168826 return SQLITE_OK;
@@ -171142,25 +172144,30 @@
171142 if( bFirst==0 ){
171143 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
171144 }
171145 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
171146
 
 
 
171147 blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
171148 if( rc==SQLITE_OK ){
171149 memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
171150 p->term.n = nPrefix+nSuffix;
171151 p->iOff += nSuffix;
171152 if( p->iChild==0 ){
171153 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
 
 
 
171154 p->aDoclist = &p->aNode[p->iOff];
171155 p->iOff += p->nDoclist;
171156 }
171157 }
171158 }
171159
171160 assert( p->iOff<=p->nNode );
171161
171162 return rc;
171163 }
171164
171165 /*
171166 ** Release all dynamic resources held by node-reader object *p.
@@ -177566,10 +178573,13 @@
177566 #define JEACH_ATOM 3
177567 #define JEACH_ID 4
177568 #define JEACH_PARENT 5
177569 #define JEACH_FULLKEY 6
177570 #define JEACH_PATH 7
 
 
 
177571 #define JEACH_JSON 8
177572 #define JEACH_ROOT 9
177573
177574 UNUSED_PARAM(pzErr);
177575 UNUSED_PARAM(argv);
@@ -177823,39 +178833,58 @@
177823 */
177824 static int jsonEachBestIndex(
177825 sqlite3_vtab *tab,
177826 sqlite3_index_info *pIdxInfo
177827 ){
177828 int i;
177829 int jsonIdx = -1;
177830 int rootIdx = -1;
 
177831 const struct sqlite3_index_constraint *pConstraint;
177832
 
 
 
177833 UNUSED_PARAM(tab);
 
177834 pConstraint = pIdxInfo->aConstraint;
177835 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
177836 if( pConstraint->usable==0 ) continue;
177837 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
177838 switch( pConstraint->iColumn ){
177839 case JEACH_JSON: jsonIdx = i; break;
177840 case JEACH_ROOT: rootIdx = i; break;
177841 default: /* no-op */ break;
 
 
 
 
 
177842 }
177843 }
177844 if( jsonIdx<0 ){
 
 
 
 
 
 
 
 
177845 pIdxInfo->idxNum = 0;
177846 pIdxInfo->estimatedCost = 1e99;
177847 }else{
177848 pIdxInfo->estimatedCost = 1.0;
177849 pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
177850 pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
177851 if( rootIdx<0 ){
177852 pIdxInfo->idxNum = 1;
 
177853 }else{
177854 pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
177855 pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
177856 pIdxInfo->idxNum = 3;
 
177857 }
177858 }
177859 return SQLITE_OK;
177860 }
177861
@@ -177960,11 +178989,12 @@
177960 0, /* xRollback */
177961 0, /* xFindMethod */
177962 0, /* xRename */
177963 0, /* xSavepoint */
177964 0, /* xRelease */
177965 0 /* xRollbackTo */
 
177966 };
177967
177968 /* The methods of the json_tree virtual table. */
177969 static sqlite3_module jsonTreeModule = {
177970 0, /* iVersion */
@@ -177987,11 +179017,12 @@
177987 0, /* xRollback */
177988 0, /* xFindMethod */
177989 0, /* xRename */
177990 0, /* xSavepoint */
177991 0, /* xRelease */
177992 0 /* xRollbackTo */
 
177993 };
177994 #endif /* SQLITE_OMIT_VIRTUALTABLE */
177995
177996 /****************************************************************************
177997 ** The following routines are the only publically visible identifiers in this
@@ -181417,12 +182448,28 @@
181417 }
181418
181419 return rc;
181420 }
181421
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181422 static sqlite3_module rtreeModule = {
181423 2, /* iVersion */
181424 rtreeCreate, /* xCreate - create a table */
181425 rtreeConnect, /* xConnect - connect to an existing table */
181426 rtreeBestIndex, /* xBestIndex - Determine search strategy */
181427 rtreeDisconnect, /* xDisconnect - Disconnect from a table */
181428 rtreeDestroy, /* xDestroy - Drop a table */
@@ -181441,10 +182488,11 @@
181441 0, /* xFindFunction - function overloading */
181442 rtreeRename, /* xRename - rename the table */
181443 rtreeSavepoint, /* xSavepoint */
181444 0, /* xRelease */
181445 0, /* xRollbackTo */
 
181446 };
181447
181448 static int rtreeSqlInit(
181449 Rtree *pRtree,
181450 sqlite3 *db,
@@ -182431,17 +183479,27 @@
182431 ** The on-disk representation consists of a 4-byte header followed by
182432 ** the values. The 4-byte header is:
182433 **
182434 ** encoding (1 byte) 0=big-endian, 1=little-endian
182435 ** nvertex (3 bytes) Number of vertexes as a big-endian integer
 
 
 
 
 
182436 */
182437 typedef struct GeoPoly GeoPoly;
182438 struct GeoPoly {
182439 int nVertex; /* Number of vertexes */
182440 unsigned char hdr[4]; /* Header for on-disk representation */
182441 GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */
182442 };
 
 
 
 
 
182443
182444 /*
182445 ** State of a parse of a GeoJSON input.
182446 */
182447 typedef struct GeoParse GeoParse;
@@ -182463,11 +183521,11 @@
182463 a[2] = t;
182464 }
182465
182466 /* Skip whitespace. Return the next non-whitespace character. */
182467 static char geopolySkipSpace(GeoParse *p){
182468 while( p->z[0] && safe_isspace(p->z[0]) ) p->z++;
182469 return p->z[0];
182470 }
182471
182472 /* Parse out a number. Write the value into *pVal if pVal!=0.
182473 ** return non-zero on success and zero if the next token is not a number.
@@ -182483,11 +183541,11 @@
182483 c = z[j];
182484 }
182485 if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
182486 for(;; j++){
182487 c = z[j];
182488 if( c>='0' && c<='9' ) continue;
182489 if( c=='.' ){
182490 if( z[j-1]=='-' ) return 0;
182491 if( seenDP ) return 0;
182492 seenDP = 1;
182493 continue;
@@ -182505,11 +183563,21 @@
182505 continue;
182506 }
182507 break;
182508 }
182509 if( z[j-1]<'0' ) return 0;
182510 if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
 
 
 
 
 
 
 
 
 
 
182511 p->z += j;
182512 return 1;
182513 }
182514
182515 /*
@@ -182563,16 +183631,14 @@
182563 && s.nVertex>=4
182564 && s.a[0]==s.a[s.nVertex*2-2]
182565 && s.a[1]==s.a[s.nVertex*2-1]
182566 && (s.z++, geopolySkipSpace(&s)==0)
182567 ){
182568 int nByte;
182569 GeoPoly *pOut;
182570 int x = 1;
182571 s.nVertex--; /* Remove the redundant vertex at the end */
182572 nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
182573 pOut = sqlite3_malloc64( nByte );
182574 x = 1;
182575 if( pOut==0 ) goto parse_json_err;
182576 pOut->nVertex = s.nVertex;
182577 memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
182578 pOut->hdr[0] = *(unsigned char*)&x;
@@ -182770,10 +183836,31 @@
182770 sqlite3_result_blob(context, p->hdr,
182771 4+8*p->nVertex, SQLITE_TRANSIENT);
182772 sqlite3_free(p);
182773 }
182774 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182775
182776 /*
182777 ** Implementation of the geopoly_area(X) function.
182778 **
182779 ** If the input is a well-formed Geopoly BLOB then return the area
@@ -182786,24 +183873,109 @@
182786 int argc,
182787 sqlite3_value **argv
182788 ){
182789 GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
182790 if( p ){
182791 double rArea = 0.0;
182792 int ii;
182793 for(ii=0; ii<p->nVertex-1; ii++){
182794 rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
182795 * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
182796 * 0.5;
182797 }
182798 rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
182799 * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
182800 * 0.5;
182801 sqlite3_result_double(context, rArea);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182802 sqlite3_free(p);
182803 }
182804 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182805
182806 /*
182807 ** If pPoly is a polygon, compute its bounding box. Then:
182808 **
182809 ** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
@@ -182845,11 +184017,11 @@
182845 else if( r>mxY ) mxY = (float)r;
182846 }
182847 if( pRc ) *pRc = SQLITE_OK;
182848 if( aCoord==0 ){
182849 geopolyBboxFill:
182850 pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
182851 if( pOut==0 ){
182852 sqlite3_free(p);
182853 if( context ) sqlite3_result_error_nomem(context);
182854 if( pRc ) *pRc = SQLITE_NOMEM;
182855 return 0;
@@ -183873,11 +185045,20 @@
183873 sqlite3_bind_int64(pUp, 1, cell.iRowid);
183874 assert( pRtree->nAux>=1 );
183875 if( sqlite3_value_nochange(aData[2]) ){
183876 sqlite3_bind_null(pUp, 2);
183877 }else{
183878 sqlite3_bind_value(pUp, 2, aData[2]);
 
 
 
 
 
 
 
 
 
183879 nChange = 1;
183880 }
183881 for(jj=1; jj<pRtree->nAux; jj++){
183882 nChange++;
183883 sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
@@ -183917,11 +185098,11 @@
183917 return 0;
183918 }
183919
183920
183921 static sqlite3_module geopolyModule = {
183922 2, /* iVersion */
183923 geopolyCreate, /* xCreate - create a table */
183924 geopolyConnect, /* xConnect - connect to an existing table */
183925 geopolyBestIndex, /* xBestIndex - Determine search strategy */
183926 rtreeDisconnect, /* xDisconnect - Disconnect from a table */
183927 rtreeDestroy, /* xDestroy - Drop a table */
@@ -183940,29 +185121,33 @@
183940 geopolyFindFunction, /* xFindFunction - function overloading */
183941 rtreeRename, /* xRename - rename the table */
183942 rtreeSavepoint, /* xSavepoint */
183943 0, /* xRelease */
183944 0, /* xRollbackTo */
 
183945 };
183946
183947 static int sqlite3_geopoly_init(sqlite3 *db){
183948 int rc = SQLITE_OK;
183949 static const struct {
183950 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
183951 int nArg;
 
183952 const char *zName;
183953 } aFunc[] = {
183954 { geopolyAreaFunc, 1, "geopoly_area" },
183955 { geopolyBlobFunc, 1, "geopoly_blob" },
183956 { geopolyJsonFunc, 1, "geopoly_json" },
183957 { geopolySvgFunc, -1, "geopoly_svg" },
183958 { geopolyWithinFunc, 2, "geopoly_within" },
183959 { geopolyContainsPointFunc, 3, "geopoly_contains_point" },
183960 { geopolyOverlapFunc, 2, "geopoly_overlap" },
183961 { geopolyDebugFunc, 1, "geopoly_debug" },
183962 { geopolyBBoxFunc, 1, "geopoly_bbox" },
183963 { geopolyXformFunc, 7, "geopoly_xform" },
 
 
183964 };
183965 static const struct {
183966 void (*xStep)(sqlite3_context*,int,sqlite3_value**);
183967 void (*xFinal)(sqlite3_context*);
183968 const char *zName;
@@ -183969,12 +185154,13 @@
183969 } aAgg[] = {
183970 { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" },
183971 };
183972 int i;
183973 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
 
183974 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
183975 SQLITE_UTF8, 0,
183976 aFunc[i].xFunc, 0, 0);
183977 }
183978 for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
183979 rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0,
183980 0, aAgg[i].xStep, aAgg[i].xFinal);
@@ -185997,11 +187183,12 @@
185997 struct rbu_vfs {
185998 sqlite3_vfs base; /* rbu VFS shim methods */
185999 sqlite3_vfs *pRealVfs; /* Underlying VFS */
186000 sqlite3_mutex *mutex; /* Mutex to protect pMain */
186001 sqlite3rbu *pRbu; /* Owner RBU object */
186002 rbu_file *pMain; /* Linked list of main db files */
 
186003 };
186004
186005 /*
186006 ** Each file opened by an rbu VFS is represented by an instance of
186007 ** the following structure.
@@ -186026,10 +187213,11 @@
186026 char *zDel; /* Delete this when closing file */
186027
186028 const char *zWal; /* Wal filename for this main db file */
186029 rbu_file *pWalFd; /* Wal file descriptor for this main db */
186030 rbu_file *pMainNext; /* Next MAIN_DB file */
 
186031 };
186032
186033 /*
186034 ** True for an RBU vacuum handle, or false otherwise.
186035 */
@@ -189621,10 +190809,73 @@
189621 pFd->sz = nNew;
189622 assert( pRbu->szTemp>=0 );
189623 if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
189624 return SQLITE_OK;
189625 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189626
189627 /*
189628 ** Close an rbu file.
189629 */
189630 static int rbuVfsClose(sqlite3_file *pFile){
@@ -189639,21 +190890,18 @@
189639 sqlite3_free(p->apShm);
189640 p->apShm = 0;
189641 sqlite3_free(p->zDel);
189642
189643 if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
189644 rbu_file **pp;
189645 sqlite3_mutex_enter(p->pRbuVfs->mutex);
189646 for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
189647 *pp = p->pMainNext;
189648 sqlite3_mutex_leave(p->pRbuVfs->mutex);
189649 rbuUnlockShm(p);
189650 p->pReal->pMethods->xShmUnmap(p->pReal, 0);
189651 }
189652 else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
189653 rbuUpdateTempSize(p, 0);
189654 }
 
189655
189656 /* Close the underlying file handle */
189657 rc = p->pReal->pMethods->xClose(p->pReal);
189658 return rc;
189659 }
@@ -189908,10 +191156,13 @@
189908 rc = SQLITE_ERROR;
189909 pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
189910 }else if( rc==SQLITE_NOTFOUND ){
189911 pRbu->pTargetFd = p;
189912 p->pRbu = pRbu;
 
 
 
189913 if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
189914 rc = SQLITE_OK;
189915 }
189916 }
189917 return rc;
@@ -190069,24 +191320,10 @@
190069 rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
190070 }
190071 return rc;
190072 }
190073
190074 /*
190075 ** Given that zWal points to a buffer containing a wal file name passed to
190076 ** either the xOpen() or xAccess() VFS method, return a pointer to the
190077 ** file-handle opened by the same database connection on the corresponding
190078 ** database file.
190079 */
190080 static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
190081 rbu_file *pDb;
190082 sqlite3_mutex_enter(pRbuVfs->mutex);
190083 for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
190084 sqlite3_mutex_leave(pRbuVfs->mutex);
190085 return pDb;
190086 }
190087
190088 /*
190089 ** A main database named zName has just been opened. The following
190090 ** function returns a pointer to a buffer owned by SQLite that contains
190091 ** the name of the *-wal file this db connection will use. SQLite
190092 ** happens to pass a pointer to this buffer when using xAccess()
@@ -190161,11 +191398,11 @@
190161 ** happens to pass a pointer to this buffer when using xAccess()
190162 ** or xOpen() to operate on the *-wal file. */
190163 pFd->zWal = rbuMainToWal(zName, flags);
190164 }
190165 else if( flags & SQLITE_OPEN_WAL ){
190166 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
190167 if( pDb ){
190168 if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
190169 /* This call is to open a *-wal file. Intead, open the *-oal. This
190170 ** code ensures that the string passed to xOpen() is terminated by a
190171 ** pair of '\0' bytes in case the VFS attempts to extract a URI
@@ -190213,14 +191450,11 @@
190213 /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
190214 ** pointer and, if the file is a main database file, link it into the
190215 ** mutex protected linked list of all such files. */
190216 pFile->pMethods = &rbuvfs_io_methods;
190217 if( flags & SQLITE_OPEN_MAIN_DB ){
190218 sqlite3_mutex_enter(pRbuVfs->mutex);
190219 pFd->pMainNext = pRbuVfs->pMain;
190220 pRbuVfs->pMain = pFd;
190221 sqlite3_mutex_leave(pRbuVfs->mutex);
190222 }
190223 }else{
190224 sqlite3_free(pFd->zDel);
190225 }
190226
@@ -190264,11 +191498,11 @@
190264 ** causing SQLite to call xOpen() to open it. This call will also
190265 ** be intercepted (see the rbuVfsOpen() function) and the *-oal
190266 ** file opened instead.
190267 */
190268 if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
190269 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
190270 if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
190271 if( *pResOut ){
190272 rc = SQLITE_CANTOPEN;
190273 }else{
190274 sqlite3_int64 sz = 0;
@@ -190677,21 +191911,19 @@
190677 ** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
190678 */
190679 static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
190680 int i;
190681
190682 pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
190683
190684 /* Look for a valid schema=? constraint. If found, change the idxNum to
190685 ** 1 and request the value of that constraint be sent to xFilter. And
190686 ** lower the cost estimate to encourage the constrained version to be
190687 ** used.
190688 */
190689 for(i=0; i<pIdxInfo->nConstraint; i++){
190690 if( pIdxInfo->aConstraint[i].usable==0 ) continue;
190691 if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
190692 if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
 
 
190693 pIdxInfo->idxNum = 1;
190694 pIdxInfo->estimatedCost = 1.0;
190695 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
190696 pIdxInfo->aConstraintUsage[i].omit = 1;
190697 break;
@@ -190737,18 +191969,24 @@
190737
190738 *ppCursor = (sqlite3_vtab_cursor *)pCsr;
190739 return SQLITE_OK;
190740 }
190741
190742 static void statClearPage(StatPage *p){
190743 int i;
190744 if( p->aCell ){
190745 for(i=0; i<p->nCell; i++){
190746 sqlite3_free(p->aCell[i].aOvfl);
190747 }
190748 sqlite3_free(p->aCell);
190749 }
 
 
 
 
 
 
190750 sqlite3PagerUnref(p->pPg);
190751 sqlite3_free(p->zPath);
190752 memset(p, 0, sizeof(StatPage));
190753 }
190754
@@ -190807,26 +192045,37 @@
190807
190808 u8 *aData = sqlite3PagerGetData(p->pPg);
190809 u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
190810
190811 p->flags = aHdr[0];
 
 
 
 
 
 
 
 
 
 
190812 p->nCell = get2byte(&aHdr[3]);
190813 p->nMxPayload = 0;
190814
190815 isLeaf = (p->flags==0x0A || p->flags==0x0D);
190816 nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
190817
190818 nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
190819 nUnused += (int)aHdr[7];
190820 iOff = get2byte(&aHdr[1]);
190821 while( iOff ){
 
 
190822 nUnused += get2byte(&aData[iOff+2]);
190823 iOff = get2byte(&aData[iOff]);
 
 
190824 }
190825 p->nUnused = nUnused;
190826 p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
190827 szPage = sqlite3BtreeGetPageSize(pBt);
190828
190829 if( p->nCell ){
190830 int i; /* Used to iterate through cells */
190831 int nUsable; /* Usable bytes per page */
190832
@@ -190839,10 +192088,11 @@
190839
190840 for(i=0; i<p->nCell; i++){
190841 StatCell *pCell = &p->aCell[i];
190842
190843 iOff = get2byte(&aData[nHdr+i*2]);
 
190844 if( !isLeaf ){
190845 pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
190846 iOff += 4;
190847 }
190848 if( p->flags==0x05 ){
@@ -190855,17 +192105,18 @@
190855 u64 dummy;
190856 iOff += sqlite3GetVarint(&aData[iOff], &dummy);
190857 }
190858 if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
190859 getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
 
190860 pCell->nLocal = nLocal;
190861 assert( nLocal>=0 );
190862 assert( nPayload>=(u32)nLocal );
190863 assert( nLocal<=(nUsable-35) );
190864 if( nPayload>(u32)nLocal ){
190865 int j;
190866 int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
 
190867 pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
190868 pCell->nOvfl = nOvfl;
190869 pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
190870 if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
190871 pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
@@ -190885,10 +192136,15 @@
190885 }
190886 }
190887 }
190888
190889 return SQLITE_OK;
 
 
 
 
 
190890 }
190891
190892 /*
190893 ** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
190894 ** the current value of pCsr->iPageno.
@@ -191180,10 +192436,11 @@
191180 0, /* xFindMethod */
191181 0, /* xRename */
191182 0, /* xSavepoint */
191183 0, /* xRelease */
191184 0, /* xRollbackTo */
 
191185 };
191186 return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
191187 }
191188 #elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
191189 SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191310,13 +192567,12 @@
191310 for(i=0; i<pIdxInfo->nConstraint; i++){
191311 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
191312 if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
191313 if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
191314 if( !p->usable ){
191315 /* No solution. Use the default SQLITE_BIG_DBL cost */
191316 pIdxInfo->estimatedRows = 0x7fffffff;
191317 return SQLITE_OK;
191318 }
191319 iPlan = 2;
191320 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
191321 pIdxInfo->aConstraintUsage[i].omit = 1;
191322 break;
@@ -191504,10 +192760,14 @@
191504 int iDb;
191505 Btree *pBt;
191506 Pager *pPager;
191507 int szPage;
191508
 
 
 
 
191509 if( argc==1 ){
191510 zErr = "cannot delete";
191511 goto update_fail;
191512 }
191513 pgno = sqlite3_value_int(argv[0]);
@@ -191594,10 +192854,11 @@
191594 0, /* xFindMethod */
191595 0, /* xRename */
191596 0, /* xSavepoint */
191597 0, /* xRelease */
191598 0, /* xRollbackTo */
 
191599 };
191600 return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
191601 }
191602 #elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
191603 SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191629,10 +192890,12 @@
191629 # define SESSIONS_STRM_CHUNK_SIZE 64
191630 # else
191631 # define SESSIONS_STRM_CHUNK_SIZE 1024
191632 # endif
191633 #endif
 
 
191634
191635 typedef struct SessionHook SessionHook;
191636 struct SessionHook {
191637 void *pCtx;
191638 int (*xOld)(void*,int,sqlite3_value**);
@@ -191692,10 +192955,11 @@
191692 */
191693 struct sqlite3_changeset_iter {
191694 SessionInput in; /* Input buffer or stream */
191695 SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
191696 int bPatchset; /* True if this is a patchset */
 
191697 int rc; /* Iterator error code */
191698 sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
191699 char *zTab; /* Current table */
191700 int nCol; /* Number of columns in zTab */
191701 int op; /* Current operation */
@@ -191848,10 +193112,46 @@
191848 ** and fields associated with modified columns contain the new column values.
191849 **
191850 ** The records associated with INSERT changes are in the same format as for
191851 ** changesets. It is not possible for a record associated with an INSERT
191852 ** change to contain a field set to "undefined".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191853 */
191854
191855 /*
191856 ** For each row modified during a session, there exists a single instance of
191857 ** this structure stored in a SessionTable.aChange[] hash table.
@@ -193398,16 +194698,16 @@
193398 ** set *pRc to SQLITE_NOMEM and return non-zero.
193399 */
193400 static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
193401 if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
193402 u8 *aNew;
193403 int nNew = p->nAlloc ? p->nAlloc : 128;
193404 do {
193405 nNew = nNew*2;
193406 }while( nNew<(p->nBuf+nByte) );
193407
193408 aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
193409 if( 0==aNew ){
193410 *pRc = SQLITE_NOMEM;
193411 }else{
193412 p->aBuf = aNew;
193413 p->nAlloc = nNew;
@@ -194001,16 +195301,16 @@
194001 }
194002 if( rc==SQLITE_OK ){
194003 rc = sqlite3_reset(pSel);
194004 }
194005
194006 /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
194007 ** its contents to the xOutput() callback. */
194008 if( xOutput
194009 && rc==SQLITE_OK
194010 && buf.nBuf>nNoop
194011 && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE
194012 ){
194013 rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
194014 nNoop = -1;
194015 buf.nBuf = 0;
194016 }
@@ -194145,11 +195445,12 @@
194145 static int sessionChangesetStart(
194146 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
194147 int (*xInput)(void *pIn, void *pData, int *pnData),
194148 void *pIn,
194149 int nChangeset, /* Size of buffer pChangeset in bytes */
194150 void *pChangeset /* Pointer to buffer containing changeset */
 
194151 ){
194152 sqlite3_changeset_iter *pRet; /* Iterator to return */
194153 int nByte; /* Number of bytes to allocate for iterator */
194154
194155 assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
@@ -194165,10 +195466,11 @@
194165 pRet->in.aData = (u8 *)pChangeset;
194166 pRet->in.nData = nChangeset;
194167 pRet->in.xInput = xInput;
194168 pRet->in.pIn = pIn;
194169 pRet->in.bEof = (xInput ? 0 : 1);
 
194170
194171 /* Populate the output variable and return success. */
194172 *pp = pRet;
194173 return SQLITE_OK;
194174 }
@@ -194179,11 +195481,20 @@
194179 SQLITE_API int sqlite3changeset_start(
194180 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
194181 int nChangeset, /* Size of buffer pChangeset in bytes */
194182 void *pChangeset /* Pointer to buffer containing changeset */
194183 ){
194184 return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
 
 
 
 
 
 
 
 
 
194185 }
194186
194187 /*
194188 ** Streaming version of sqlite3changeset_start().
194189 */
@@ -194190,19 +195501,28 @@
194190 SQLITE_API int sqlite3changeset_start_strm(
194191 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
194192 int (*xInput)(void *pIn, void *pData, int *pnData),
194193 void *pIn
194194 ){
194195 return sessionChangesetStart(pp, xInput, pIn, 0, 0);
 
 
 
 
 
 
 
 
 
194196 }
194197
194198 /*
194199 ** If the SessionInput object passed as the only argument is a streaming
194200 ** object and the buffer is full, discard some data to free up space.
194201 */
194202 static void sessionDiscardData(SessionInput *pIn){
194203 if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
194204 int nMove = pIn->buf.nBuf - pIn->iNext;
194205 assert( nMove>=0 );
194206 if( nMove>0 ){
194207 memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
194208 }
@@ -194221,11 +195541,11 @@
194221 */
194222 static int sessionInputBuffer(SessionInput *pIn, int nByte){
194223 int rc = SQLITE_OK;
194224 if( pIn->xInput ){
194225 while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
194226 int nNew = SESSIONS_STRM_CHUNK_SIZE;
194227
194228 if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
194229 if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
194230 rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
194231 if( nNew==0 ){
@@ -194569,14 +195889,14 @@
194569 p->in.iCurrent = p->in.iNext;
194570 if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
194571 op = p->in.aData[p->in.iNext++];
194572 }
194573
194574 if( p->zTab==0 ){
194575 /* The first record in the changeset is not a table header. Must be a
194576 ** corrupt changeset. */
194577 assert( p->in.iNext==1 );
194578 return (p->rc = SQLITE_CORRUPT_BKPT);
194579 }
194580
194581 p->op = op;
194582 p->bIndirect = p->in.aData[p->in.iNext++];
@@ -194597,37 +195917,43 @@
194597 p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
194598 if( p->rc!=SQLITE_OK ) return p->rc;
194599 *paRec = &p->in.aData[p->in.iNext];
194600 p->in.iNext += *pnRec;
194601 }else{
 
 
194602
194603 /* If this is an UPDATE or DELETE, read the old.* record. */
194604 if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
194605 u8 *abPK = p->bPatchset ? p->abPK : 0;
194606 p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
194607 if( p->rc!=SQLITE_OK ) return p->rc;
194608 }
194609
194610 /* If this is an INSERT or UPDATE, read the new.* record. */
194611 if( p->op!=SQLITE_DELETE ){
194612 p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
194613 if( p->rc!=SQLITE_OK ) return p->rc;
194614 }
194615
194616 if( p->bPatchset && p->op==SQLITE_UPDATE ){
194617 /* If this is an UPDATE that is part of a patchset, then all PK and
194618 ** modified fields are present in the new.* record. The old.* record
194619 ** is currently completely empty. This block shifts the PK fields from
194620 ** new.* to old.*, to accommodate the code that reads these arrays. */
194621 for(i=0; i<p->nCol; i++){
194622 assert( p->apValue[i]==0 );
194623 if( p->abPK[i] ){
 
194624 p->apValue[i] = p->apValue[i+p->nCol];
194625 if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
194626 p->apValue[i+p->nCol] = 0;
194627 }
194628 }
 
 
 
194629 }
194630 }
194631
194632 return SQLITE_ROW;
194633 }
@@ -194940,11 +196266,11 @@
194940 rc = SQLITE_CORRUPT_BKPT;
194941 goto finished_invert;
194942 }
194943
194944 assert( rc==SQLITE_OK );
194945 if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
194946 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
194947 sOut.nBuf = 0;
194948 if( rc!=SQLITE_OK ) goto finished_invert;
194949 }
194950 }
@@ -195019,11 +196345,12 @@
195019 u8 *abPK; /* Boolean array - true if column is in PK */
195020 int bStat1; /* True if table is sqlite_stat1 */
195021 int bDeferConstraints; /* True to defer constraints */
195022 SessionBuffer constraints; /* Deferred constraints are stored here */
195023 SessionBuffer rebase; /* Rebase information (if any) here */
195024 int bRebaseStarted; /* If table header is already in rebase */
 
195025 };
195026
195027 /*
195028 ** Formulate a statement to DELETE a row from database db. Assuming a table
195029 ** structure like this:
@@ -195416,39 +196743,40 @@
195416 SessionApplyCtx *p, /* Apply context */
195417 int eType, /* Conflict resolution (OMIT or REPLACE) */
195418 sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
195419 ){
195420 int rc = SQLITE_OK;
195421 int i;
195422 int eOp = pIter->op;
195423 if( p->bRebaseStarted==0 ){
195424 /* Append a table-header to the rebase buffer */
195425 const char *zTab = pIter->zTab;
195426 sessionAppendByte(&p->rebase, 'T', &rc);
195427 sessionAppendVarint(&p->rebase, p->nCol, &rc);
195428 sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
195429 sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
195430 p->bRebaseStarted = 1;
195431 }
195432
195433 assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
195434 assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
195435
195436 sessionAppendByte(&p->rebase,
195437 (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
195438 );
195439 sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
195440 for(i=0; i<p->nCol; i++){
195441 sqlite3_value *pVal = 0;
195442 if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
195443 sqlite3changeset_old(pIter, i, &pVal);
195444 }else{
195445 sqlite3changeset_new(pIter, i, &pVal);
195446 }
195447 sessionAppendValue(&p->rebase, pVal, &rc);
195448 }
195449
 
195450 return rc;
195451 }
195452
195453 /*
195454 ** Invoke the conflict handler for the change that the changeset iterator
@@ -195787,11 +197115,11 @@
195787 while( pApply->constraints.nBuf ){
195788 sqlite3_changeset_iter *pIter2 = 0;
195789 SessionBuffer cons = pApply->constraints;
195790 memset(&pApply->constraints, 0, sizeof(SessionBuffer));
195791
195792 rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
195793 if( rc==SQLITE_OK ){
195794 int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
195795 int rc2;
195796 pIter2->bPatchset = bPatchset;
195797 pIter2->zTab = (char*)zTab;
@@ -195853,10 +197181,11 @@
195853
195854 assert( xConflict!=0 );
195855
195856 pIter->in.bNoDiscard = 1;
195857 memset(&sApply, 0, sizeof(sApply));
 
195858 sqlite3_mutex_enter(sqlite3_db_mutex(db));
195859 if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
195860 rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
195861 }
195862 if( rc==SQLITE_OK ){
@@ -196003,11 +197332,12 @@
196003 sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
196004 sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
196005 }
196006 }
196007
196008 if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
 
196009 *ppRebase = (void*)sApply.rebase.aBuf;
196010 *pnRebase = sApply.rebase.nBuf;
196011 sApply.rebase.aBuf = 0;
196012 }
196013 sqlite3_finalize(sApply.pInsert);
@@ -196041,11 +197371,12 @@
196041 void *pCtx, /* First argument passed to xConflict */
196042 void **ppRebase, int *pnRebase,
196043 int flags
196044 ){
196045 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
196046 int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
 
196047 if( rc==SQLITE_OK ){
196048 rc = sessionChangesetApply(
196049 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
196050 );
196051 }
@@ -196098,11 +197429,12 @@
196098 void *pCtx, /* First argument passed to xConflict */
196099 void **ppRebase, int *pnRebase,
196100 int flags
196101 ){
196102 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
196103 int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
 
196104 if( rc==SQLITE_OK ){
196105 rc = sessionChangesetApply(
196106 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
196107 );
196108 }
@@ -196471,17 +197803,16 @@
196471 SessionChange *p;
196472 for(p=pTab->apChange[i]; p; p=p->pNext){
196473 sessionAppendByte(&buf, p->op, &rc);
196474 sessionAppendByte(&buf, p->bIndirect, &rc);
196475 sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
 
 
 
 
196476 }
196477 }
196478
196479 if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
196480 rc = xOutput(pOut, buf.aBuf, buf.nBuf);
196481 buf.nBuf = 0;
196482 }
196483 }
196484
196485 if( rc==SQLITE_OK ){
196486 if( xOutput ){
196487 if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
@@ -196868,11 +198199,11 @@
196868 if( bDone==0 ){
196869 sessionAppendByte(&sOut, pIter->op, &rc);
196870 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
196871 sessionAppendBlob(&sOut, aRec, nRec, &rc);
196872 }
196873 if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
196874 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
196875 sOut.nBuf = 0;
196876 }
196877 if( rc ) break;
196878 }
@@ -196978,10 +198309,31 @@
196978 if( p ){
196979 sessionDeleteTable(p->grp.pList);
196980 sqlite3_free(p);
196981 }
196982 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196983
196984 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
196985
196986 /************** End of sqlite3session.c **************************************/
196987 /************** Begin file fts5.c ********************************************/
@@ -198413,10 +199765,11 @@
198413 **
198414 ** The following is the concatenation of all %include directives from the
198415 ** input grammar file:
198416 */
198417 /* #include <stdio.h> */
 
198418 /************ Begin %include sections from the grammar ************************/
198419
198420 /* #include "fts5Int.h" */
198421 /* #include "fts5parse.h" */
198422
@@ -199740,14 +201093,13 @@
199740 #endif
199741 fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
199742 fts5yymajor = fts5YYNOCODE;
199743 }else{
199744 while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
199745 && fts5yymx != fts5YYERRORSYMBOL
199746 && (fts5yyact = fts5yy_find_reduce_action(
199747 fts5yypParser->fts5yytos->stateno,
199748 fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
199749 ){
199750 fts5yy_pop_parser_stack(fts5yypParser);
199751 }
199752 if( fts5yypParser->fts5yytos < fts5yypParser->fts5yystack || fts5yymajor==0 ){
199753 fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
@@ -210693,11 +212045,11 @@
210693 sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
210694 pRet = 0;
210695 fts5CloseReader(p);
210696 }
210697
210698 *ppIter = &pRet->base;
210699 sqlite3Fts5BufferFree(&buf);
210700 }
210701 return fts5IndexReturn(p);
210702 }
210703
@@ -214442,16 +215794,31 @@
214442 int nArg, /* Number of args */
214443 sqlite3_value **apUnused /* Function arguments */
214444 ){
214445 assert( nArg==0 );
214446 UNUSED_PARAM2(nArg, apUnused);
214447 sqlite3_result_text(pCtx, "fts5: 2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7", -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214448 }
214449
214450 static int fts5Init(sqlite3 *db){
214451 static const sqlite3_module fts5Mod = {
214452 /* iVersion */ 2,
214453 /* xCreate */ fts5CreateMethod,
214454 /* xConnect */ fts5ConnectMethod,
214455 /* xBestIndex */ fts5BestIndexMethod,
214456 /* xDisconnect */ fts5DisconnectMethod,
214457 /* xDestroy */ fts5DestroyMethod,
@@ -214470,10 +215837,11 @@
214470 /* xFindFunction */ fts5FindFunctionMethod,
214471 /* xRename */ fts5RenameMethod,
214472 /* xSavepoint */ fts5SavepointMethod,
214473 /* xRelease */ fts5ReleaseMethod,
214474 /* xRollbackTo */ fts5RollbackToMethod,
 
214475 };
214476
214477 int rc;
214478 Fts5Global *pGlobal = 0;
214479
@@ -218514,20 +219882,22 @@
218514 int rc = SQLITE_OK;
218515 Fts5IndexIter *pIter = pCsr->pIter;
218516 i64 *pp = &pCsr->iInstPos;
218517 int *po = &pCsr->iInstOff;
218518
 
 
218519 while( eDetail==FTS5_DETAIL_NONE
218520 || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
218521 ){
218522 pCsr->iInstPos = 0;
218523 pCsr->iInstOff = 0;
218524
218525 rc = sqlite3Fts5IterNextScan(pCsr->pIter);
218526 if( rc==SQLITE_OK ){
218527 rc = fts5VocabInstanceNewTerm(pCsr);
218528 if( eDetail==FTS5_DETAIL_NONE ) break;
218529 }
218530 if( rc ){
218531 pCsr->bEof = 1;
218532 break;
218533 }
@@ -218838,17 +220208,16 @@
218838 /* xFindFunction */ 0,
218839 /* xRename */ 0,
218840 /* xSavepoint */ 0,
218841 /* xRelease */ 0,
218842 /* xRollbackTo */ 0,
 
218843 };
218844 void *p = (void*)pGlobal;
218845
218846 return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
218847 }
218848
218849
218850
218851
218852
218853 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
218854
@@ -219120,10 +220489,11 @@
219120 0, /* xFindMethod */
219121 0, /* xRename */
219122 0, /* xSavepoint */
219123 0, /* xRelease */
219124 0, /* xRollbackTo */
 
219125 };
219126
219127 #endif /* SQLITE_OMIT_VIRTUALTABLE */
219128
219129 SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){
@@ -219152,12 +220522,12 @@
219152 }
219153 #endif /* SQLITE_CORE */
219154 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
219155
219156 /************** End of stmt.c ************************************************/
219157 #if __LINE__!=219157
219158 #undef SQLITE_SOURCE_ID
219159 #define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792alt2"
219160 #endif
219161 /* Return the source-id for this library */
219162 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
219163 /************************** End of sqlite3.c ******************************/
219164
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.26.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -257,10 +257,13 @@
257 #if SQLITE_ENABLE_FTS4
258 "ENABLE_FTS4",
259 #endif
260 #if SQLITE_ENABLE_FTS5
261 "ENABLE_FTS5",
262 #endif
263 #if SQLITE_ENABLE_GEOPOLY
264 "ENABLE_GEOPOLY",
265 #endif
266 #if SQLITE_ENABLE_HIDDEN_COLUMNS
267 "ENABLE_HIDDEN_COLUMNS",
268 #endif
269 #if SQLITE_ENABLE_ICU
@@ -287,10 +290,13 @@
290 #if SQLITE_ENABLE_MEMSYS5
291 "ENABLE_MEMSYS5",
292 #endif
293 #if SQLITE_ENABLE_MULTIPLEX
294 "ENABLE_MULTIPLEX",
295 #endif
296 #if SQLITE_ENABLE_NORMALIZE
297 "ENABLE_NORMALIZE",
298 #endif
299 #if SQLITE_ENABLE_NULL_TRIM
300 "ENABLE_NULL_TRIM",
301 #endif
302 #if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
@@ -1154,13 +1160,13 @@
1160 **
1161 ** See also: [sqlite3_libversion()],
1162 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1163 ** [sqlite_version()] and [sqlite_source_id()].
1164 */
1165 #define SQLITE_VERSION "3.26.0"
1166 #define SQLITE_VERSION_NUMBER 3026000
1167 #define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
1168
1169 /*
1170 ** CAPI3REF: Run-Time Library Version Numbers
1171 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1172 **
@@ -3048,10 +3054,11 @@
3054 ** the call worked. ^The [sqlite3_db_config()] interface will return a
3055 ** non-zero [error code] if a discontinued or unsupported configuration option
3056 ** is invoked.
3057 **
3058 ** <dl>
3059 ** [[SQLITE_DBCONFIG_LOOKASIDE]]
3060 ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
3061 ** <dd> ^This option takes three additional arguments that determine the
3062 ** [lookaside memory allocator] configuration for the [database connection].
3063 ** ^The first argument (the third parameter to [sqlite3_db_config()] is a
3064 ** pointer to a memory buffer to use for lookaside memory.
@@ -3070,10 +3077,11 @@
3077 ** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
3078 ** Any attempt to change the lookaside memory configuration when lookaside
3079 ** memory is in use leaves the configuration unchanged and returns
3080 ** [SQLITE_BUSY].)^</dd>
3081 **
3082 ** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
3083 ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
3084 ** <dd> ^This option is used to enable or disable the enforcement of
3085 ** [foreign key constraints]. There should be two additional arguments.
3086 ** The first argument is an integer which is 0 to disable FK enforcement,
3087 ** positive to enable FK enforcement or negative to leave FK enforcement
@@ -3080,10 +3088,11 @@
3088 ** unchanged. The second parameter is a pointer to an integer into which
3089 ** is written 0 or 1 to indicate whether FK enforcement is off or on
3090 ** following this call. The second parameter may be a NULL pointer, in
3091 ** which case the FK enforcement setting is not reported back. </dd>
3092 **
3093 ** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
3094 ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
3095 ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
3096 ** There should be two additional arguments.
3097 ** The first argument is an integer which is 0 to disable triggers,
3098 ** positive to enable triggers or negative to leave the setting unchanged.
@@ -3090,10 +3099,11 @@
3099 ** The second parameter is a pointer to an integer into which
3100 ** is written 0 or 1 to indicate whether triggers are disabled or enabled
3101 ** following this call. The second parameter may be a NULL pointer, in
3102 ** which case the trigger setting is not reported back. </dd>
3103 **
3104 ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
3105 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
3106 ** <dd> ^This option is used to enable or disable the two-argument
3107 ** version of the [fts3_tokenizer()] function which is part of the
3108 ** [FTS3] full-text search engine extension.
3109 ** There should be two additional arguments.
@@ -3103,10 +3113,11 @@
3113 ** The second parameter is a pointer to an integer into which
3114 ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
3115 ** following this call. The second parameter may be a NULL pointer, in
3116 ** which case the new setting is not reported back. </dd>
3117 **
3118 ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
3119 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
3120 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
3121 ** interface independently of the [load_extension()] SQL function.
3122 ** The [sqlite3_enable_load_extension()] API enables or disables both the
3123 ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -3120,19 +3131,20 @@
3131 ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
3132 ** is disabled or enabled following this call. The second parameter may
3133 ** be a NULL pointer, in which case the new setting is not reported back.
3134 ** </dd>
3135 **
3136 ** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
3137 ** <dd> ^This option is used to change the name of the "main" database
3138 ** schema. ^The sole argument is a pointer to a constant UTF8 string
3139 ** which will become the new schema name in place of "main". ^SQLite
3140 ** does not make a copy of the new main schema name string, so the application
3141 ** must ensure that the argument passed into this DBCONFIG option is unchanged
3142 ** until after the database connection closes.
3143 ** </dd>
3144 **
3145 ** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
3146 ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
3147 ** <dd> Usually, when a database in wal mode is closed or detached from a
3148 ** database handle, SQLite checks if this will mean that there are now no
3149 ** connections at all to the database. If so, it performs a checkpoint
3150 ** operation before closing the connection. This option may be used to
@@ -3142,11 +3154,11 @@
3154 ** The second parameter is a pointer to an integer
3155 ** into which is written 0 or 1 to indicate whether checkpoints-on-close
3156 ** have been disabled - 0 if they are not disabled, 1 if they are.
3157 ** </dd>
3158 **
3159 ** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
3160 ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
3161 ** the [query planner stability guarantee] (QPSG). When the QPSG is active,
3162 ** a single SQL query statement will always use the same algorithm regardless
3163 ** of values of [bound parameters].)^ The QPSG disables some query optimizations
3164 ** that look at the values of bound parameters, which can make some queries
@@ -3158,11 +3170,11 @@
3170 ** unchanged. The second parameter is a pointer to an integer into which
3171 ** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
3172 ** following this call.
3173 ** </dd>
3174 **
3175 ** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
3176 ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
3177 ** include output for any operations performed by trigger programs. This
3178 ** option is used to set or clear (the default) a flag that governs this
3179 ** behavior. The first parameter passed to this operation is an integer -
3180 ** positive to enable output for trigger programs, or zero to disable it,
@@ -3170,11 +3182,11 @@
3182 ** The second parameter is a pointer to an integer into which is written
3183 ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
3184 ** it is not disabled, 1 if it is.
3185 ** </dd>
3186 **
3187 ** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
3188 ** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
3189 ** [VACUUM] in order to reset a database back to an empty database
3190 ** with no schema and no content. The following process works even for
3191 ** a badly corrupted database file:
3192 ** <ol>
@@ -3189,10 +3201,22 @@
3201 ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
3202 ** </ol>
3203 ** Because resetting a database is destructive and irreversible, the
3204 ** process requires the use of this obscure API and multiple steps to help
3205 ** ensure that it does not happen by accident.
3206 **
3207 ** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
3208 ** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
3209 ** "defensive" flag for a database connection. When the defensive
3210 ** flag is enabled, language features that allow ordinary SQL to
3211 ** deliberately corrupt the database file are disabled. The disabled
3212 ** features include but are not limited to the following:
3213 ** <ul>
3214 ** <li> The [PRAGMA writable_schema=ON] statement.
3215 ** <li> Writes to the [sqlite_dbpage] virtual table.
3216 ** <li> Direct writes to [shadow tables].
3217 ** </ul>
3218 ** </dd>
3219 ** </dl>
3220 */
3221 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
3222 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -3202,11 +3226,12 @@
3226 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
3227 #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
3228 #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
3229 #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
3230 #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
3231 #define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
3232 #define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
3233
3234 /*
3235 ** CAPI3REF: Enable Or Disable Extended Result Codes
3236 ** METHOD: sqlite3
3237 **
@@ -4640,13 +4665,23 @@
4665 ** be used just once or at most a few times and then destroyed using
4666 ** [sqlite3_finalize()] relatively soon. The current implementation acts
4667 ** on this hint by avoiding the use of [lookaside memory] so as not to
4668 ** deplete the limited store of lookaside memory. Future versions of
4669 ** SQLite may act on this hint differently.
4670 **
4671 ** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
4672 ** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
4673 ** representation of the SQL statement should be calculated and then
4674 ** associated with the prepared statement, which can be obtained via
4675 ** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
4676 ** normalize a SQL statement are unspecified and subject to change.
4677 ** At a minimum, literal values will be replaced with suitable
4678 ** placeholders.
4679 ** </dl>
4680 */
4681 #define SQLITE_PREPARE_PERSISTENT 0x01
4682 #define SQLITE_PREPARE_NORMALIZE 0x02
4683
4684 /*
4685 ** CAPI3REF: Compiling An SQL Statement
4686 ** KEYWORDS: {SQL statement compiler}
4687 ** METHOD: sqlite3
@@ -4800,10 +4835,15 @@
4835 ** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
4836 ** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
4837 ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
4838 ** string containing the SQL text of prepared statement P with
4839 ** [bound parameters] expanded.
4840 ** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
4841 ** string containing the normalized SQL text of prepared statement P. The
4842 ** semantics used to normalize a SQL statement are unspecified and subject
4843 ** to change. At a minimum, literal values will be replaced with suitable
4844 ** placeholders.
4845 **
4846 ** ^(For example, if a prepared statement is created using the SQL
4847 ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
4848 ** and parameter :xyz is unbound, then sqlite3_sql() will return
4849 ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -4815,18 +4855,20 @@
4855 **
4856 ** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
4857 ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
4858 ** option causes sqlite3_expanded_sql() to always return NULL.
4859 **
4860 ** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
4861 ** are managed by SQLite and are automatically freed when the prepared
4862 ** statement is finalized.
4863 ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
4864 ** is obtained from [sqlite3_malloc()] and must be free by the application
4865 ** by passing it to [sqlite3_free()].
4866 */
4867 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
4868 SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
4869 SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
4870
4871 /*
4872 ** CAPI3REF: Determine If An SQL Statement Writes The Database
4873 ** METHOD: sqlite3_stmt
4874 **
@@ -7312,10 +7354,13 @@
7354 /* The methods above are in version 1 of the sqlite_module object. Those
7355 ** below are for version 2 and greater. */
7356 int (*xSavepoint)(sqlite3_vtab *pVTab, int);
7357 int (*xRelease)(sqlite3_vtab *pVTab, int);
7358 int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
7359 /* The methods above are in versions 1 and 2 of the sqlite_module object.
7360 ** Those below are for version 3 and greater. */
7361 int (*xShadowName)(const char*);
7362 };
7363
7364 /*
7365 ** CAPI3REF: Virtual Table Indexing Information
7366 ** KEYWORDS: sqlite3_index_info
@@ -8234,10 +8279,11 @@
8279 #define SQLITE_TESTCTRL_ALWAYS 13
8280 #define SQLITE_TESTCTRL_RESERVE 14
8281 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
8282 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
8283 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
8284 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
8285 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
8286 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
8287 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
8288 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
8289 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -9646,10 +9692,11 @@
9692 ** These macros define the various options to the
9693 ** [sqlite3_vtab_config()] interface that [virtual table] implementations
9694 ** can use to customize and optimize their behavior.
9695 **
9696 ** <dl>
9697 ** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
9698 ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
9699 ** <dd>Calls of the form
9700 ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
9701 ** where X is an integer. If X is zero, then the [virtual table] whose
9702 ** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -10415,11 +10462,11 @@
10462 int iLevel; /* Level of current node or entry */
10463 int mxLevel; /* The largest iLevel value in the tree */
10464 sqlite3_int64 iRowid; /* Rowid for current entry */
10465 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
10466 int eParentWithin; /* Visibility of parent node */
10467 int eWithin; /* OUT: Visibility */
10468 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
10469 /* The following fields are only available in 3.8.11 and later */
10470 sqlite3_value **apSqlParam; /* Original SQL values of parameters */
10471 };
10472
@@ -10911,16 +10958,42 @@
10958 ** an application iterates through a changeset using an iterator created by
10959 ** this function, all changes that relate to a single table are visited
10960 ** consecutively. There is no chance that the iterator will visit a change
10961 ** the applies to table X, then one for table Y, and then later on visit
10962 ** another change for table X.
10963 **
10964 ** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
10965 ** may be modified by passing a combination of
10966 ** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
10967 **
10968 ** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
10969 ** and therefore subject to change.
10970 */
10971 SQLITE_API int sqlite3changeset_start(
10972 sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
10973 int nChangeset, /* Size of changeset blob in bytes */
10974 void *pChangeset /* Pointer to blob containing changeset */
10975 );
10976 SQLITE_API int sqlite3changeset_start_v2(
10977 sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
10978 int nChangeset, /* Size of changeset blob in bytes */
10979 void *pChangeset, /* Pointer to blob containing changeset */
10980 int flags /* SESSION_CHANGESETSTART_* flags */
10981 );
10982
10983 /*
10984 ** CAPI3REF: Flags for sqlite3changeset_start_v2
10985 **
10986 ** The following flags may passed via the 4th parameter to
10987 ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
10988 **
10989 ** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
10990 ** Invert the changeset while iterating through it. This is equivalent to
10991 ** inverting a changeset using sqlite3changeset_invert() before applying it.
10992 ** It is an error to specify this flag with a patchset.
10993 */
10994 #define SQLITE_CHANGESETSTART_INVERT 0x0002
10995
10996
10997 /*
10998 ** CAPI3REF: Advance A Changeset Iterator
10999 ** METHOD: sqlite3_changeset_iter
@@ -11571,11 +11644,11 @@
11644 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
11645 sqlite3_changeset_iter *p /* Handle describing change and conflict */
11646 ),
11647 void *pCtx, /* First argument passed to xConflict */
11648 void **ppRebase, int *pnRebase, /* OUT: Rebase data */
11649 int flags /* SESSION_CHANGESETAPPLY_* flags */
11650 );
11651
11652 /*
11653 ** CAPI3REF: Flags for sqlite3changeset_apply_v2
11654 **
@@ -11589,12 +11662,18 @@
11662 ** SAVEPOINT is committed if the changeset or patchset is successfully
11663 ** applied, or rolled back if an error occurs. Specifying this flag
11664 ** causes the sessions module to omit this savepoint. In this case, if the
11665 ** caller has an open transaction or savepoint when apply_v2() is called,
11666 ** it may revert the partially applied changeset by rolling it back.
11667 **
11668 ** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
11669 ** Invert the changeset before applying it. This is equivalent to inverting
11670 ** a changeset using sqlite3changeset_invert() before applying it. It is
11671 ** an error to specify this flag with a patchset.
11672 */
11673 #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
11674 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002
11675
11676 /*
11677 ** CAPI3REF: Constants Passed To The Conflict Handler
11678 **
11679 ** Values that may be passed as the second argument to a conflict-handler.
@@ -11983,10 +12062,16 @@
12062 );
12063 SQLITE_API int sqlite3changeset_start_strm(
12064 sqlite3_changeset_iter **pp,
12065 int (*xInput)(void *pIn, void *pData, int *pnData),
12066 void *pIn
12067 );
12068 SQLITE_API int sqlite3changeset_start_v2_strm(
12069 sqlite3_changeset_iter **pp,
12070 int (*xInput)(void *pIn, void *pData, int *pnData),
12071 void *pIn,
12072 int flags
12073 );
12074 SQLITE_API int sqlite3session_changeset_strm(
12075 sqlite3_session *pSession,
12076 int (*xOutput)(void *pOut, const void *pData, int nData),
12077 void *pOut
@@ -12010,10 +12095,49 @@
12095 void *pIn,
12096 int (*xOutput)(void *pOut, const void *pData, int nData),
12097 void *pOut
12098 );
12099
12100 /*
12101 ** CAPI3REF: Configure global parameters
12102 **
12103 ** The sqlite3session_config() interface is used to make global configuration
12104 ** changes to the sessions module in order to tune it to the specific needs
12105 ** of the application.
12106 **
12107 ** The sqlite3session_config() interface is not threadsafe. If it is invoked
12108 ** while any other thread is inside any other sessions method then the
12109 ** results are undefined. Furthermore, if it is invoked after any sessions
12110 ** related objects have been created, the results are also undefined.
12111 **
12112 ** The first argument to the sqlite3session_config() function must be one
12113 ** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
12114 ** interpretation of the (void*) value passed as the second parameter and
12115 ** the effect of calling this function depends on the value of the first
12116 ** parameter.
12117 **
12118 ** <dl>
12119 ** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
12120 ** By default, the sessions module streaming interfaces attempt to input
12121 ** and output data in approximately 1 KiB chunks. This operand may be used
12122 ** to set and query the value of this configuration setting. The pointer
12123 ** passed as the second argument must point to a value of type (int).
12124 ** If this value is greater than 0, it is used as the new streaming data
12125 ** chunk size for both input and output. Before returning, the (int) value
12126 ** pointed to by pArg is set to the final value of the streaming interface
12127 ** chunk size.
12128 ** </dl>
12129 **
12130 ** This function returns SQLITE_OK if successful, or an SQLite error code
12131 ** otherwise.
12132 */
12133 SQLITE_API int sqlite3session_config(int op, void *pArg);
12134
12135 /*
12136 ** CAPI3REF: Values for sqlite3session_config().
12137 */
12138 #define SQLITE_SESSION_CONFIG_STRMSIZE 1
12139
12140 /*
12141 ** Make sure we can call this stuff from C++.
12142 */
12143 #if 0
@@ -15275,22 +15399,21 @@
15399 SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
15400 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
15401 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
15402 SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
15403 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
 
 
 
15404 # ifdef SQLITE_ENABLE_SNAPSHOT
15405 SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
15406 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
15407 SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
15408 SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
15409 SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
15410 # endif
15411 #endif
15412
15413 #ifdef SQLITE_DIRECT_OVERFLOW_READ
15414 SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
15415 #endif
15416
15417 #ifdef SQLITE_ENABLE_ZIPVFS
15418 SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
15419 #endif
@@ -15530,10 +15653,14 @@
15653 SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
15654 SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
15655
15656 /* Number of dirty pages as a percentage of the configured cache size */
15657 SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
15658
15659 #ifdef SQLITE_DIRECT_OVERFLOW_READ
15660 SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
15661 #endif
15662
15663 #endif /* _PCACHE_H_ */
15664
15665 /************** End of pcache.h **********************************************/
15666 /************** Continuing where we left off in sqliteInt.h ******************/
@@ -16036,16 +16163,18 @@
16163 /*
16164 ** A hash table for built-in function definitions. (Application-defined
16165 ** functions use a regular table table from hash.h.)
16166 **
16167 ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
16168 ** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH()
16169 ** macro to compute a hash on the function name.
16170 */
16171 #define SQLITE_FUNC_HASH_SZ 23
16172 struct FuncDefHash {
16173 FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
16174 };
16175 #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
16176
16177 #ifdef SQLITE_USER_AUTHENTICATION
16178 /*
16179 ** Information held in the "sqlite3" database connection object and used
16180 ** to manage user authentication.
@@ -16102,11 +16231,11 @@
16231 CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
16232 sqlite3_mutex *mutex; /* Connection mutex */
16233 Db *aDb; /* All backends */
16234 int nDb; /* Number of backends currently in use */
16235 u32 mDbFlags; /* flags recording internal state */
16236 u64 flags; /* flags settable by pragmas. See below */
16237 i64 lastRowid; /* ROWID of most recent insert (see above) */
16238 i64 szMmap; /* Default mmap_size setting */
16239 u32 nSchemaLock; /* Do not reset the schema when non-zero */
16240 unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
16241 int errCode; /* Most recent error code (SQLITE_*) */
@@ -16268,18 +16397,21 @@
16397 #define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
16398 #define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
16399 #define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
16400 #define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
16401 #define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
16402 #define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
16403 #define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
16404
16405 /* Flags used only if debugging */
16406 #define HI(X) ((u64)(X)<<32)
16407 #ifdef SQLITE_DEBUG
16408 #define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
16409 #define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
16410 #define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
16411 #define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
16412 #define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
16413 #endif
16414
16415 /*
16416 ** Allowed values for sqlite3.mDbFlags
16417 */
@@ -16409,12 +16541,13 @@
16541 #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
16542 #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
16543 ** single query - might change over time */
16544 #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
16545 #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
16546 #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
16547 #define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
16548 #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
16549
16550 /*
16551 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
16552 ** used to create the initializers for the FuncDef structures.
16553 **
@@ -16486,14 +16619,17 @@
16619 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
16620 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
16621 #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
16622 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
16623 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
 
16624 #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
16625 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
16626 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
16627 #define INTERNAL_FUNCTION(zName, nArg, xFunc) \
16628 {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
16629 0, 0, xFunc, 0, 0, 0, #zName, {0} }
16630
16631
16632 /*
16633 ** All current savepoints are stored in a linked list starting at
16634 ** sqlite3.pSavepoint. The first element in the list is the most recently
16635 ** opened savepoint. Savepoints are added to the list by the vdbe
@@ -16674,10 +16810,13 @@
16810 ** by an instance of the following structure.
16811 */
16812 struct Table {
16813 char *zName; /* Name of the table or view */
16814 Column *aCol; /* Information about each column */
16815 #ifdef SQLITE_ENABLE_NORMALIZE
16816 Hash *pColHash; /* All columns indexed by name */
16817 #endif
16818 Index *pIndex; /* List of SQL indexes on this table. */
16819 Select *pSelect; /* NULL for tables. Points to definition if a view. */
16820 FKey *pFKey; /* Linked list of all foreign keys in this table */
16821 char *zColAff; /* String defining the affinity of each column */
16822 ExprList *pCheck; /* All CHECK constraints */
@@ -16724,10 +16863,11 @@
16863 #define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
16864 #define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
16865 #define TF_StatsUsed 0x0100 /* Query planner decisions affected by
16866 ** Index.aiRowLogEst[] values */
16867 #define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
16868 #define TF_Shadow 0x0400 /* True for a shadow table */
16869
16870 /*
16871 ** Test to see whether or not a table is a virtual table. This is
16872 ** done as a macro so that it will be optimized out when virtual
16873 ** table support is omitted from the build.
@@ -17010,10 +17150,16 @@
17150 tRowcnt *anEq; /* Est. number of rows where the key equals this sample */
17151 tRowcnt *anLt; /* Est. number of rows where key is less than this sample */
17152 tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
17153 };
17154
17155 /*
17156 ** Possible values to use within the flags argument to sqlite3GetToken().
17157 */
17158 #define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */
17159 #define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */
17160
17161 /*
17162 ** Each token coming out of the lexer is an instance of
17163 ** this structure. Tokens are also used as part of an expression.
17164 **
17165 ** The memory that "z" points to is owned by other objects. Take care
@@ -17191,15 +17337,15 @@
17337 i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
17338 u8 op2; /* TK_REGISTER: original value of Expr.op
17339 ** TK_COLUMN: the value of p5 for OP_Column
17340 ** TK_AGG_FUNCTION: nesting depth */
17341 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
17342 union {
17343 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
17344 ** for a column of an index on an expression */
17345 Window *pWin; /* TK_FUNCTION: Window definition for the func */
17346 } y;
17347 };
17348
17349 /*
17350 ** The following are the meanings of bits in the Expr.flags field.
17351 */
@@ -17225,10 +17371,11 @@
17371 #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
17372 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
17373 #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
17374 #define EP_Alias 0x400000 /* Is an alias for a result set column */
17375 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
17376 #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
17377
17378 /*
17379 ** The EP_Propagate mask is a set of properties that automatically propagate
17380 ** upwards into parent nodes.
17381 */
@@ -17910,10 +18057,11 @@
18057 ** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
18058 ** OPFLAG_AUXDELETE == BTREE_AUXDELETE
18059 */
18060 #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
18061 /* Also used in P2 (not P5) of OP_Delete */
18062 #define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */
18063 #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
18064 #define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
18065 #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
18066 #define OPFLAG_APPEND 0x08 /* This is likely to be an append */
18067 #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
@@ -18128,10 +18276,11 @@
18276 #endif
18277 #ifndef SQLITE_UNTESTABLE
18278 int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
18279 #endif
18280 int bLocaltimeFault; /* True to fail localtime() calls */
18281 int bInternalFunctions; /* Internal SQL functions are visible */
18282 int iOnceResetThreshold; /* When to reset OP_Once counters */
18283 u32 szSorterRef; /* Min size in bytes to use sorter-refs */
18284 };
18285
18286 /*
@@ -18381,10 +18530,11 @@
18530 /*
18531 ** Internal function prototypes
18532 */
18533 SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
18534 SQLITE_PRIVATE int sqlite3Strlen30(const char*);
18535 #define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
18536 SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
18537 #define sqlite3StrNICmp sqlite3_strnicmp
18538
18539 SQLITE_PRIVATE int sqlite3MallocInit(void);
18540 SQLITE_PRIVATE void sqlite3MallocEnd(void);
@@ -18497,10 +18647,11 @@
18647
18648 #if defined(SQLITE_DEBUG)
18649 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
18650 SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
18651 SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
18652 SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
18653 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
18654 SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
18655 #ifndef SQLITE_OMIT_WINDOWFUNC
18656 SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
18657 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
@@ -18729,15 +18880,19 @@
18880 #endif
18881 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
18882 SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
18883 SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
18884 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
18885 #ifdef SQLITE_ENABLE_NORMALIZE
18886 SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int);
18887 #endif
18888 SQLITE_PRIVATE void sqlite3GenerateRowDelete(
18889 Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
18890 SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
18891 SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
18892 SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
18893 SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
18894 SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
18895 u8,u8,int,int*,int*,Upsert*);
18896 #ifdef SQLITE_ENABLE_NULL_TRIM
18897 SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
18898 #else
@@ -18754,10 +18909,13 @@
18909 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
18910 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
18911 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
18912 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
18913 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
18914 #ifdef SQLITE_ENABLE_NORMALIZE
18915 SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int);
18916 #endif
18917 SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
18918 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
18919 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
18920 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
18921 SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
@@ -18911,10 +19069,11 @@
19069 SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
19070 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
19071 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
19072 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
19073 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
19074 SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*);
19075 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
19076 SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
19077 SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
19078 SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
19079 SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64);
@@ -18957,10 +19116,13 @@
19116 SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
19117 SQLITE_PRIVATE void sqlite3AlterFunctions(void);
19118 SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
19119 SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
19120 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
19121 #ifdef SQLITE_ENABLE_NORMALIZE
19122 SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
19123 #endif
19124 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
19125 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
19126 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
19127 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
19128 SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
@@ -19114,10 +19276,13 @@
19276 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
19277 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
19278 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
19279 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
19280 SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
19281 #ifdef SQLITE_ENABLE_NORMALIZE
19282 SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8);
19283 #endif
19284 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
19285 SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
19286 SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
19287 SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
19288 SQLITE_PRIVATE const char *sqlite3JournalModename(int);
@@ -19575,10 +19740,11 @@
19740 #endif
19741 #ifndef SQLITE_UNTESTABLE
19742 0, /* xTestCallback */
19743 #endif
19744 0, /* bLocaltimeFault */
19745 0, /* bInternalFunctions */
19746 0x7ffffffe, /* iOnceResetThreshold */
19747 SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
19748 };
19749
19750 /*
@@ -20066,10 +20232,13 @@
20232 bft bIsReader:1; /* True for statements that read */
20233 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
20234 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
20235 u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
20236 char *zSql; /* Text of the SQL statement that generated this */
20237 #ifdef SQLITE_ENABLE_NORMALIZE
20238 char *zNormSql; /* Normalization of the associated SQL statement */
20239 #endif
20240 void *pFree; /* Free this when deleting the vdbe */
20241 VdbeFrame *pFrame; /* Parent frame */
20242 VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
20243 int nFrame; /* Number of frames in pFrame list */
20244 u32 expmask; /* Binding to these vars invalidates VM */
@@ -20128,11 +20297,13 @@
20297
20298 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
20299 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
20300 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
20301 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
20302 #ifndef SQLITE_OMIT_EXPLAIN
20303 SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
20304 #endif
20305 SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
20306 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
20307 SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
20308 SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
20309 SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
@@ -20167,11 +20338,13 @@
20338 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
20339 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
20340 #ifndef SQLITE_OMIT_WINDOWFUNC
20341 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
20342 #endif
20343 #ifndef SQLITE_OMIT_EXPLAIN
20344 SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
20345 #endif
20346 SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
20347 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
20348 SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
20349 #ifdef SQLITE_DEBUG
20350 SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
@@ -28294,10 +28467,46 @@
28467 }
28468 sqlite3TreeViewPop(pView);
28469 }
28470 }
28471
28472 /*
28473 ** Generate a human-readable description of a SrcList object.
28474 */
28475 SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
28476 int i;
28477 for(i=0; i<pSrc->nSrc; i++){
28478 const struct SrcList_item *pItem = &pSrc->a[i];
28479 StrAccum x;
28480 char zLine[100];
28481 sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
28482 sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
28483 if( pItem->zDatabase ){
28484 sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
28485 }else if( pItem->zName ){
28486 sqlite3_str_appendf(&x, " %s", pItem->zName);
28487 }
28488 if( pItem->pTab ){
28489 sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
28490 }
28491 if( pItem->zAlias ){
28492 sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
28493 }
28494 if( pItem->fg.jointype & JT_LEFT ){
28495 sqlite3_str_appendf(&x, " LEFT-JOIN");
28496 }
28497 sqlite3StrAccumFinish(&x);
28498 sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
28499 if( pItem->pSelect ){
28500 sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
28501 }
28502 if( pItem->fg.isTabFunc ){
28503 sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
28504 }
28505 sqlite3TreeViewPop(pView);
28506 }
28507 }
28508
28509 /*
28510 ** Generate a human-readable description of a Select object.
28511 */
28512 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
@@ -28348,43 +28557,13 @@
28557 }
28558 sqlite3TreeViewPop(pView);
28559 }
28560 #endif
28561 if( p->pSrc && p->pSrc->nSrc ){
 
28562 pView = sqlite3TreeViewPush(pView, (n--)>0);
28563 sqlite3TreeViewLine(pView, "FROM");
28564 sqlite3TreeViewSrcList(pView, p->pSrc);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28565 sqlite3TreeViewPop(pView);
28566 }
28567 if( p->pWhere ){
28568 sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
28569 sqlite3TreeViewExpr(pView, p->pWhere, 0);
@@ -28670,11 +28849,11 @@
28849 pFarg = 0;
28850 pWin = 0;
28851 }else{
28852 pFarg = pExpr->x.pList;
28853 #ifndef SQLITE_OMIT_WINDOWFUNC
28854 pWin = pExpr->y.pWin;
28855 #else
28856 pWin = 0;
28857 #endif
28858 }
28859 if( pExpr->op==TK_AGG_FUNCTION ){
@@ -31498,10 +31677,24 @@
31677 h += sqlite3UpperToLower[c];
31678 h *= 0x9e3779b1;
31679 }
31680 return h;
31681 }
31682 #ifdef SQLITE_ENABLE_NORMALIZE
31683 static unsigned int strHashN(const char *z, int n){
31684 unsigned int h = 0;
31685 int i;
31686 for(i=0; i<n; i++){
31687 /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
31688 ** 0x9e3779b1 is 2654435761 which is the closest prime number to
31689 ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
31690 h += sqlite3UpperToLower[z[i]];
31691 h *= 0x9e3779b1;
31692 }
31693 return h;
31694 }
31695 #endif /* SQLITE_ENABLE_NORMALIZE */
31696
31697
31698 /* Link pNew element into the hash table pH. If pEntry!=0 then also
31699 ** insert pNew into the pEntry hash bucket.
31700 */
@@ -31609,10 +31802,44 @@
31802 }
31803 elem = elem->next;
31804 }
31805 return &nullElement;
31806 }
31807 #ifdef SQLITE_ENABLE_NORMALIZE
31808 static HashElem *findElementWithHashN(
31809 const Hash *pH, /* The pH to be searched */
31810 const char *pKey, /* The key we are searching for */
31811 int nKey, /* Number of key bytes to use */
31812 unsigned int *pHash /* Write the hash value here */
31813 ){
31814 HashElem *elem; /* Used to loop thru the element list */
31815 int count; /* Number of elements left to test */
31816 unsigned int h; /* The computed hash */
31817 static HashElem nullElement = { 0, 0, 0, 0 };
31818
31819 if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
31820 struct _ht *pEntry;
31821 h = strHashN(pKey, nKey) % pH->htsize;
31822 pEntry = &pH->ht[h];
31823 elem = pEntry->chain;
31824 count = pEntry->count;
31825 }else{
31826 h = 0;
31827 elem = pH->first;
31828 count = pH->count;
31829 }
31830 if( pHash ) *pHash = h;
31831 while( count-- ){
31832 assert( elem!=0 );
31833 if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
31834 return elem;
31835 }
31836 elem = elem->next;
31837 }
31838 return &nullElement;
31839 }
31840 #endif /* SQLITE_ENABLE_NORMALIZE */
31841
31842 /* Remove a single entry from the hash table given a pointer to that
31843 ** element and a hash on the element's key.
31844 */
31845 static void removeElementGivenHash(
@@ -31653,10 +31880,18 @@
31880 SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
31881 assert( pH!=0 );
31882 assert( pKey!=0 );
31883 return findElementWithHash(pH, pKey, 0)->data;
31884 }
31885 #ifdef SQLITE_ENABLE_NORMALIZE
31886 SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
31887 assert( pH!=0 );
31888 assert( pKey!=0 );
31889 assert( nKey>=0 );
31890 return findElementWithHashN(pH, pKey, nKey, 0)->data;
31891 }
31892 #endif /* SQLITE_ENABLE_NORMALIZE */
31893
31894 /* Insert an element into the hash table pH. The key is pKey
31895 ** and the data is "data".
31896 **
31897 ** If no element exists with a matching key, then a new
@@ -32035,16 +32270,14 @@
32270 ** Allowed values of unixFile.fsFlags
32271 */
32272 #define SQLITE_FSFLAGS_IS_MSDOS 0x1
32273
32274 /*
32275 ** If we are to be thread-safe, include the pthreads header.
 
32276 */
32277 #if SQLITE_THREADSAFE
32278 /* # include <pthread.h> */
 
32279 #endif
32280
32281 /*
32282 ** Default permissions when creating a new file
32283 */
@@ -33216,12 +33449,11 @@
33449 #endif
33450 };
33451
33452 /*
33453 ** An instance of the following structure is allocated for each open
33454 ** inode.
 
33455 **
33456 ** A single inode can have multiple file descriptors, so each unixFile
33457 ** structure contains a pointer to an instance of this object and this
33458 ** object keeps a count of the number of unixFile pointing to it.
33459 **
@@ -33263,17 +33495,20 @@
33495 #endif
33496 };
33497
33498 /*
33499 ** A lists of all unixInodeInfo objects.
33500 **
33501 ** Must hold unixBigLock in order to read or write this variable.
33502 */
33503 static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
33504
33505 #ifdef SQLITE_DEBUG
33506 /*
33507 ** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
33508 ** This routine is used only within assert() to help verify correct mutex
33509 ** usage.
33510 */
33511 int unixFileMutexHeld(unixFile *pFile){
33512 assert( pFile->pInode );
33513 return sqlite3_mutex_held(pFile->pInode->pLockMutex);
33514 }
@@ -33397,12 +33632,12 @@
33632 }
33633
33634 /*
33635 ** Release a unixInodeInfo structure previously allocated by findInodeInfo().
33636 **
33637 ** The global mutex must be held when this routine is called, but the mutex
33638 ** on the inode being deleted must NOT be held.
33639 */
33640 static void releaseInodeInfo(unixFile *pFile){
33641 unixInodeInfo *pInode = pFile->pInode;
33642 assert( unixMutexHeld() );
33643 assert( unixFileMutexNotheld(pFile) );
@@ -33433,12 +33668,11 @@
33668 /*
33669 ** Given a file descriptor, locate the unixInodeInfo object that
33670 ** describes that file descriptor. Create a new one if necessary. The
33671 ** return value might be uninitialized if an error occurs.
33672 **
33673 ** The global mutex must held when calling this routine.
 
33674 **
33675 ** Return an appropriate error code.
33676 */
33677 static int findInodeInfo(
33678 unixFile *pFile, /* Unix file with file desc used in the key */
@@ -33495,10 +33729,11 @@
33729 #if OS_VXWORKS
33730 fileId.pId = pFile->pId;
33731 #else
33732 fileId.ino = (u64)statbuf.st_ino;
33733 #endif
33734 assert( unixMutexHeld() );
33735 pInode = inodeList;
33736 while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
33737 pInode = pInode->pNext;
33738 }
33739 if( pInode==0 ){
@@ -33514,10 +33749,11 @@
33749 sqlite3_free(pInode);
33750 return SQLITE_NOMEM_BKPT;
33751 }
33752 }
33753 pInode->nRef = 1;
33754 assert( unixMutexHeld() );
33755 pInode->pNext = inodeList;
33756 pInode->pPrev = 0;
33757 if( inodeList ) inodeList->pPrev = pInode;
33758 inodeList = pInode;
33759 }else{
@@ -36311,22 +36547,22 @@
36547 **
36548 ** nRef
36549 **
36550 ** The following fields are read-only after the object is created:
36551 **
36552 ** hShm
36553 ** zFilename
36554 **
36555 ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
36556 ** unixMutexHeld() is true when reading or writing any other field
36557 ** in this structure.
36558 */
36559 struct unixShmNode {
36560 unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
36561 sqlite3_mutex *pShmMutex; /* Mutex to access this object */
36562 char *zFilename; /* Name of the mmapped file */
36563 int hShm; /* Open file descriptor */
36564 int szRegion; /* Size of shared-memory regions */
36565 u16 nRegion; /* Size of array apRegion */
36566 u8 isReadonly; /* True if read-only */
36567 u8 isUnlocked; /* True if no DMS lock held */
36568 char **apRegion; /* Array of mapped shared-memory regions */
@@ -36344,20 +36580,20 @@
36580 ** open shared memory connection.
36581 **
36582 ** The following fields are initialized when this object is created and
36583 ** are read-only thereafter:
36584 **
36585 ** unixShm.pShmNode
36586 ** unixShm.id
36587 **
36588 ** All other fields are read/write. The unixShm.pShmNode->pShmMutex must
36589 ** be held while accessing any read/write fields.
36590 */
36591 struct unixShm {
36592 unixShmNode *pShmNode; /* The underlying unixShmNode object */
36593 unixShm *pNext; /* Next unixShm with the same unixShmNode */
36594 u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */
36595 u8 id; /* Id of this connection within its unixShmNode */
36596 u16 sharedMask; /* Mask of shared locks held */
36597 u16 exclMask; /* Mask of exclusive locks held */
36598 };
36599
@@ -36383,25 +36619,26 @@
36619 struct flock f; /* The posix advisory locking structure */
36620 int rc = SQLITE_OK; /* Result code form fcntl() */
36621
36622 /* Access to the unixShmNode object is serialized by the caller */
36623 pShmNode = pFile->pInode->pShmNode;
36624 assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
36625 assert( pShmNode->nRef>0 || unixMutexHeld() );
36626
36627 /* Shared locks never span more than one byte */
36628 assert( n==1 || lockType!=F_RDLCK );
36629
36630 /* Locks are within range */
36631 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
36632
36633 if( pShmNode->hShm>=0 ){
36634 /* Initialize the locking parameters */
36635 f.l_type = lockType;
36636 f.l_whence = SEEK_SET;
36637 f.l_start = ofst;
36638 f.l_len = n;
36639 rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
36640 rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
36641 }
36642
36643 /* Update the global lock state and do debug tracing */
36644 #ifdef SQLITE_DEBUG
@@ -36469,22 +36706,22 @@
36706 assert( unixMutexHeld() );
36707 if( p && ALWAYS(p->nRef==0) ){
36708 int nShmPerMap = unixShmRegionPerMap();
36709 int i;
36710 assert( p->pInode==pFd->pInode );
36711 sqlite3_mutex_free(p->pShmMutex);
36712 for(i=0; i<p->nRegion; i+=nShmPerMap){
36713 if( p->hShm>=0 ){
36714 osMunmap(p->apRegion[i], p->szRegion);
36715 }else{
36716 sqlite3_free(p->apRegion[i]);
36717 }
36718 }
36719 sqlite3_free(p->apRegion);
36720 if( p->hShm>=0 ){
36721 robust_close(pFd, p->hShm, __LINE__);
36722 p->hShm = -1;
36723 }
36724 p->pInode->pShmNode = 0;
36725 sqlite3_free(p);
36726 }
36727 }
@@ -36522,19 +36759,24 @@
36759 ** system crash, the database itself may also become corrupt. */
36760 lock.l_whence = SEEK_SET;
36761 lock.l_start = UNIX_SHM_DMS;
36762 lock.l_len = 1;
36763 lock.l_type = F_WRLCK;
36764 if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
36765 rc = SQLITE_IOERR_LOCK;
36766 }else if( lock.l_type==F_UNLCK ){
36767 if( pShmNode->isReadonly ){
36768 pShmNode->isUnlocked = 1;
36769 rc = SQLITE_READONLY_CANTINIT;
36770 }else{
36771 rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
36772 /* The first connection to attach must truncate the -shm file. We
36773 ** truncate to 3 bytes (an arbitrary small number, less than the
36774 ** -shm header size) rather than 0 as a system debugging aid, to
36775 ** help detect if a -shm file truncation is legitimate or is the work
36776 ** or a rogue process. */
36777 if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
36778 rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
36779 }
36780 }
36781 }else if( lock.l_type==F_WRLCK ){
36782 rc = SQLITE_BUSY;
@@ -36636,28 +36878,28 @@
36878 (u32)sStat.st_ino, (u32)sStat.st_dev);
36879 #else
36880 sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
36881 sqlite3FileSuffix3(pDbFd->zPath, zShm);
36882 #endif
36883 pShmNode->hShm = -1;
36884 pDbFd->pInode->pShmNode = pShmNode;
36885 pShmNode->pInode = pDbFd->pInode;
36886 if( sqlite3GlobalConfig.bCoreMutex ){
36887 pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
36888 if( pShmNode->pShmMutex==0 ){
36889 rc = SQLITE_NOMEM_BKPT;
36890 goto shm_open_err;
36891 }
36892 }
36893
36894 if( pInode->bProcessLock==0 ){
36895 if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
36896 pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
36897 }
36898 if( pShmNode->hShm<0 ){
36899 pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
36900 if( pShmNode->hShm<0 ){
36901 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
36902 goto shm_open_err;
36903 }
36904 pShmNode->isReadonly = 1;
36905 }
@@ -36664,11 +36906,11 @@
36906
36907 /* If this process is running as root, make sure that the SHM file
36908 ** is owned by the same user that owns the original database. Otherwise,
36909 ** the original owner will not be able to connect.
36910 */
36911 robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
36912
36913 rc = unixLockSharedMemory(pDbFd, pShmNode);
36914 if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
36915 }
36916 }
@@ -36684,17 +36926,17 @@
36926
36927 /* The reference count on pShmNode has already been incremented under
36928 ** the cover of the unixEnterMutex() mutex and the pointer from the
36929 ** new (struct unixShm) object to the pShmNode has been set. All that is
36930 ** left to do is to link the new object into the linked list starting
36931 ** at pShmNode->pFirst. This must be done while holding the
36932 ** pShmNode->pShmMutex.
36933 */
36934 sqlite3_mutex_enter(pShmNode->pShmMutex);
36935 p->pNext = pShmNode->pFirst;
36936 pShmNode->pFirst = p;
36937 sqlite3_mutex_leave(pShmNode->pShmMutex);
36938 return rc;
36939
36940 /* Jump here on any error */
36941 shm_open_err:
36942 unixShmPurge(pDbFd); /* This call frees pShmNode if required */
@@ -36742,20 +36984,20 @@
36984 if( rc!=SQLITE_OK ) return rc;
36985 }
36986
36987 p = pDbFd->pShm;
36988 pShmNode = p->pShmNode;
36989 sqlite3_mutex_enter(pShmNode->pShmMutex);
36990 if( pShmNode->isUnlocked ){
36991 rc = unixLockSharedMemory(pDbFd, pShmNode);
36992 if( rc!=SQLITE_OK ) goto shmpage_out;
36993 pShmNode->isUnlocked = 0;
36994 }
36995 assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
36996 assert( pShmNode->pInode==pDbFd->pInode );
36997 assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
36998 assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
36999
37000 /* Minimum number of regions required to be mapped. */
37001 nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
37002
37003 if( pShmNode->nRegion<nReqRegion ){
@@ -36763,16 +37005,16 @@
37005 int nByte = nReqRegion*szRegion; /* Minimum required file size */
37006 struct stat sStat; /* Used by fstat() */
37007
37008 pShmNode->szRegion = szRegion;
37009
37010 if( pShmNode->hShm>=0 ){
37011 /* The requested region is not mapped into this processes address space.
37012 ** Check to see if it has been allocated (i.e. if the wal-index file is
37013 ** large enough to contain the requested region).
37014 */
37015 if( osFstat(pShmNode->hShm, &sStat) ){
37016 rc = SQLITE_IOERR_SHMSIZE;
37017 goto shmpage_out;
37018 }
37019
37020 if( sStat.st_size<nByte ){
@@ -36796,11 +37038,11 @@
37038
37039 /* Write to the last byte of each newly allocated or extended page */
37040 assert( (nByte % pgsz)==0 );
37041 for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
37042 int x = 0;
37043 if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
37044 const char *zFile = pShmNode->zFilename;
37045 rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
37046 goto shmpage_out;
37047 }
37048 }
@@ -36819,26 +37061,26 @@
37061 pShmNode->apRegion = apNew;
37062 while( pShmNode->nRegion<nReqRegion ){
37063 int nMap = szRegion*nShmPerMap;
37064 int i;
37065 void *pMem;
37066 if( pShmNode->hShm>=0 ){
37067 pMem = osMmap(0, nMap,
37068 pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
37069 MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
37070 );
37071 if( pMem==MAP_FAILED ){
37072 rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
37073 goto shmpage_out;
37074 }
37075 }else{
37076 pMem = sqlite3_malloc64(nMap);
37077 if( pMem==0 ){
37078 rc = SQLITE_NOMEM_BKPT;
37079 goto shmpage_out;
37080 }
37081 memset(pMem, 0, nMap);
37082 }
37083
37084 for(i=0; i<nShmPerMap; i++){
37085 pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
37086 }
@@ -36851,11 +37093,11 @@
37093 *pp = pShmNode->apRegion[iRegion];
37094 }else{
37095 *pp = 0;
37096 }
37097 if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
37098 sqlite3_mutex_leave(pShmNode->pShmMutex);
37099 return rc;
37100 }
37101
37102 /*
37103 ** Change the lock state for a shared-memory segment.
@@ -36885,16 +37127,16 @@
37127 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
37128 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
37129 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
37130 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
37131 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
37132 assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
37133 assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
37134
37135 mask = (1<<(ofst+n)) - (1<<ofst);
37136 assert( n>1 || mask==(1<<ofst) );
37137 sqlite3_mutex_enter(pShmNode->pShmMutex);
37138 if( flags & SQLITE_SHM_UNLOCK ){
37139 u16 allMask = 0; /* Mask of locks held by siblings */
37140
37141 /* See if any siblings hold this same lock */
37142 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
@@ -36963,11 +37205,11 @@
37205 assert( (p->sharedMask & mask)==0 );
37206 p->exclMask |= mask;
37207 }
37208 }
37209 }
37210 sqlite3_mutex_leave(pShmNode->pShmMutex);
37211 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
37212 p->id, osGetpid(0), p->sharedMask, p->exclMask));
37213 return rc;
37214 }
37215
@@ -37013,27 +37255,27 @@
37255 assert( pShmNode==pDbFd->pInode->pShmNode );
37256 assert( pShmNode->pInode==pDbFd->pInode );
37257
37258 /* Remove connection p from the set of connections associated
37259 ** with pShmNode */
37260 sqlite3_mutex_enter(pShmNode->pShmMutex);
37261 for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
37262 *pp = p->pNext;
37263
37264 /* Free the connection p */
37265 sqlite3_free(p);
37266 pDbFd->pShm = 0;
37267 sqlite3_mutex_leave(pShmNode->pShmMutex);
37268
37269 /* If pShmNode->nRef has reached 0, then close the underlying
37270 ** shared-memory file, too */
37271 assert( unixFileMutexNotheld(pDbFd) );
37272 unixEnterMutex();
37273 assert( pShmNode->nRef>0 );
37274 pShmNode->nRef--;
37275 if( pShmNode->nRef==0 ){
37276 if( deleteFlag && pShmNode->hShm>=0 ){
37277 osUnlink(pShmNode->zFilename);
37278 }
37279 unixShmPurge(pDbFd);
37280 }
37281 unixLeaveMutex();
@@ -40447,12 +40689,11 @@
40689 #endif
40690 #if SQLITE_MAX_MMAP_SIZE>0
40691 int nFetchOut; /* Number of outstanding xFetch references */
40692 HANDLE hMap; /* Handle for accessing memory mapping */
40693 void *pMapRegion; /* Area memory mapped */
40694 sqlite3_int64 mmapSize; /* Size of mapped region */
 
40695 sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
40696 #endif
40697 };
40698
40699 /*
@@ -43069,10 +43310,30 @@
43310 winFile *pFile = (winFile*)id; /* File handle object */
43311 int rc = SQLITE_OK; /* Return code for this function */
43312 DWORD lastErrno;
43313 #if SQLITE_MAX_MMAP_SIZE>0
43314 sqlite3_int64 oldMmapSize;
43315 if( pFile->nFetchOut>0 ){
43316 /* File truncation is a no-op if there are outstanding memory mapped
43317 ** pages. This is because truncating the file means temporarily unmapping
43318 ** the file, and that might delete memory out from under existing cursors.
43319 **
43320 ** This can result in incremental vacuum not truncating the file,
43321 ** if there is an active read cursor when the incremental vacuum occurs.
43322 ** No real harm comes of this - the database file is not corrupted,
43323 ** though some folks might complain that the file is bigger than it
43324 ** needs to be.
43325 **
43326 ** The only feasible work-around is to defer the truncation until after
43327 ** all references to memory-mapped content are closed. That is doable,
43328 ** but involves adding a few branches in the common write code path which
43329 ** could slow down normal operations slightly. Hence, we have decided for
43330 ** now to simply make trancations a no-op if there are pending reads. We
43331 ** can maybe revisit this decision in the future.
43332 */
43333 return SQLITE_OK;
43334 }
43335 #endif
43336
43337 assert( pFile );
43338 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
43339 OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
@@ -44497,13 +44758,13 @@
44758 */
44759 #if SQLITE_MAX_MMAP_SIZE>0
44760 static int winUnmapfile(winFile *pFile){
44761 assert( pFile!=0 );
44762 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
44763 "mmapSize=%lld, mmapSizeMax=%lld\n",
44764 osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
44765 pFile->mmapSize, pFile->mmapSizeMax));
44766 if( pFile->pMapRegion ){
44767 if( !osUnmapViewOfFile(pFile->pMapRegion) ){
44768 pFile->lastErrno = osGetLastError();
44769 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
44770 "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
@@ -44511,11 +44772,10 @@
44772 return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
44773 "winUnmapfile1", pFile->zPath);
44774 }
44775 pFile->pMapRegion = 0;
44776 pFile->mmapSize = 0;
 
44777 }
44778 if( pFile->hMap!=NULL ){
44779 if( !osCloseHandle(pFile->hMap) ){
44780 pFile->lastErrno = osGetLastError();
44781 OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
@@ -44622,11 +44882,10 @@
44882 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
44883 return SQLITE_OK;
44884 }
44885 pFd->pMapRegion = pNew;
44886 pFd->mmapSize = nMap;
 
44887 }
44888
44889 OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
44890 osGetCurrentProcessId(), pFd));
44891 return SQLITE_OK;
@@ -45424,11 +45683,10 @@
45683 pFile->zPath = zName;
45684 #if SQLITE_MAX_MMAP_SIZE>0
45685 pFile->hMap = NULL;
45686 pFile->pMapRegion = 0;
45687 pFile->mmapSize = 0;
 
45688 pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
45689 #endif
45690
45691 OpenCounter(+1);
45692 return rc;
@@ -47321,11 +47579,11 @@
47579 ** pDirtyTail to the last (oldest).
47580 **
47581 ** The PCache.pSynced variable is used to optimize searching for a dirty
47582 ** page to eject from the cache mid-transaction. It is better to eject
47583 ** a page that does not require a journal sync than one that does.
47584 ** Therefore, pSynced is maintained so that it *almost* always points
47585 ** to either the oldest page in the pDirty/pDirtyTail list that has a
47586 ** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
47587 ** (so that the right page to eject can be found by following pDirtyPrev
47588 ** pointers).
47589 */
@@ -48144,10 +48402,19 @@
48402 int nDirty = 0;
48403 int nCache = numberOfCachePages(pCache);
48404 for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
48405 return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
48406 }
48407
48408 #ifdef SQLITE_DIRECT_OVERFLOW_READ
48409 /*
48410 ** Return true if there are one or more dirty pages in the cache. Else false.
48411 */
48412 SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){
48413 return (pCache->pDirty!=0);
48414 }
48415 #endif
48416
48417 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
48418 /*
48419 ** For all dirty pages currently in the cache, invoke the specified
48420 ** callback. This is only used if the SQLITE_CHECK_PAGES macro is
@@ -48268,11 +48535,12 @@
48535 PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
48536 PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
48537 };
48538
48539 /*
48540 ** A page is pinned if it is not on the LRU list. To be "pinned" means
48541 ** that the page is in active use and must not be deallocated.
48542 */
48543 #define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
48544 #define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
48545
48546 /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
@@ -50908,23 +51176,34 @@
51176 **
51177 ** if( pPager->jfd->pMethods ){ ...
51178 */
51179 #define isOpen(pFd) ((pFd)->pMethods!=0)
51180
51181 #ifdef SQLITE_DIRECT_OVERFLOW_READ
51182 /*
51183 ** Return true if page pgno can be read directly from the database file
51184 ** by the b-tree layer. This is the case if:
51185 **
51186 ** * the database file is open,
51187 ** * there are no dirty pages in the cache, and
51188 ** * the desired page is not currently in the wal file.
51189 */
51190 SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
51191 if( pPager->fd->pMethods==0 ) return 0;
51192 if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
51193 #ifndef SQLITE_OMIT_WAL
51194 if( pPager->pWal ){
51195 u32 iRead = 0;
51196 int rc;
51197 rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
51198 return (rc==SQLITE_OK && iRead==0);
51199 }
51200 #endif
51201 return 1;
51202 }
51203 #endif
51204
51205 #ifndef SQLITE_OMIT_WAL
51206 # define pagerUseWal(x) ((x)->pWal!=0)
51207 #else
51208 # define pagerUseWal(x) 0
51209 # define pagerRollbackWal(x) 0
@@ -57104,11 +57383,15 @@
57383 void *(*xCodec)(void*,void*,Pgno,int),
57384 void (*xCodecSizeChng)(void*,int,int),
57385 void (*xCodecFree)(void*),
57386 void *pCodec
57387 ){
57388 if( pPager->xCodecFree ){
57389 pPager->xCodecFree(pPager->pCodec);
57390 }else{
57391 pager_reset(pPager);
57392 }
57393 pPager->xCodec = pPager->memDb ? 0 : xCodec;
57394 pPager->xCodecSizeChng = xCodecSizeChng;
57395 pPager->xCodecFree = xCodecFree;
57396 pPager->pCodec = pCodec;
57397 setGetterMethod(pPager);
@@ -65764,11 +66047,11 @@
66047 freeTempSpace(pBt);
66048 rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
66049 pageSize-usableSize);
66050 return rc;
66051 }
66052 if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
66053 rc = SQLITE_CORRUPT_BKPT;
66054 goto page1_init_failed;
66055 }
66056 /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
66057 ** be less than 480. In other words, if the page size is 512, then the
@@ -66238,10 +66521,11 @@
66521
66522 assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
66523 eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
66524 assert( sqlite3_mutex_held(pBt->mutex) );
66525 assert( pDbPage->pBt==pBt );
66526 if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
66527
66528 /* Move page iDbPage from its current location to page number iFreePage */
66529 TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
66530 iDbPage, iFreePage, iPtrPage, eType));
66531 rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
@@ -67409,13 +67693,10 @@
67693 offset -= ovflSize;
67694 }else{
67695 /* Need to read this page properly. It contains some of the
67696 ** range of data that is being read (eOp==0) or written (eOp!=0).
67697 */
 
 
 
67698 int a = amt;
67699 if( a + offset > ovflSize ){
67700 a = ovflSize - offset;
67701 }
67702
@@ -67422,11 +67703,11 @@
67703 #ifdef SQLITE_DIRECT_OVERFLOW_READ
67704 /* If all the following are true:
67705 **
67706 ** 1) this is a read operation, and
67707 ** 2) data is required from the start of this overflow page, and
67708 ** 3) there are no dirty pages in the page-cache
67709 ** 4) the database is file-backed, and
67710 ** 5) the page is not in the WAL file
67711 ** 6) at least 4 bytes have already been read into the output buffer
67712 **
67713 ** then data can be read directly from the database file into the
@@ -67433,15 +67714,14 @@
67714 ** output buffer, bypassing the page-cache altogether. This speeds
67715 ** up loading large records that span many overflow pages.
67716 */
67717 if( eOp==0 /* (1) */
67718 && offset==0 /* (2) */
67719 && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */
 
 
67720 && &pBuf[-4]>=pBufStart /* (6) */
67721 ){
67722 sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
67723 u8 aSave[4];
67724 u8 *aWrite = &pBuf[-4];
67725 assert( aWrite>=pBufStart ); /* due to (6) */
67726 memcpy(aSave, aWrite, 4);
67727 rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
@@ -74033,11 +74313,12 @@
74313 sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
74314 }else{
74315 assert( fg & MEM_Real );
74316 sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
74317 }
74318 assert( pMem->z!=0 );
74319 pMem->n = sqlite3Strlen30NN(pMem->z);
74320 pMem->enc = SQLITE_UTF8;
74321 pMem->flags |= MEM_Str|MEM_Term;
74322 if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
74323 sqlite3VdbeChangeEncoding(pMem, enc);
74324 return SQLITE_OK;
@@ -75608,10 +75889,17 @@
75889 if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
75890 p->expmask = 0;
75891 }
75892 assert( p->zSql==0 );
75893 p->zSql = sqlite3DbStrNDup(p->db, z, n);
75894 #ifdef SQLITE_ENABLE_NORMALIZE
75895 assert( p->zNormSql==0 );
75896 if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
75897 sqlite3Normalize(p, p->zSql, n, prepFlags);
75898 assert( p->zNormSql!=0 || p->db->mallocFailed );
75899 }
75900 #endif
75901 }
75902
75903 /*
75904 ** Swap all content between two VDBE structures.
75905 */
@@ -75629,10 +75917,15 @@
75917 pA->pPrev = pB->pPrev;
75918 pB->pPrev = pTmp;
75919 zTmp = pA->zSql;
75920 pA->zSql = pB->zSql;
75921 pB->zSql = zTmp;
75922 #ifdef SQLITE_ENABLE_NORMALIZE
75923 zTmp = pA->zNormSql;
75924 pA->zNormSql = pB->zNormSql;
75925 pB->zNormSql = zTmp;
75926 #endif
75927 pB->expmask = pA->expmask;
75928 pB->prepFlags = pA->prepFlags;
75929 memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
75930 pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
75931 }
@@ -78700,10 +78993,13 @@
78993 sqlite3DbFree(db, p->pFree);
78994 }
78995 vdbeFreeOpArray(db, p->aOp, p->nOp);
78996 sqlite3DbFree(db, p->aColName);
78997 sqlite3DbFree(db, p->zSql);
78998 #ifdef SQLITE_ENABLE_NORMALIZE
78999 sqlite3DbFree(db, p->zNormSql);
79000 #endif
79001 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
79002 {
79003 int i;
79004 for(i=0; i<p->nScan; i++){
79005 sqlite3DbFree(db, p->aScan[i].zName);
@@ -80101,11 +80397,13 @@
80397
80398 /* The index entry must begin with a header size */
80399 (void)getVarint32((u8*)m.z, szHdr);
80400 testcase( szHdr==3 );
80401 testcase( szHdr==m.n );
80402 testcase( szHdr>0x7fffffff );
80403 assert( m.n>=0 );
80404 if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
80405 goto idx_rowid_corruption;
80406 }
80407
80408 /* The last field of the index should be an integer - the ROWID.
80409 ** Verify that the last entry really is an integer. */
@@ -82112,10 +82410,20 @@
82410 }
82411 return z;
82412 #endif
82413 }
82414
82415 #ifdef SQLITE_ENABLE_NORMALIZE
82416 /*
82417 ** Return the normalized SQL associated with a prepared statement.
82418 */
82419 SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
82420 Vdbe *p = (Vdbe *)pStmt;
82421 return p ? p->zNormSql : 0;
82422 }
82423 #endif /* SQLITE_ENABLE_NORMALIZE */
82424
82425 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
82426 /*
82427 ** Allocate and populate an UnpackedRecord structure based on the serialized
82428 ** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
82429 ** if successful, or a NULL pointer if an OOM error is encountered.
@@ -85551,21 +85859,29 @@
85859 nVarint = sqlite3VarintLen(nHdr);
85860 nHdr += nVarint;
85861 if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
85862 }
85863 nByte = nHdr+nData;
 
 
 
85864
85865 /* Make sure the output register has a buffer large enough to store
85866 ** the new record. The output register (pOp->p3) is not allowed to
85867 ** be one of the input registers (because the following call to
85868 ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
85869 */
85870 if( nByte+nZero<=pOut->szMalloc ){
85871 /* The output register is already large enough to hold the record.
85872 ** No error checks or buffer enlargement is required */
85873 pOut->z = pOut->zMalloc;
85874 }else{
85875 /* Need to make sure that the output is not too big and then enlarge
85876 ** the output register to hold the full result */
85877 if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
85878 goto too_big;
85879 }
85880 if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
85881 goto no_mem;
85882 }
85883 }
85884 zNewRecord = (u8 *)pOut->z;
85885
85886 /* Write the record */
85887 i = putVarint32(zNewRecord, nHdr);
@@ -88417,11 +88733,11 @@
88733 }else
88734 #endif
88735 {
88736 zMaster = MASTER_NAME;
88737 initData.db = db;
88738 initData.iDb = iDb;
88739 initData.pzErrMsg = &p->zErrMsg;
88740 initData.mInitFlags = 0;
88741 zSql = sqlite3MPrintf(db,
88742 "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
88743 db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
@@ -89614,14 +89930,15 @@
89930 ** Store in register P3 the value of the P2-th column of
89931 ** the current row of the virtual-table of cursor P1.
89932 **
89933 ** If the VColumn opcode is being used to fetch the value of
89934 ** an unchanging column during an UPDATE operation, then the P5
89935 ** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange()
89936 ** function to return true inside the xColumn method of the virtual
89937 ** table implementation. The P5 column might also contain other
89938 ** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
89939 ** unused by OP_VColumn.
89940 */
89941 case OP_VColumn: {
89942 sqlite3_vtab *pVtab;
89943 const sqlite3_module *pModule;
89944 Mem *pDest;
@@ -89639,11 +89956,12 @@
89956 pVtab = pCur->uc.pVCur->pVtab;
89957 pModule = pVtab->pModule;
89958 assert( pModule->xColumn );
89959 memset(&sContext, 0, sizeof(sContext));
89960 sContext.pOut = pDest;
89961 testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
89962 if( pOp->p5 & OPFLAG_NOCHNG ){
89963 sqlite3VdbeMemSetNull(pDest);
89964 pDest->flags = MEM_Null|MEM_Zero;
89965 pDest->u.nZero = 0;
89966 }else{
89967 MemSetTypeFlag(pDest, MEM_Null);
@@ -93998,12 +94316,12 @@
94316 if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
94317 }else if( pExpr->x.pList ){
94318 if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
94319 }
94320 #ifndef SQLITE_OMIT_WINDOWFUNC
94321 if( ExprHasProperty(pExpr, EP_WinFunc) ){
94322 Window *pWin = pExpr->y.pWin;
94323 if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
94324 if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
94325 if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
94326 }
94327 #endif
@@ -94272,11 +94590,11 @@
94590 **
94591 ** pExpr->iDb Set the index in db->aDb[] of the database X
94592 ** (even if X is implied).
94593 ** pExpr->iTable Set to the cursor number for the table obtained
94594 ** from pSrcList.
94595 ** pExpr->y.pTab Points to the Table structure of X.Y (even if
94596 ** X and/or Y are implied.)
94597 ** pExpr->iColumn Set to the column number within the table.
94598 ** pExpr->op Set to TK_COLUMN.
94599 ** pExpr->pLeft Any expression this points to is deleted
94600 ** pExpr->pRight Any expression this points to is deleted.
@@ -94316,11 +94634,10 @@
94634 assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
94635 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
94636
94637 /* Initialize the node to no-match */
94638 pExpr->iTable = -1;
 
94639 ExprSetVVAProperty(pExpr, EP_NoReduce);
94640
94641 /* Translate the schema name in zDb into a pointer to the corresponding
94642 ** schema. If not found, pSchema will remain NULL and nothing will match
94643 ** resulting in an appropriate error message toward the end of this routine
@@ -94378,11 +94695,11 @@
94695 assert( zTabName!=0 );
94696 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
94697 continue;
94698 }
94699 if( IN_RENAME_OBJECT && pItem->zAlias ){
94700 sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
94701 }
94702 }
94703 if( 0==(cntTab++) ){
94704 pMatch = pItem;
94705 }
@@ -94404,17 +94721,17 @@
94721 }
94722 }
94723 }
94724 if( pMatch ){
94725 pExpr->iTable = pMatch->iCursor;
94726 pExpr->y.pTab = pMatch->pTab;
94727 /* RIGHT JOIN not (yet) supported */
94728 assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
94729 if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
94730 ExprSetProperty(pExpr, EP_CanBeNull);
94731 }
94732 pSchema = pExpr->y.pTab->pSchema;
94733 }
94734 } /* if( pSrcList ) */
94735
94736 #if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
94737 /* If we have not already resolved the name, then maybe
@@ -94467,11 +94784,11 @@
94784 #ifndef SQLITE_OMIT_UPSERT
94785 if( pExpr->iTable==2 ){
94786 testcase( iCol==(-1) );
94787 if( IN_RENAME_OBJECT ){
94788 pExpr->iColumn = iCol;
94789 pExpr->y.pTab = pTab;
94790 eNewExprOp = TK_COLUMN;
94791 }else{
94792 pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
94793 eNewExprOp = TK_REGISTER;
94794 ExprSetProperty(pExpr, EP_Alias);
@@ -94489,11 +94806,11 @@
94806 }else{
94807 testcase( iCol==31 );
94808 testcase( iCol==32 );
94809 pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
94810 }
94811 pExpr->y.pTab = pTab;
94812 pExpr->iColumn = (i16)iCol;
94813 eNewExprOp = TK_TRIGGER;
94814 #endif /* SQLITE_OMIT_TRIGGER */
94815 }
94816 }
@@ -94589,11 +94906,11 @@
94906 */
94907 if( cnt==0 && zTab==0 ){
94908 assert( pExpr->op==TK_ID );
94909 if( ExprHasProperty(pExpr,EP_DblQuoted) ){
94910 pExpr->op = TK_STRING;
94911 pExpr->y.pTab = 0;
94912 return WRC_Prune;
94913 }
94914 if( sqlite3ExprIdToTrueFalse(pExpr) ){
94915 return WRC_Prune;
94916 }
@@ -94667,13 +94984,13 @@
94984 */
94985 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
94986 Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
94987 if( p ){
94988 struct SrcList_item *pItem = &pSrc->a[iSrc];
94989 p->y.pTab = pItem->pTab;
94990 p->iTable = pItem->iCursor;
94991 if( p->y.pTab->iPKey==iCol ){
94992 p->iColumn = -1;
94993 }else{
94994 p->iColumn = (ynVar)iCol;
94995 testcase( iCol==BMS );
94996 testcase( iCol==BMS-1 );
@@ -94759,11 +95076,11 @@
95076 struct SrcList_item *pItem;
95077 assert( pSrcList && pSrcList->nSrc==1 );
95078 pItem = pSrcList->a;
95079 assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
95080 pExpr->op = TK_COLUMN;
95081 pExpr->y.pTab = pItem->pTab;
95082 pExpr->iTable = pItem->iCursor;
95083 pExpr->iColumn = -1;
95084 pExpr->affinity = SQLITE_AFF_INTEGER;
95085 break;
95086 }
@@ -94803,13 +95120,11 @@
95120 }
95121 zTable = pLeft->u.zToken;
95122 zColumn = pRight->u.zToken;
95123 if( IN_RENAME_OBJECT ){
95124 sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
95125 sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
 
 
95126 }
95127 }
95128 return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
95129 }
95130
@@ -94887,30 +95202,39 @@
95202 ** sqlite_version() that might change over time cannot be used
95203 ** in an index. */
95204 notValid(pParse, pNC, "non-deterministic functions",
95205 NC_IdxExpr|NC_PartIdx);
95206 }
95207 if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
95208 && pParse->nested==0
95209 && sqlite3Config.bInternalFunctions==0
95210 ){
95211 /* Internal-use-only functions are disallowed unless the
95212 ** SQL is being compiled using sqlite3NestedParse() */
95213 no_such_func = 1;
95214 pDef = 0;
95215 }
95216 }
95217
95218 if( 0==IN_RENAME_OBJECT ){
95219 #ifndef SQLITE_OMIT_WINDOWFUNC
95220 assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
95221 || (pDef->xValue==0 && pDef->xInverse==0)
95222 || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
95223 );
95224 if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
95225 sqlite3ErrorMsg(pParse,
95226 "%.*s() may not be used as a window function", nId, zId
95227 );
95228 pNC->nErr++;
95229 }else if(
95230 (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
95231 || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
95232 || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
95233 ){
95234 const char *zType;
95235 if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
95236 zType = "window";
95237 }else{
95238 zType = "aggregate";
95239 }
95240 sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
@@ -94936,30 +95260,30 @@
95260 nId, zId);
95261 pNC->nErr++;
95262 }
95263 if( is_agg ){
95264 #ifndef SQLITE_OMIT_WINDOWFUNC
95265 pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
95266 #else
95267 pNC->ncFlags &= ~NC_AllowAgg;
95268 #endif
95269 }
95270 }
95271 sqlite3WalkExprList(pWalker, pList);
95272 if( is_agg ){
95273 #ifndef SQLITE_OMIT_WINDOWFUNC
95274 if( pExpr->y.pWin ){
95275 Select *pSel = pNC->pWinSelect;
95276 sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
95277 sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
95278 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
95279 sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
95280 if( 0==pSel->pWin
95281 || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
95282 ){
95283 pExpr->y.pWin->pNextWin = pSel->pWin;
95284 pSel->pWin = pExpr->y.pWin;
95285 }
95286 pNC->ncFlags |= NC_AllowWin;
95287 }else
95288 #endif /* SQLITE_OMIT_WINDOWFUNC */
95289 {
@@ -95378,17 +95702,17 @@
95702 return 1;
95703 }
95704 for(j=0; j<pSelect->pEList->nExpr; j++){
95705 if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
95706 #ifndef SQLITE_OMIT_WINDOWFUNC
95707 if( ExprHasProperty(pE, EP_WinFunc) ){
95708 /* Since this window function is being changed into a reference
95709 ** to the same window function the result set, remove the instance
95710 ** of this window function from the Select.pWin list. */
95711 Window **pp;
95712 for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
95713 if( *pp==pE->y.pWin ){
95714 *pp = (*pp)->pNextWin;
95715 }
95716 }
95717 }
95718 #endif
@@ -95847,12 +96171,12 @@
96171 if( op==TK_CAST ){
96172 assert( !ExprHasProperty(pExpr, EP_IntValue) );
96173 return sqlite3AffinityType(pExpr->u.zToken, 0);
96174 }
96175 #endif
96176 if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
96177 return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
96178 }
96179 if( op==TK_SELECT_COLUMN ){
96180 assert( pExpr->pLeft->flags&EP_xIsSelect );
96181 return sqlite3ExprAffinity(
96182 pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
@@ -95932,17 +96256,17 @@
96256 while( p ){
96257 int op = p->op;
96258 if( p->flags & EP_Generic ) break;
96259 if( (op==TK_AGG_COLUMN || op==TK_COLUMN
96260 || op==TK_REGISTER || op==TK_TRIGGER)
96261 && p->y.pTab!=0
96262 ){
96263 /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
96264 ** a TK_COLUMN but was previously evaluated and cached in a register */
96265 int j = p->iColumn;
96266 if( j>=0 ){
96267 const char *zColl = p->y.pTab->aCol[j].zColl;
96268 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
96269 }
96270 break;
96271 }
96272 if( op==TK_CAST || op==TK_UPLUS ){
@@ -96841,10 +97165,14 @@
97165 */
97166 static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
97167 assert( p!=0 );
97168 /* Sanity check: Assert that the IntValue is non-negative if it exists */
97169 assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
97170
97171 assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
97172 assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
97173 || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
97174 #ifdef SQLITE_DEBUG
97175 if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
97176 assert( p->pLeft==0 );
97177 assert( p->pRight==0 );
97178 assert( p->x.pSelect==0 );
@@ -96859,12 +97187,13 @@
97187 }else if( ExprHasProperty(p, EP_xIsSelect) ){
97188 sqlite3SelectDelete(db, p->x.pSelect);
97189 }else{
97190 sqlite3ExprListDelete(db, p->x.pList);
97191 }
97192 if( ExprHasProperty(p, EP_WinFunc) ){
97193 assert( p->op==TK_FUNCTION );
97194 sqlite3WindowDelete(db, p->y.pWin);
97195 }
97196 }
97197 if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
97198 if( !ExprHasProperty(p, EP_Static) ){
97199 sqlite3DbFreeNN(db, p);
@@ -96924,11 +97253,11 @@
97253 assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
97254 assert( EXPR_FULLSIZE<=0xfff );
97255 assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
97256 if( 0==flags || p->op==TK_SELECT_COLUMN
97257 #ifndef SQLITE_OMIT_WINDOWFUNC
97258 || ExprHasProperty(p, EP_WinFunc)
97259 #endif
97260 ){
97261 nSize = EXPR_FULLSIZE;
97262 }else{
97263 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -96951,11 +97280,11 @@
97280 ** string is defined.)
97281 */
97282 static int dupedExprNodeSize(Expr *p, int flags){
97283 int nByte = dupedExprStructSize(p, flags) & 0xfff;
97284 if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
97285 nByte += sqlite3Strlen30NN(p->u.zToken)+1;
97286 }
97287 return ROUND8(nByte);
97288 }
97289
97290 /*
@@ -97054,26 +97383,28 @@
97383 pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
97384 }
97385 }
97386
97387 /* Fill in pNew->pLeft and pNew->pRight. */
97388 if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
97389 zAlloc += dupedExprNodeSize(p, dupFlags);
97390 if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
97391 pNew->pLeft = p->pLeft ?
97392 exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
97393 pNew->pRight = p->pRight ?
97394 exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
97395 }
 
97396 #ifndef SQLITE_OMIT_WINDOWFUNC
97397 if( ExprHasProperty(p, EP_WinFunc) ){
97398 pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
97399 assert( ExprHasProperty(pNew, EP_WinFunc) );
 
97400 }
97401 #endif /* SQLITE_OMIT_WINDOWFUNC */
97402 if( pzBuffer ){
97403 *pzBuffer = zAlloc;
97404 }
97405 }else{
97406 if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
97407 if( pNew->op==TK_SELECT_COLUMN ){
97408 pNew->pLeft = p->pLeft;
97409 assert( p->iColumn==0 || p->pRight==0 );
97410 assert( p->pRight==0 || p->pRight==p->pLeft );
@@ -97081,13 +97412,10 @@
97412 pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
97413 }
97414 pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
97415 }
97416 }
 
 
 
97417 }
97418 return pNew;
97419 }
97420
97421 /*
@@ -97878,12 +98206,12 @@
98206 case TK_FLOAT:
98207 case TK_BLOB:
98208 return 0;
98209 case TK_COLUMN:
98210 return ExprHasProperty(p, EP_CanBeNull) ||
98211 p->y.pTab==0 || /* Reference to column of index on expression */
98212 (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
98213 default:
98214 return 1;
98215 }
98216 }
98217
@@ -97934,10 +98262,18 @@
98262 if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
98263 if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
98264 if( sqlite3StrICmp(z, "OID")==0 ) return 1;
98265 return 0;
98266 }
98267 #ifdef SQLITE_ENABLE_NORMALIZE
98268 SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){
98269 if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
98270 if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
98271 if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
98272 return 0;
98273 }
98274 #endif
98275
98276 /*
98277 ** pX is the RHS of an IN operator. If pX is a SELECT statement
98278 ** that can be simplified to a direct table access, then return
98279 ** a pointer to the SELECT statement. If pX is not a SELECT statement,
@@ -99167,11 +99503,11 @@
99503 ** expresssion. However, make sure the constant has the correct
99504 ** datatype by applying the Affinity of the table column to the
99505 ** constant.
99506 */
99507 int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
99508 int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
99509 if( aff!=SQLITE_AFF_BLOB ){
99510 static const char zAff[] = "B\000C\000D\000E";
99511 assert( SQLITE_AFF_BLOB=='A' );
99512 assert( SQLITE_AFF_TEXT=='B' );
99513 if( iReg!=target ){
@@ -99191,11 +99527,11 @@
99527 /* Coding an expression that is part of an index where column names
99528 ** in the index refer to the table to which the index belongs */
99529 iTab = pParse->iSelfTab - 1;
99530 }
99531 }
99532 return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
99533 pExpr->iColumn, iTab, target,
99534 pExpr->op2);
99535 }
99536 case TK_INTEGER: {
99537 codeInteger(pParse, pExpr, 0, target);
@@ -99405,12 +99741,12 @@
99741 sqlite3 *db = pParse->db; /* The database connection */
99742 u8 enc = ENC(db); /* The text encoding used by this database */
99743 CollSeq *pColl = 0; /* A collating sequence */
99744
99745 #ifndef SQLITE_OMIT_WINDOWFUNC
99746 if( ExprHasProperty(pExpr, EP_WinFunc) ){
99747 return pExpr->y.pWin->regResult;
99748 }
99749 #endif
99750
99751 if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
99752 /* SQL functions can be expensive. So try to move constant functions
@@ -99649,11 +99985,11 @@
99985 **
99986 ** p1==0 -> old.rowid p1==3 -> new.rowid
99987 ** p1==1 -> old.a p1==4 -> new.a
99988 ** p1==2 -> old.b p1==5 -> new.b
99989 */
99990 Table *pTab = pExpr->y.pTab;
99991 int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
99992
99993 assert( pExpr->iTable==0 || pExpr->iTable==1 );
99994 assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
99995 assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
@@ -99660,11 +99996,11 @@
99996 assert( p1>=0 && p1<(pTab->nCol*2+2) );
99997
99998 sqlite3VdbeAddOp2(v, OP_Param, p1, target);
99999 VdbeComment((v, "r[%d]=%s.%s", target,
100000 (pExpr->iTable ? "new" : "old"),
100001 (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
100002 ));
100003
100004 #ifndef SQLITE_OMIT_FLOATING_POINT
100005 /* If the column has REAL affinity, it may currently be stored as an
100006 ** integer. Use OP_RealAffinity to make sure it is really real.
@@ -100511,10 +100847,24 @@
100847 return 2;
100848 }
100849 if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
100850 if( pA->op==TK_FUNCTION ){
100851 if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
100852 #ifndef SQLITE_OMIT_WINDOWFUNC
100853 /* Justification for the assert():
100854 ** window functions have p->op==TK_FUNCTION but aggregate functions
100855 ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
100856 ** function and a window function should have failed before reaching
100857 ** this point. And, it is not possible to have a window function and
100858 ** a scalar function with the same name and number of arguments. So
100859 ** if we reach this point, either A and B both window functions or
100860 ** neither are a window functions. */
100861 assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
100862 if( ExprHasProperty(pA,EP_WinFunc) ){
100863 if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
100864 }
100865 #endif
100866 }else if( pA->op==TK_COLLATE ){
100867 if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
100868 }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
100869 return 2;
100870 }
@@ -100530,25 +100880,10 @@
100880 if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
100881 if( pA->iColumn!=pB->iColumn ) return 2;
100882 if( pA->iTable!=pB->iTable
100883 && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
100884 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100885 }
100886 return 0;
100887 }
100888
100889 /*
@@ -100685,12 +101020,12 @@
101020 testcase( pExpr->op==TK_NE );
101021 testcase( pExpr->op==TK_LT );
101022 testcase( pExpr->op==TK_LE );
101023 testcase( pExpr->op==TK_GT );
101024 testcase( pExpr->op==TK_GE );
101025 if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
101026 || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
101027 ){
101028 return WRC_Prune;
101029 }
101030 default:
101031 return WRC_Continue;
@@ -100917,11 +101252,11 @@
101252 }
101253 if( (k>=pAggInfo->nColumn)
101254 && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
101255 ){
101256 pCol = &pAggInfo->aCol[k];
101257 pCol->pTab = pExpr->y.pTab;
101258 pCol->iTable = pExpr->iTable;
101259 pCol->iColumn = pExpr->iColumn;
101260 pCol->iMem = ++pParse->nMem;
101261 pCol->iSorterColumn = -1;
101262 pCol->pExpr = pExpr;
@@ -101800,14 +102135,20 @@
102135 #else
102136 # define renameTokenCheckAll(x,y)
102137 #endif
102138
102139 /*
102140 ** Remember that the parser tree element pPtr was created using
102141 ** the token pToken.
102142 **
102143 ** In other words, construct a new RenameToken object and add it
102144 ** to the list of RenameToken objects currently being built up
102145 ** in pParse->pRename.
102146 **
102147 ** The pPtr argument is returned so that this routine can be used
102148 ** with tail recursion in tokenExpr() routine, for a small performance
102149 ** improvement.
102150 */
102151 SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
102152 RenameToken *pNew;
102153 assert( pPtr || pParse->db->mallocFailed );
102154 renameTokenCheckAll(pParse, pPtr);
@@ -101936,11 +102277,11 @@
102277 && pWalker->pParse->pTriggerTab==p->pTab
102278 ){
102279 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
102280 }else if( pExpr->op==TK_COLUMN
102281 && pExpr->iColumn==p->iCol
102282 && p->pTab==pExpr->y.pTab
102283 ){
102284 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
102285 }
102286 return WRC_Continue;
102287 }
@@ -102194,13 +102535,18 @@
102535 assert( pNew->pTabSchema );
102536 pParse->pTriggerTab = sqlite3FindTable(db, pNew->table,
102537 db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
102538 );
102539 pParse->eTriggerOp = pNew->op;
102540 /* ALWAYS() because if the table of the trigger does not exist, the
102541 ** error would have been hit before this point */
102542 if( ALWAYS(pParse->pTriggerTab) ){
102543 rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
102544 }
102545
102546 /* Resolve symbols in WHEN clause */
102547 if( rc==SQLITE_OK && pNew->pWhen ){
102548 rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
102549 }
102550
102551 for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
102552 if( pStep->pSelect ){
@@ -102310,19 +102656,12 @@
102656 ** Do a column rename operation on the CREATE statement given in zSql.
102657 ** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
102658 ** into zNew. The name should be quoted if bQuote is true.
102659 **
102660 ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
102661 ** It is only accessible to SQL created using sqlite3NestedParse(). It is
102662 ** not reachable from ordinary SQL passed into sqlite3_prepare().
 
 
 
 
 
 
 
102663 */
102664 static void renameColumnFunc(
102665 sqlite3_context *context,
102666 int NotUsed,
102667 sqlite3_value **argv
@@ -102474,12 +102813,12 @@
102813 /*
102814 ** Walker expression callback used by "RENAME TABLE".
102815 */
102816 static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
102817 RenameCtx *p = pWalker->u.pRename;
102818 if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
102819 renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
102820 }
102821 return WRC_Continue;
102822 }
102823
102824 /*
@@ -102572,11 +102911,11 @@
102911 sqlite3WalkSelect(&sWalker, pTab->pSelect);
102912 }
102913 }else{
102914 /* Modify any FK definitions to point to the new table. */
102915 #ifndef SQLITE_OMIT_FOREIGN_KEY
102916 if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
102917 FKey *pFKey;
102918 for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
102919 if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
102920 renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
102921 }
@@ -102726,13 +103065,13 @@
103065 /*
103066 ** Register built-in functions used to help implement ALTER TABLE
103067 */
103068 SQLITE_PRIVATE void sqlite3AlterFunctions(void){
103069 static FuncDef aAlterTableFuncs[] = {
103070 INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
103071 INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc),
103072 INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest),
103073 };
103074 sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
103075 }
103076 #endif /* SQLITE_ALTER_TABLE */
103077
@@ -104777,11 +105116,11 @@
105116 if( pVfs==0 ) return;
105117 pNew = &db->aDb[db->init.iDb];
105118 if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
105119 pNew->pBt = 0;
105120 pNew->pSchema = 0;
105121 rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
105122 }else{
105123 /* This is a real ATTACH
105124 **
105125 ** Check for the following errors:
105126 **
@@ -105457,10 +105796,11 @@
105796 int iSrc; /* Index in pTabList->a[] of table being read */
105797 int iDb; /* The index of the database the expression refers to */
105798 int iCol; /* Index of column in table */
105799
105800 assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
105801 assert( !IN_RENAME_OBJECT || db->xAuth==0 );
105802 if( db->xAuth==0 ) return;
105803 iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
105804 if( iDb<0 ){
105805 /* An attempt to read a column out of a subquery or other
105806 ** temporary table. */
@@ -105513,10 +105853,11 @@
105853 int rc;
105854
105855 /* Don't do any authorization checks if the database is initialising
105856 ** or if the parser is being invoked from within sqlite3_declare_vtab.
105857 */
105858 assert( !IN_RENAME_OBJECT || db->xAuth==0 );
105859 if( db->init.busy || IN_SPECIAL_PARSE ){
105860 return SQLITE_OK;
105861 }
105862
105863 if( db->xAuth==0 ){
@@ -105936,21 +106277,19 @@
106277
106278 p = sqlite3FindTable(db, zName, zDbase);
106279 if( p==0 ){
106280 const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
106281 #ifndef SQLITE_OMIT_VIRTUALTABLE
106282 /* If zName is the not the name of a table in the schema created using
106283 ** CREATE, then check to see if it is the name of an virtual table that
106284 ** can be an eponymous virtual table. */
106285 Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
106286 if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
106287 pMod = sqlite3PragmaVtabRegister(db, zName);
106288 }
106289 if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
106290 return pMod->pEpoTab;
 
 
106291 }
106292 #endif
106293 if( (flags & LOCATE_NOERR)==0 ){
106294 if( zDbase ){
106295 sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
@@ -106126,21 +106465,26 @@
106465 ** "main" and "temp") for a single database connection.
106466 */
106467 SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
106468 int i;
106469 sqlite3BtreeEnterAll(db);
 
106470 for(i=0; i<db->nDb; i++){
106471 Db *pDb = &db->aDb[i];
106472 if( pDb->pSchema ){
106473 if( db->nSchemaLock==0 ){
106474 sqlite3SchemaClear(pDb->pSchema);
106475 }else{
106476 DbSetProperty(db, i, DB_ResetWanted);
106477 }
106478 }
106479 }
106480 db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
106481 sqlite3VtabUnlockList(db);
106482 sqlite3BtreeLeaveAll(db);
106483 if( db->nSchemaLock==0 ){
106484 sqlite3CollapseDatabaseArray(db);
106485 }
106486 }
106487
106488 /*
106489 ** This routine is called when a commit occurs.
106490 */
@@ -106213,10 +106557,16 @@
106557 /* Delete any foreign keys attached to this table. */
106558 sqlite3FkDelete(db, pTable);
106559
106560 /* Delete the Table structure itself.
106561 */
106562 #ifdef SQLITE_ENABLE_NORMALIZE
106563 if( pTable->pColHash ){
106564 sqlite3HashClear(pTable->pColHash);
106565 sqlite3_free(pTable->pColHash);
106566 }
106567 #endif
106568 sqlite3DeleteColumnNames(db, pTable);
106569 sqlite3DbFree(db, pTable->zName);
106570 sqlite3DbFree(db, pTable->zColAff);
106571 sqlite3SelectDelete(db, pTable->pSelect);
106572 sqlite3ExprListDelete(db, pTable->pCheck);
@@ -106370,10 +106720,24 @@
106720 iDb = db->init.iDb;
106721 *pUnqual = pName1;
106722 }
106723 return iDb;
106724 }
106725
106726 /*
106727 ** True if PRAGMA writable_schema is ON
106728 */
106729 SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
106730 testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
106731 testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
106732 SQLITE_WriteSchema );
106733 testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
106734 SQLITE_Defensive );
106735 testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
106736 (SQLITE_WriteSchema|SQLITE_Defensive) );
106737 return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
106738 }
106739
106740 /*
106741 ** This routine is used to check if the UTF-8 string zName is a legal
106742 ** unqualified name for a new schema object (table, index, view or
106743 ** trigger). All names are legal except those that begin with the string
@@ -106380,11 +106744,11 @@
106744 ** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
106745 ** is reserved for internal use.
106746 */
106747 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
106748 if( !pParse->db->init.busy && pParse->nested==0
106749 && sqlite3WritableSchema(pParse->db)==0
106750 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
106751 sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
106752 return SQLITE_ERROR;
106753 }
106754 return SQLITE_OK;
@@ -107456,10 +107820,40 @@
107820 pPk->nColumn = pTab->nCol;
107821 }
107822 recomputeColumnsNotIndexed(pPk);
107823 }
107824
107825 #ifndef SQLITE_OMIT_VIRTUALTABLE
107826 /*
107827 ** Return true if zName is a shadow table name in the current database
107828 ** connection.
107829 **
107830 ** zName is temporarily modified while this routine is running, but is
107831 ** restored to its original value prior to this routine returning.
107832 */
107833 static int isShadowTableName(sqlite3 *db, char *zName){
107834 char *zTail; /* Pointer to the last "_" in zName */
107835 Table *pTab; /* Table that zName is a shadow of */
107836 Module *pMod; /* Module for the virtual table */
107837
107838 zTail = strrchr(zName, '_');
107839 if( zTail==0 ) return 0;
107840 *zTail = 0;
107841 pTab = sqlite3FindTable(db, zName, 0);
107842 *zTail = '_';
107843 if( pTab==0 ) return 0;
107844 if( !IsVirtual(pTab) ) return 0;
107845 pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
107846 if( pMod==0 ) return 0;
107847 if( pMod->pModule->iVersion<3 ) return 0;
107848 if( pMod->pModule->xShadowName==0 ) return 0;
107849 return pMod->pModule->xShadowName(zTail+1);
107850 }
107851 #else
107852 # define isShadowTableName(x,y) 0
107853 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
107854
107855 /*
107856 ** This routine is called to report the final ")" that terminates
107857 ** a CREATE TABLE statement.
107858 **
107859 ** The table structure that other action routines have been building
@@ -107494,10 +107888,14 @@
107888 return;
107889 }
107890 assert( !db->mallocFailed );
107891 p = pParse->pNewTable;
107892 if( p==0 ) return;
107893
107894 if( pSelect==0 && isShadowTableName(db, p->zName) ){
107895 p->tabFlags |= TF_Shadow;
107896 }
107897
107898 /* If the db->init.busy is 1 it means we are reading the SQL off the
107899 ** "sqlite_master" or "sqlite_temp_master" table on the disk.
107900 ** So do not write to the disk again. Extract the root page number
107901 ** for the table from the db->init.newTnum field. (The page number
@@ -108002,11 +108400,11 @@
108400 ** erasing iTable (this can happen with an auto-vacuum database).
108401 */
108402 static void destroyRootPage(Parse *pParse, int iTable, int iDb){
108403 Vdbe *v = sqlite3GetVdbe(pParse);
108404 int r1 = sqlite3GetTempReg(pParse);
108405 if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
108406 sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
108407 sqlite3MayAbort(pParse);
108408 #ifndef SQLITE_OMIT_AUTOVACUUM
108409 /* OP_Destroy stores an in integer r1. If this integer
108410 ** is non-zero, then it is the root page number of a table moved to
@@ -110457,10 +110855,25 @@
110855 return p;
110856 }
110857 }
110858 return 0;
110859 }
110860 #ifdef SQLITE_ENABLE_NORMALIZE
110861 SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(
110862 int h, /* Hash of the name */
110863 const char *zFunc, /* Name of function */
110864 int nFunc /* Length of the name */
110865 ){
110866 FuncDef *p;
110867 for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
110868 if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
110869 return p;
110870 }
110871 }
110872 return 0;
110873 }
110874 #endif /* SQLITE_ENABLE_NORMALIZE */
110875
110876 /*
110877 ** Insert a new FuncDef into a FuncDefHash hash table.
110878 */
110879 SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
@@ -110470,11 +110883,11 @@
110883 int i;
110884 for(i=0; i<nDef; i++){
110885 FuncDef *pOther;
110886 const char *zName = aDef[i].zName;
110887 int nName = sqlite3Strlen30(zName);
110888 int h = SQLITE_FUNC_HASH(zName[0], nName);
110889 assert( zName[0]>='a' && zName[0]<='z' );
110890 pOther = functionSearch(h, zName);
110891 if( pOther ){
110892 assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
110893 aDef[i].pNext = pOther->pNext;
@@ -110549,11 +110962,11 @@
110962 ** new function. But the FuncDefs for built-in functions are read-only.
110963 ** So we must not search for built-ins when creating a new function.
110964 */
110965 if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
110966 bestScore = 0;
110967 h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
110968 p = functionSearch(h, zName);
110969 while( p ){
110970 int score = matchQuality(p, nArg, enc);
110971 if( score>bestScore ){
110972 pBest = p;
@@ -110696,37 +111109,54 @@
111109 if( sqlite3IndexedByLookup(pParse, pItem) ){
111110 pTab = 0;
111111 }
111112 return pTab;
111113 }
111114
111115 /* Return true if table pTab is read-only.
111116 **
111117 ** A table is read-only if any of the following are true:
111118 **
111119 ** 1) It is a virtual table and no implementation of the xUpdate method
111120 ** has been provided
111121 **
111122 ** 2) It is a system table (i.e. sqlite_master), this call is not
111123 ** part of a nested parse and writable_schema pragma has not
111124 ** been specified
111125 **
111126 ** 3) The table is a shadow table, the database connection is in
111127 ** defensive mode, and the current sqlite3_prepare()
111128 ** is for a top-level SQL statement.
111129 */
111130 static int tabIsReadOnly(Parse *pParse, Table *pTab){
111131 sqlite3 *db;
111132 if( IsVirtual(pTab) ){
111133 return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
111134 }
111135 if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
111136 db = pParse->db;
111137 if( (pTab->tabFlags & TF_Readonly)!=0 ){
111138 return sqlite3WritableSchema(db)==0 && pParse->nested==0;
111139 }
111140 assert( pTab->tabFlags & TF_Shadow );
111141 return (db->flags & SQLITE_Defensive)!=0
111142 #ifndef SQLITE_OMIT_VIRTUALTABLE
111143 && db->pVtabCtx==0
111144 #endif
111145 && db->nVdbeExec==0;
111146 }
111147
111148 /*
111149 ** Check to make sure the given table is writable. If it is not
111150 ** writable, generate an error message and return 1. If it is
111151 ** writable return 0;
111152 */
111153 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
111154 if( tabIsReadOnly(pParse, pTab) ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111155 sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
111156 return 1;
111157 }
 
111158 #ifndef SQLITE_OMIT_VIEW
111159 if( !viewOk && pTab->pSelect ){
111160 sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
111161 return 1;
111162 }
@@ -114126,11 +114556,11 @@
114556 int iCursor, /* The open cursor on the table */
114557 i16 iCol /* The column that is wanted */
114558 ){
114559 Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
114560 if( pExpr ){
114561 pExpr->y.pTab = pTab;
114562 pExpr->iTable = iCursor;
114563 pExpr->iColumn = iCol;
114564 }
114565 return pExpr;
114566 }
@@ -115202,11 +115632,12 @@
115632 do{
115633 zColAff[i--] = 0;
115634 }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
115635 pTab->zColAff = zColAff;
115636 }
115637 assert( zColAff!=0 );
115638 i = sqlite3Strlen30NN(zColAff);
115639 if( i ){
115640 if( iReg ){
115641 sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
115642 }else{
115643 sqlite3VdbeChangeP4(v, -1, zColAff, i);
@@ -116182,18 +116613,19 @@
116613 #ifdef tmask
116614 #undef tmask
116615 #endif
116616
116617 /*
116618 ** Meanings of bits in of pWalker->eCode for
116619 ** sqlite3ExprReferencesUpdatedColumn()
116620 */
116621 #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
116622 #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
116623
116624 /* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
116625 * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
116626 ** expression node references any of the
116627 ** columns that are being modifed by an UPDATE statement.
116628 */
116629 static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
116630 if( pExpr->op==TK_COLUMN ){
116631 assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
@@ -116211,16 +116643,25 @@
116643 /*
116644 ** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The
116645 ** only columns that are modified by the UPDATE are those for which
116646 ** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
116647 **
116648 ** Return true if CHECK constraint pExpr uses any of the
116649 ** changing columns (or the rowid if it is changing). In other words,
116650 ** return true if this CHECK constraint must be validated for
116651 ** the new row in the UPDATE statement.
116652 **
116653 ** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
116654 ** The operation of this routine is the same - return true if an only if
116655 ** the expression uses one or more of columns identified by the second and
116656 ** third arguments.
116657 */
116658 SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
116659 Expr *pExpr, /* The expression to be checked */
116660 int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
116661 int chngRowid /* True if UPDATE changes the rowid */
116662 ){
116663 Walker w;
116664 memset(&w, 0, sizeof(w));
116665 w.eCode = 0;
116666 w.xExprCallback = checkConstraintExprNode;
116667 w.u.aiCol = aiChng;
@@ -116231,11 +116672,11 @@
116672 }
116673 testcase( w.eCode==0 );
116674 testcase( w.eCode==CKCNSTRNT_COLUMN );
116675 testcase( w.eCode==CKCNSTRNT_ROWID );
116676 testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
116677 return w.eCode!=0;
116678 }
116679
116680 /*
116681 ** Generate code to do constraint checks prior to an INSERT or an UPDATE
116682 ** on table pTab.
@@ -116437,11 +116878,17 @@
116878 pParse->iSelfTab = -(regNewData+1);
116879 onError = overrideError!=OE_Default ? overrideError : OE_Abort;
116880 for(i=0; i<pCheck->nExpr; i++){
116881 int allOk;
116882 Expr *pExpr = pCheck->a[i].pExpr;
116883 if( aiChng
116884 && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
116885 ){
116886 /* The check constraints do not reference any of the columns being
116887 ** updated so there is no point it verifying the check constraint */
116888 continue;
116889 }
116890 allOk = sqlite3VdbeMakeLabel(v);
116891 sqlite3VdbeVerifyAbortable(v, onError);
116892 sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
116893 if( onError==OE_Ignore ){
116894 sqlite3VdbeGoto(v, ignoreDest);
@@ -117938,16 +118385,19 @@
118385 void (*str_appendchar)(sqlite3_str*, int N, char C);
118386 void (*str_reset)(sqlite3_str*);
118387 int (*str_errcode)(sqlite3_str*);
118388 int (*str_length)(sqlite3_str*);
118389 char *(*str_value)(sqlite3_str*);
118390 /* Version 3.25.0 and later */
118391 int (*create_window_function)(sqlite3*,const char*,int,int,void*,
118392 void (*xStep)(sqlite3_context*,int,sqlite3_value**),
118393 void (*xFinal)(sqlite3_context*),
118394 void (*xValue)(sqlite3_context*),
118395 void (*xInv)(sqlite3_context*,int,sqlite3_value**),
118396 void(*xDestroy)(void*));
118397 /* Version 3.26.0 and later */
118398 const char *(*normalized_sql)(sqlite3_stmt*);
118399 };
118400
118401 /*
118402 ** This is the function signature used for all extension entry points. It
118403 ** is also defined in the file "loadext.c".
@@ -118231,10 +118681,12 @@
118681 #define sqlite3_str_errcode sqlite3_api->str_errcode
118682 #define sqlite3_str_length sqlite3_api->str_length
118683 #define sqlite3_str_value sqlite3_api->str_value
118684 /* Version 3.25.0 and later */
118685 #define sqlite3_create_window_function sqlite3_api->create_window_function
118686 /* Version 3.26.0 and later */
118687 #define sqlite3_normalized_sql sqlite3_api->normalized_sql
118688 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
118689
118690 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
118691 /* This case when the file really is being compiled as a loadable
118692 ** extension */
@@ -118319,10 +118771,11 @@
118771 # define sqlite3_create_module 0
118772 # define sqlite3_create_module_v2 0
118773 # define sqlite3_declare_vtab 0
118774 # define sqlite3_vtab_config 0
118775 # define sqlite3_vtab_on_conflict 0
118776 # define sqlite3_vtab_collation 0
118777 #endif
118778
118779 #ifdef SQLITE_OMIT_SHARED_CACHE
118780 # define sqlite3_enable_shared_cache 0
118781 #endif
@@ -118686,11 +119139,17 @@
119139 sqlite3_str_reset,
119140 sqlite3_str_errcode,
119141 sqlite3_str_length,
119142 sqlite3_str_value,
119143 /* Version 3.25.0 and later */
119144 sqlite3_create_window_function,
119145 /* Version 3.26.0 and later */
119146 #ifdef SQLITE_ENABLE_NORMALIZE
119147 sqlite3_normalized_sql
119148 #else
119149 0
119150 #endif
119151 };
119152
119153 /*
119154 ** Attempt to load an SQLite extension library contained in the file
119155 ** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -119136,14 +119595,13 @@
119595 #define PragTyp_WAL_AUTOCHECKPOINT 38
119596 #define PragTyp_WAL_CHECKPOINT 39
119597 #define PragTyp_ACTIVATE_EXTENSIONS 40
119598 #define PragTyp_HEXKEY 41
119599 #define PragTyp_KEY 42
119600 #define PragTyp_LOCK_STATUS 43
119601 #define PragTyp_PARSER_TRACE 44
119602 #define PragTyp_STATS 45
 
119603
119604 /* Property flags associated with various pragma. */
119605 #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
119606 #define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
119607 #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
@@ -119156,72 +119614,71 @@
119614 /* Names of columns for pragmas that return multi-column result
119615 ** or that return single-column results where the name of the
119616 ** result column is different from the name of the pragma
119617 */
119618 static const char *const pragCName[] = {
119619 /* 0 */ "id", /* Used by: foreign_key_list */
119620 /* 1 */ "seq",
119621 /* 2 */ "table",
119622 /* 3 */ "from",
119623 /* 4 */ "to",
119624 /* 5 */ "on_update",
119625 /* 6 */ "on_delete",
119626 /* 7 */ "match",
119627 /* 8 */ "cid", /* Used by: table_xinfo */
119628 /* 9 */ "name",
119629 /* 10 */ "type",
119630 /* 11 */ "notnull",
119631 /* 12 */ "dflt_value",
119632 /* 13 */ "pk",
119633 /* 14 */ "hidden",
119634 /* table_info reuses 8 */
119635 /* 15 */ "seqno", /* Used by: index_xinfo */
119636 /* 16 */ "cid",
119637 /* 17 */ "name",
119638 /* 18 */ "desc",
119639 /* 19 */ "coll",
119640 /* 20 */ "key",
119641 /* 21 */ "tbl", /* Used by: stats */
119642 /* 22 */ "idx",
119643 /* 23 */ "wdth",
119644 /* 24 */ "hght",
119645 /* 25 */ "flgs",
119646 /* 26 */ "seq", /* Used by: index_list */
119647 /* 27 */ "name",
119648 /* 28 */ "unique",
119649 /* 29 */ "origin",
119650 /* 30 */ "partial",
119651 /* 31 */ "table", /* Used by: foreign_key_check */
119652 /* 32 */ "rowid",
119653 /* 33 */ "parent",
119654 /* 34 */ "fkid",
119655 /* index_info reuses 15 */
119656 /* 35 */ "seq", /* Used by: database_list */
119657 /* 36 */ "name",
119658 /* 37 */ "file",
119659 /* 38 */ "busy", /* Used by: wal_checkpoint */
119660 /* 39 */ "log",
119661 /* 40 */ "checkpointed",
119662 /* 41 */ "name", /* Used by: function_list */
119663 /* 42 */ "builtin",
119664 /* collation_list reuses 26 */
119665 /* 43 */ "database", /* Used by: lock_status */
119666 /* 44 */ "status",
119667 /* 45 */ "cache_size", /* Used by: default_cache_size */
119668 /* module_list pragma_list reuses 9 */
119669 /* 46 */ "timeout", /* Used by: busy_timeout */
 
 
119670 };
119671
119672 /* Definitions of all built-in pragmas */
119673 typedef struct PragmaName {
119674 const char *const zName; /* Name of pragma */
119675 u8 ePragTyp; /* PragTyp_XXX value */
119676 u8 mPragFlg; /* Zero or more PragFlg_XXX values */
119677 u8 iPragCName; /* Start of column names in pragCName[] */
119678 u8 nPragCName; /* Num of col names. 0 means use pragma name */
119679 u64 iArg; /* Extra argument */
119680 } PragmaName;
119681 static const PragmaName aPragmaName[] = {
119682 #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
119683 {/* zName: */ "activate_extensions",
119684 /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
@@ -119253,11 +119710,11 @@
119710 #endif
119711 #endif
119712 {/* zName: */ "busy_timeout",
119713 /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
119714 /* ePragFlg: */ PragFlg_Result0,
119715 /* ColNames: */ 46, 1,
119716 /* iArg: */ 0 },
119717 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119718 {/* zName: */ "cache_size",
119719 /* ePragTyp: */ PragTyp_CACHE_SIZE,
119720 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
@@ -119290,11 +119747,11 @@
119747 #endif
119748 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119749 {/* zName: */ "collation_list",
119750 /* ePragTyp: */ PragTyp_COLLATION_LIST,
119751 /* ePragFlg: */ PragFlg_Result0,
119752 /* ColNames: */ 26, 2,
119753 /* iArg: */ 0 },
119754 #endif
119755 #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
119756 {/* zName: */ "compile_options",
119757 /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
@@ -119325,18 +119782,18 @@
119782 #endif
119783 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119784 {/* zName: */ "database_list",
119785 /* ePragTyp: */ PragTyp_DATABASE_LIST,
119786 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
119787 /* ColNames: */ 35, 3,
119788 /* iArg: */ 0 },
119789 #endif
119790 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
119791 {/* zName: */ "default_cache_size",
119792 /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
119793 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
119794 /* ColNames: */ 45, 1,
119795 /* iArg: */ 0 },
119796 #endif
119797 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119798 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119799 {/* zName: */ "defer_foreign_keys",
@@ -119362,18 +119819,18 @@
119819 #endif
119820 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119821 {/* zName: */ "foreign_key_check",
119822 /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
119823 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
119824 /* ColNames: */ 31, 4,
119825 /* iArg: */ 0 },
119826 #endif
119827 #if !defined(SQLITE_OMIT_FOREIGN_KEY)
119828 {/* zName: */ "foreign_key_list",
119829 /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
119830 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119831 /* ColNames: */ 0, 8,
119832 /* iArg: */ 0 },
119833 #endif
119834 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119835 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
119836 {/* zName: */ "foreign_keys",
@@ -119405,25 +119862,25 @@
119862 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119863 #if defined(SQLITE_INTROSPECTION_PRAGMAS)
119864 {/* zName: */ "function_list",
119865 /* ePragTyp: */ PragTyp_FUNCTION_LIST,
119866 /* ePragFlg: */ PragFlg_Result0,
119867 /* ColNames: */ 41, 2,
119868 /* iArg: */ 0 },
119869 #endif
119870 #endif
119871 #if defined(SQLITE_HAS_CODEC)
119872 {/* zName: */ "hexkey",
119873 /* ePragTyp: */ PragTyp_HEXKEY,
119874 /* ePragFlg: */ 0,
119875 /* ColNames: */ 0, 0,
119876 /* iArg: */ 2 },
119877 {/* zName: */ "hexrekey",
119878 /* ePragTyp: */ PragTyp_HEXKEY,
119879 /* ePragFlg: */ 0,
119880 /* ColNames: */ 0, 0,
119881 /* iArg: */ 3 },
119882 #endif
119883 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119884 #if !defined(SQLITE_OMIT_CHECK)
119885 {/* zName: */ "ignore_check_constraints",
119886 /* ePragTyp: */ PragTyp_FLAG,
@@ -119441,16 +119898,16 @@
119898 #endif
119899 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
119900 {/* zName: */ "index_info",
119901 /* ePragTyp: */ PragTyp_INDEX_INFO,
119902 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119903 /* ColNames: */ 15, 3,
119904 /* iArg: */ 0 },
119905 {/* zName: */ "index_list",
119906 /* ePragTyp: */ PragTyp_INDEX_LIST,
119907 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119908 /* ColNames: */ 26, 5,
119909 /* iArg: */ 0 },
119910 {/* zName: */ "index_xinfo",
119911 /* ePragTyp: */ PragTyp_INDEX_INFO,
119912 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
119913 /* ColNames: */ 15, 6,
@@ -119503,11 +119960,11 @@
119960 #endif
119961 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
119962 {/* zName: */ "lock_status",
119963 /* ePragTyp: */ PragTyp_LOCK_STATUS,
119964 /* ePragFlg: */ PragFlg_Result0,
119965 /* ColNames: */ 43, 2,
119966 /* iArg: */ 0 },
119967 #endif
119968 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
119969 {/* zName: */ "locking_mode",
119970 /* ePragTyp: */ PragTyp_LOCKING_MODE,
@@ -119529,11 +119986,11 @@
119986 #if !defined(SQLITE_OMIT_VIRTUALTABLE)
119987 #if defined(SQLITE_INTROSPECTION_PRAGMAS)
119988 {/* zName: */ "module_list",
119989 /* ePragTyp: */ PragTyp_MODULE_LIST,
119990 /* ePragFlg: */ PragFlg_Result0,
119991 /* ColNames: */ 9, 1,
119992 /* iArg: */ 0 },
119993 #endif
119994 #endif
119995 #endif
119996 {/* zName: */ "optimize",
@@ -119562,11 +120019,11 @@
120019 #endif
120020 #if defined(SQLITE_INTROSPECTION_PRAGMAS)
120021 {/* zName: */ "pragma_list",
120022 /* ePragTyp: */ PragTyp_PRAGMA_LIST,
120023 /* ePragFlg: */ PragFlg_Result0,
120024 /* ColNames: */ 9, 1,
120025 /* iArg: */ 0 },
120026 #endif
120027 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
120028 {/* zName: */ "query_only",
120029 /* ePragTyp: */ PragTyp_FLAG,
@@ -119593,14 +120050,14 @@
120050 /* ColNames: */ 0, 0,
120051 /* iArg: */ SQLITE_RecTriggers },
120052 #endif
120053 #if defined(SQLITE_HAS_CODEC)
120054 {/* zName: */ "rekey",
120055 /* ePragTyp: */ PragTyp_KEY,
120056 /* ePragFlg: */ 0,
120057 /* ColNames: */ 0, 0,
120058 /* iArg: */ 1 },
120059 #endif
120060 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
120061 {/* zName: */ "reverse_unordered_selects",
120062 /* ePragTyp: */ PragTyp_FLAG,
120063 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119649,11 +120106,11 @@
120106 #endif
120107 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
120108 {/* zName: */ "stats",
120109 /* ePragTyp: */ PragTyp_STATS,
120110 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
120111 /* ColNames: */ 21, 5,
120112 /* iArg: */ 0 },
120113 #endif
120114 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
120115 {/* zName: */ "synchronous",
120116 /* ePragTyp: */ PragTyp_SYNCHRONOUS,
@@ -119663,12 +120120,17 @@
120120 #endif
120121 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
120122 {/* zName: */ "table_info",
120123 /* ePragTyp: */ PragTyp_TABLE_INFO,
120124 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
120125 /* ColNames: */ 8, 6,
120126 /* iArg: */ 0 },
120127 {/* zName: */ "table_xinfo",
120128 /* ePragTyp: */ PragTyp_TABLE_INFO,
120129 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
120130 /* ColNames: */ 8, 7,
120131 /* iArg: */ 1 },
120132 #endif
120133 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
120134 {/* zName: */ "temp_store",
120135 /* ePragTyp: */ PragTyp_TEMP_STORE,
120136 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119677,10 +120139,22 @@
120139 {/* zName: */ "temp_store_directory",
120140 /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
120141 /* ePragFlg: */ PragFlg_NoColumns1,
120142 /* ColNames: */ 0, 0,
120143 /* iArg: */ 0 },
120144 #endif
120145 #if defined(SQLITE_HAS_CODEC)
120146 {/* zName: */ "textkey",
120147 /* ePragTyp: */ PragTyp_KEY,
120148 /* ePragFlg: */ 0,
120149 /* ColNames: */ 0, 0,
120150 /* iArg: */ 4 },
120151 {/* zName: */ "textrekey",
120152 /* ePragTyp: */ PragTyp_KEY,
120153 /* ePragFlg: */ 0,
120154 /* ColNames: */ 0, 0,
120155 /* iArg: */ 5 },
120156 #endif
120157 {/* zName: */ "threads",
120158 /* ePragTyp: */ PragTyp_THREADS,
120159 /* ePragFlg: */ PragFlg_Result0,
120160 /* ColNames: */ 0, 0,
@@ -119728,22 +120202,22 @@
120202 /* ColNames: */ 0, 0,
120203 /* iArg: */ 0 },
120204 {/* zName: */ "wal_checkpoint",
120205 /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
120206 /* ePragFlg: */ PragFlg_NeedSchema,
120207 /* ColNames: */ 38, 3,
120208 /* iArg: */ 0 },
120209 #endif
120210 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
120211 {/* zName: */ "writable_schema",
120212 /* ePragTyp: */ PragTyp_FLAG,
120213 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
120214 /* ColNames: */ 0, 0,
120215 /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
120216 #endif
120217 };
120218 /* Number of pragmas: 62 on by default, 81 total. */
120219
120220 /************** End of pragma.h **********************************************/
120221 /************** Continuing where we left off in pragma.c *********************/
120222
120223 /*
@@ -120751,11 +121225,11 @@
121225 case PragTyp_FLAG: {
121226 if( zRight==0 ){
121227 setPragmaResultColumnNames(v, pPragma);
121228 returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
121229 }else{
121230 u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */
121231 if( db->autoCommit==0 ){
121232 /* Foreign key support may not be enabled or disabled while not
121233 ** in auto-commit mode. */
121234 mask &= ~(SQLITE_ForeignKeys);
121235 }
@@ -120800,19 +121274,21 @@
121274 */
121275 case PragTyp_TABLE_INFO: if( zRight ){
121276 Table *pTab;
121277 pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
121278 if( pTab ){
121279 int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
121280 int i, k;
121281 int nHidden = 0;
121282 Column *pCol;
121283 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
121284 pParse->nMem = 7;
121285 sqlite3CodeVerifySchema(pParse, iTabDb);
121286 sqlite3ViewGetColumnNames(pParse, pTab);
121287 for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
121288 int isHidden = IsHiddenColumn(pCol);
121289 if( isHidden && pPragma->iArg==0 ){
121290 nHidden++;
121291 continue;
121292 }
121293 if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
121294 k = 0;
@@ -120820,17 +121296,18 @@
121296 k = 1;
121297 }else{
121298 for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
121299 }
121300 assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
121301 sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
121302 i-nHidden,
121303 pCol->zName,
121304 sqlite3ColumnType(pCol,""),
121305 pCol->notNull ? 1 : 0,
121306 pCol->pDflt ? pCol->pDflt->u.zToken : 0,
121307 k,
121308 isHidden);
121309 }
121310 }
121311 }
121312 break;
121313
@@ -120864,10 +121341,11 @@
121341 case PragTyp_INDEX_INFO: if( zRight ){
121342 Index *pIdx;
121343 Table *pTab;
121344 pIdx = sqlite3FindIndex(db, zRight, zDb);
121345 if( pIdx ){
121346 int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
121347 int i;
121348 int mx;
121349 if( pPragma->iArg ){
121350 /* PRAGMA index_xinfo (newer version with more rows and columns) */
121351 mx = pIdx->nColumn;
@@ -120876,11 +121354,11 @@
121354 /* PRAGMA index_info (legacy version) */
121355 mx = pIdx->nKeyCol;
121356 pParse->nMem = 3;
121357 }
121358 pTab = pIdx->pTable;
121359 sqlite3CodeVerifySchema(pParse, iIdxDb);
121360 assert( pParse->nMem<=pPragma->nPragCName );
121361 for(i=0; i<mx; i++){
121362 i16 cnum = pIdx->aiColumn[i];
121363 sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum,
121364 cnum<0 ? 0 : pTab->aCol[cnum].zName);
@@ -120900,12 +121378,13 @@
121378 Index *pIdx;
121379 Table *pTab;
121380 int i;
121381 pTab = sqlite3FindTable(db, zRight, zDb);
121382 if( pTab ){
121383 int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
121384 pParse->nMem = 5;
121385 sqlite3CodeVerifySchema(pParse, iTabDb);
121386 for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
121387 const char *azOrigin[] = { "c", "u", "pk" };
121388 sqlite3VdbeMultiLoad(v, 1, "isisi",
121389 i,
121390 pIdx->zName,
@@ -120948,10 +121427,11 @@
121427 HashElem *j;
121428 FuncDef *p;
121429 pParse->nMem = 2;
121430 for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
121431 for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
121432 if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
121433 sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
121434 }
121435 }
121436 for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
121437 p = (FuncDef*)sqliteHashData(j);
@@ -120989,13 +121469,14 @@
121469 Table *pTab;
121470 pTab = sqlite3FindTable(db, zRight, zDb);
121471 if( pTab ){
121472 pFK = pTab->pFKey;
121473 if( pFK ){
121474 int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
121475 int i = 0;
121476 pParse->nMem = 8;
121477 sqlite3CodeVerifySchema(pParse, iTabDb);
121478 while(pFK){
121479 int j;
121480 for(j=0; j<pFK->nCol; j++){
121481 sqlite3VdbeMultiLoad(v, 1, "iissssss",
121482 i,
@@ -121036,36 +121517,38 @@
121517
121518 regResult = pParse->nMem+1;
121519 pParse->nMem += 4;
121520 regKey = ++pParse->nMem;
121521 regRow = ++pParse->nMem;
 
121522 k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
121523 while( k ){
121524 int iTabDb;
121525 if( zRight ){
121526 pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
121527 k = 0;
121528 }else{
121529 pTab = (Table*)sqliteHashData(k);
121530 k = sqliteHashNext(k);
121531 }
121532 if( pTab==0 || pTab->pFKey==0 ) continue;
121533 iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
121534 sqlite3CodeVerifySchema(pParse, iTabDb);
121535 sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
121536 if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
121537 sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
121538 sqlite3VdbeLoadString(v, regResult, pTab->zName);
121539 for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
121540 pParent = sqlite3FindTable(db, pFK->zTo, zDb);
121541 if( pParent==0 ) continue;
121542 pIdx = 0;
121543 sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
121544 x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
121545 if( x==0 ){
121546 if( pIdx==0 ){
121547 sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
121548 }else{
121549 sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb);
121550 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
121551 }
121552 }else{
121553 k = 0;
121554 break;
@@ -121830,16 +122313,28 @@
122313 break;
122314 }
122315 #endif
122316
122317 #ifdef SQLITE_HAS_CODEC
122318 /* Pragma iArg
122319 ** ---------- ------
122320 ** key 0
122321 ** rekey 1
122322 ** hexkey 2
122323 ** hexrekey 3
122324 ** textkey 4
122325 ** textrekey 5
122326 */
122327 case PragTyp_KEY: {
122328 if( zRight ){
122329 int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
122330 if( (pPragma->iArg & 1)==0 ){
122331 sqlite3_key_v2(db, zDb, zRight, n);
122332 }else{
122333 sqlite3_rekey_v2(db, zDb, zRight, n);
122334 }
122335 }
122336 break;
122337 }
122338 case PragTyp_HEXKEY: {
122339 if( zRight ){
122340 u8 iByte;
@@ -121847,11 +122342,11 @@
122342 char zKey[40];
122343 for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
122344 iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
122345 if( (i&1)!=0 ) zKey[i/2] = iByte;
122346 }
122347 if( (pPragma->iArg & 1)==0 ){
122348 sqlite3_key_v2(db, zDb, zKey, i/2);
122349 }else{
122350 sqlite3_rekey_v2(db, zDb, zKey, i/2);
122351 }
122352 }
@@ -122177,11 +122672,12 @@
122672 0, /* xRollback - rollback transaction */
122673 0, /* xFindFunction - function overloading */
122674 0, /* xRename - rename the table */
122675 0, /* xSavepoint */
122676 0, /* xRelease */
122677 0, /* xRollbackTo */
122678 0 /* xShadowName */
122679 };
122680
122681 /*
122682 ** Check to see if zTabName is really the name of a pragma. If it is,
122683 ** then register an eponymous virtual table for that pragma and return
@@ -122530,12 +123026,12 @@
123026 }
123027 if( db->mallocFailed ){
123028 rc = SQLITE_NOMEM_BKPT;
123029 sqlite3ResetAllSchemasOfConnection(db);
123030 }
123031 if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
123032 /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
123033 ** the schema loaded, even if errors occurred. In this situation the
123034 ** current sqlite3_prepare() operation will fail, but the following one
123035 ** will attempt to compile the supplied statement against whatever subset
123036 ** of the schema was loaded before the error occurred. The primary
123037 ** purpose of this is to allow access to the sqlite_master table
@@ -122912,10 +123408,298 @@
123408 assert( (rc&db->errMask)==rc );
123409 sqlite3_mutex_leave(db->mutex);
123410 return rc;
123411 }
123412
123413 #ifdef SQLITE_ENABLE_NORMALIZE
123414 /*
123415 ** Checks if the specified token is a table, column, or function name,
123416 ** based on the databases associated with the statement being prepared.
123417 ** If the function fails, zero is returned and pRc is filled with the
123418 ** error code.
123419 */
123420 static int shouldTreatAsIdentifier(
123421 sqlite3 *db, /* Database handle. */
123422 const char *zToken, /* Pointer to start of token to be checked */
123423 int nToken, /* Length of token to be checked */
123424 int *pRc /* Pointer to error code upon failure */
123425 ){
123426 int bFound = 0; /* Non-zero if token is an identifier name. */
123427 int i, j; /* Database and column loop indexes. */
123428 Schema *pSchema; /* Schema for current database. */
123429 Hash *pHash; /* Hash table of tables for current database. */
123430 HashElem *e; /* Hash element for hash table iteration. */
123431 Table *pTab; /* Database table for columns being checked. */
123432
123433 if( sqlite3IsRowidN(zToken, nToken) ){
123434 return 1;
123435 }
123436 if( nToken>0 ){
123437 int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
123438 if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
123439 }
123440 assert( db!=0 );
123441 sqlite3_mutex_enter(db->mutex);
123442 sqlite3BtreeEnterAll(db);
123443 for(i=0; i<db->nDb; i++){
123444 pHash = &db->aFunc;
123445 if( sqlite3HashFindN(pHash, zToken, nToken) ){
123446 bFound = 1;
123447 break;
123448 }
123449 pSchema = db->aDb[i].pSchema;
123450 if( pSchema==0 ) continue;
123451 pHash = &pSchema->tblHash;
123452 if( sqlite3HashFindN(pHash, zToken, nToken) ){
123453 bFound = 1;
123454 break;
123455 }
123456 for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
123457 pTab = sqliteHashData(e);
123458 if( pTab==0 ) continue;
123459 pHash = pTab->pColHash;
123460 if( pHash==0 ){
123461 pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
123462 if( pHash ){
123463 sqlite3HashInit(pHash);
123464 for(j=0; j<pTab->nCol; j++){
123465 Column *pCol = &pTab->aCol[j];
123466 sqlite3HashInsert(pHash, pCol->zName, pCol);
123467 }
123468 }else{
123469 *pRc = SQLITE_NOMEM_BKPT;
123470 bFound = 0;
123471 goto done;
123472 }
123473 }
123474 if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
123475 bFound = 1;
123476 goto done;
123477 }
123478 }
123479 }
123480 done:
123481 sqlite3BtreeLeaveAll(db);
123482 sqlite3_mutex_leave(db->mutex);
123483 return bFound;
123484 }
123485
123486 /*
123487 ** Attempt to estimate the final output buffer size needed for the fully
123488 ** normalized version of the specified SQL string. This should take into
123489 ** account any potential expansion that could occur (e.g. via IN clauses
123490 ** being expanded, etc). This size returned is the total number of bytes
123491 ** including the NUL terminator.
123492 */
123493 static int estimateNormalizedSize(
123494 const char *zSql, /* The original SQL string */
123495 int nSql, /* Length of original SQL string */
123496 u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
123497 ){
123498 int nOut = nSql + 4;
123499 const char *z = zSql;
123500 while( nOut<nSql*5 ){
123501 while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; }
123502 if( z[0]==0 ) break;
123503 z++;
123504 if( z[0]!='N' && z[0]!='n' ) break;
123505 z++;
123506 while( sqlite3Isspace(z[0]) ){ z++; }
123507 if( z[0]!='(' ) break;
123508 z++;
123509 nOut += 5; /* ?,?,? */
123510 }
123511 return nOut;
123512 }
123513
123514 /*
123515 ** Copy the current token into the output buffer while dealing with quoted
123516 ** identifiers. By default, all letters will be converted into lowercase.
123517 ** If the bUpper flag is set, uppercase will be used. The piOut argument
123518 ** will be used to update the target index into the output string.
123519 */
123520 static void copyNormalizedToken(
123521 const char *zSql, /* The original SQL string */
123522 int iIn, /* Current index into the original SQL string */
123523 int nToken, /* Number of bytes in the current token */
123524 int tokenFlags, /* Flags returned by the tokenizer */
123525 char *zOut, /* The output string */
123526 int *piOut /* Pointer to target index into the output string */
123527 ){
123528 int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED;
123529 int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD;
123530 int j = *piOut, k = 0;
123531 for(; k<nToken; k++){
123532 if( bQuoted ){
123533 if( k==0 && iIn>0 ){
123534 zOut[j++] = '"';
123535 continue;
123536 }else if( k==nToken-1 ){
123537 zOut[j++] = '"';
123538 continue;
123539 }
123540 }
123541 if( bKeyword ){
123542 zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
123543 }else{
123544 zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
123545 }
123546 }
123547 *piOut = j;
123548 }
123549
123550 /*
123551 ** Perform normalization of the SQL contained in the prepared statement and
123552 ** store the result in the zNormSql field. The schema for the associated
123553 ** databases are consulted while performing the normalization in order to
123554 ** determine if a token appears to be an identifier. All identifiers are
123555 ** left intact in the normalized SQL and all literals are replaced with a
123556 ** single '?'.
123557 */
123558 SQLITE_PRIVATE void sqlite3Normalize(
123559 Vdbe *pVdbe, /* VM being reprepared */
123560 const char *zSql, /* The original SQL string */
123561 int nSql, /* Size of the input string in bytes */
123562 u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
123563 ){
123564 sqlite3 *db; /* Database handle. */
123565 char *z; /* The output string */
123566 int nZ; /* Size of the output string in bytes */
123567 int i; /* Next character to read from zSql[] */
123568 int j; /* Next character to fill in on z[] */
123569 int tokenType = 0; /* Type of the next token */
123570 int prevTokenType = 0; /* Type of the previous token, except spaces */
123571 int n; /* Size of the next token */
123572 int nParen = 0; /* Nesting level of parenthesis */
123573 Hash inHash; /* Table of parenthesis levels to output index. */
123574
123575 db = sqlite3VdbeDb(pVdbe);
123576 assert( db!=0 );
123577 assert( pVdbe->zNormSql==0 );
123578 if( zSql==0 ) return;
123579 nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
123580 z = sqlite3DbMallocRawNN(db, nZ);
123581 if( z==0 ) return;
123582 sqlite3HashInit(&inHash);
123583 for(i=j=0; i<nSql && zSql[i]; i+=n){
123584 int flags = 0;
123585 if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
123586 n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
123587 switch( tokenType ){
123588 case TK_SPACE: {
123589 break;
123590 }
123591 case TK_ILLEGAL: {
123592 sqlite3DbFree(db, z);
123593 sqlite3HashClear(&inHash);
123594 return;
123595 }
123596 case TK_STRING:
123597 case TK_INTEGER:
123598 case TK_FLOAT:
123599 case TK_VARIABLE:
123600 case TK_BLOB: {
123601 z[j++] = '?';
123602 break;
123603 }
123604 case TK_LP:
123605 case TK_RP: {
123606 if( tokenType==TK_LP ){
123607 nParen++;
123608 if( prevTokenType==TK_IN ){
123609 assert( nParen<nSql );
123610 sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
123611 }
123612 }else{
123613 int jj;
123614 assert( nParen<nSql );
123615 jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
123616 if( jj>0 ){
123617 sqlite3HashInsert(&inHash, zSql+nParen, 0);
123618 assert( jj+6<nZ );
123619 memcpy(z+jj+1, "?,?,?", 5);
123620 j = jj+6;
123621 assert( nZ-1-j>=0 );
123622 assert( nZ-1-j<nZ );
123623 memset(z+j, 0, nZ-1-j);
123624 }
123625 nParen--;
123626 }
123627 assert( nParen>=0 );
123628 /* Fall through */
123629 }
123630 case TK_MINUS:
123631 case TK_SEMI:
123632 case TK_PLUS:
123633 case TK_STAR:
123634 case TK_SLASH:
123635 case TK_REM:
123636 case TK_EQ:
123637 case TK_LE:
123638 case TK_NE:
123639 case TK_LSHIFT:
123640 case TK_LT:
123641 case TK_RSHIFT:
123642 case TK_GT:
123643 case TK_GE:
123644 case TK_BITOR:
123645 case TK_CONCAT:
123646 case TK_COMMA:
123647 case TK_BITAND:
123648 case TK_BITNOT:
123649 case TK_DOT:
123650 case TK_IN:
123651 case TK_IS:
123652 case TK_NOT:
123653 case TK_NULL:
123654 case TK_ID: {
123655 if( tokenType==TK_NULL ){
123656 if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
123657 /* NULL is a keyword in this case, not a literal value */
123658 }else{
123659 /* Here the NULL is a literal value */
123660 z[j++] = '?';
123661 break;
123662 }
123663 }
123664 if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
123665 z[j++] = ' ';
123666 }
123667 if( tokenType==TK_ID ){
123668 int i2 = i, n2 = n, rc = SQLITE_OK;
123669 if( nParen>0 ){
123670 assert( nParen<nSql );
123671 sqlite3HashInsert(&inHash, zSql+nParen, 0);
123672 }
123673 if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
123674 if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
123675 if( rc!=SQLITE_OK ){
123676 sqlite3DbFree(db, z);
123677 sqlite3HashClear(&inHash);
123678 return;
123679 }
123680 if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
123681 z[j++] = '?';
123682 break;
123683 }
123684 }
123685 }
123686 copyNormalizedToken(zSql, i, n, flags, z, &j);
123687 break;
123688 }
123689 }
123690 }
123691 assert( j<nZ && "one" );
123692 while( j>0 && z[j-1]==' ' ){ j--; }
123693 if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
123694 z[j] = 0;
123695 assert( j<nZ && "two" );
123696 pVdbe->zNormSql = z;
123697 sqlite3HashClear(&inHash);
123698 }
123699 #endif /* SQLITE_ENABLE_NORMALIZE */
123700
123701 /*
123702 ** Rerun the compilation of a statement after a schema change.
123703 **
123704 ** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
123705 ** if the statement cannot be recompiled because another connection has
@@ -123924,11 +124708,11 @@
124708 ExprList *pExtra = 0;
124709 for(i=0; i<pEList->nExpr; i++){
124710 struct ExprList_item *pItem = &pEList->a[i];
124711 if( pItem->u.x.iOrderByCol==0 ){
124712 Expr *pExpr = pItem->pExpr;
124713 Table *pTab = pExpr->y.pTab;
124714 if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
124715 && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
124716 ){
124717 int j;
124718 for(j=0; j<nDefer; j++){
@@ -123947,16 +124731,16 @@
124731 }
124732 for(k=0; k<nKey; k++){
124733 Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
124734 if( pNew ){
124735 pNew->iTable = pExpr->iTable;
124736 pNew->y.pTab = pExpr->y.pTab;
124737 pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
124738 pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
124739 }
124740 }
124741 pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
124742 pSort->aDefer[nDefer].iCsr = pExpr->iTable;
124743 pSort->aDefer[nDefer].nKey = nKey;
124744 nDefer++;
124745 }
124746 }
@@ -124801,11 +125585,11 @@
125585 ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
125586 ** branch below. */
125587 break;
125588 }
125589
125590 assert( pTab && pExpr->y.pTab==pTab );
125591 if( pS ){
125592 /* The "table" is actually a sub-select or a view in the FROM clause
125593 ** of the SELECT statement. Return the declaration type and origin
125594 ** data for the result-set column of the sub-select.
125595 */
@@ -124986,19 +125770,19 @@
125770 for(i=0; i<pEList->nExpr; i++){
125771 Expr *p = pEList->a[i].pExpr;
125772
125773 assert( p!=0 );
125774 assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
125775 assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
125776 if( pEList->a[i].zName ){
125777 /* An AS clause always takes first priority */
125778 char *zName = pEList->a[i].zName;
125779 sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
125780 }else if( srcName && p->op==TK_COLUMN ){
125781 char *zCol;
125782 int iCol = p->iColumn;
125783 pTab = p->y.pTab;
125784 assert( pTab!=0 );
125785 if( iCol<0 ) iCol = pTab->iPKey;
125786 assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
125787 if( iCol<0 ){
125788 zCol = "rowid";
@@ -125085,11 +125869,11 @@
125869 }
125870 assert( pColExpr->op!=TK_AGG_COLUMN );
125871 if( pColExpr->op==TK_COLUMN ){
125872 /* For columns use the column name name */
125873 int iCol = pColExpr->iColumn;
125874 Table *pTab = pColExpr->y.pTab;
125875 assert( pTab!=0 );
125876 if( iCol<0 ) iCol = pTab->iPKey;
125877 zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
125878 }else if( pColExpr->op==TK_ID ){
125879 assert( !ExprHasProperty(pColExpr, EP_IntValue) );
@@ -125438,10 +126222,17 @@
126222 int i; /* Loop counter */
126223 int rc; /* Result code */
126224 ExprList *pOrderBy; /* The ORDER BY clause */
126225 Expr *pLimit; /* Saved LIMIT and OFFSET */
126226 int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
126227
126228 #ifndef SQLITE_OMIT_WINDOWFUNC
126229 if( p->pWin ){
126230 sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
126231 return;
126232 }
126233 #endif
126234
126235 /* Obtain authorization to do a recursive query */
126236 if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
126237
126238 /* Process the LIMIT and OFFSET clauses, if they exist */
@@ -127188,11 +127979,11 @@
127979 return 1;
127980 }
127981 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
127982
127983 /*
127984 ** A structure to keep track of all of the column values that are fixed to
127985 ** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
127986 */
127987 typedef struct WhereConst WhereConst;
127988 struct WhereConst {
127989 Parse *pParse; /* Parsing context */
@@ -127200,17 +127991,32 @@
127991 int nChng; /* Number of times a constant is propagated */
127992 Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
127993 };
127994
127995 /*
127996 ** Add a new entry to the pConst object. Except, do not add duplicate
127997 ** pColumn entires.
127998 */
127999 static void constInsert(
128000 WhereConst *pConst, /* The WhereConst into which we are inserting */
128001 Expr *pColumn, /* The COLUMN part of the constraint */
128002 Expr *pValue /* The VALUE part of the constraint */
128003 ){
128004 int i;
128005 assert( pColumn->op==TK_COLUMN );
128006
128007 /* 2018-10-25 ticket [cf5ed20f]
128008 ** Make sure the same pColumn is not inserted more than once */
128009 for(i=0; i<pConst->nConst; i++){
128010 const Expr *pExpr = pConst->apExpr[i*2];
128011 assert( pExpr->op==TK_COLUMN );
128012 if( pExpr->iTable==pColumn->iTable
128013 && pExpr->iColumn==pColumn->iColumn
128014 ){
128015 return; /* Already present. Return without doing anything. */
128016 }
128017 }
128018
128019 pConst->nConst++;
128020 pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
128021 pConst->nConst*2*sizeof(Expr*));
128022 if( pConst->apExpr==0 ){
@@ -131187,10 +131993,61 @@
131993 if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
131994 sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
131995 }
131996 #endif
131997 }
131998
131999 /*
132000 ** Check to see if column iCol of index pIdx references any of the
132001 ** columns defined by aXRef and chngRowid. Return true if it does
132002 ** and false if not. This is an optimization. False-positives are a
132003 ** performance degradation, but false-negatives can result in a corrupt
132004 ** index and incorrect answers.
132005 **
132006 ** aXRef[j] will be non-negative if column j of the original table is
132007 ** being updated. chngRowid will be true if the rowid of the table is
132008 ** being updated.
132009 */
132010 static int indexColumnIsBeingUpdated(
132011 Index *pIdx, /* The index to check */
132012 int iCol, /* Which column of the index to check */
132013 int *aXRef, /* aXRef[j]>=0 if column j is being updated */
132014 int chngRowid /* true if the rowid is being updated */
132015 ){
132016 i16 iIdxCol = pIdx->aiColumn[iCol];
132017 assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
132018 if( iIdxCol>=0 ){
132019 return aXRef[iIdxCol]>=0;
132020 }
132021 assert( iIdxCol==XN_EXPR );
132022 assert( pIdx->aColExpr!=0 );
132023 assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
132024 return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
132025 aXRef,chngRowid);
132026 }
132027
132028 /*
132029 ** Check to see if index pIdx is a partial index whose conditional
132030 ** expression might change values due to an UPDATE. Return true if
132031 ** the index is subject to change and false if the index is guaranteed
132032 ** to be unchanged. This is an optimization. False-positives are a
132033 ** performance degradation, but false-negatives can result in a corrupt
132034 ** index and incorrect answers.
132035 **
132036 ** aXRef[j] will be non-negative if column j of the original table is
132037 ** being updated. chngRowid will be true if the rowid of the table is
132038 ** being updated.
132039 */
132040 static int indexWhereClauseMightChange(
132041 Index *pIdx, /* The index to check */
132042 int *aXRef, /* aXRef[j]>=0 if column j is being updated */
132043 int chngRowid /* true if the rowid is being updated */
132044 ){
132045 if( pIdx->pPartIdxWhere==0 ) return 0;
132046 return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
132047 aXRef, chngRowid);
132048 }
132049
132050 /*
132051 ** Process an UPDATE statement.
132052 **
132053 ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
@@ -131411,23 +132268,22 @@
132268 hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
132269
132270 /* There is one entry in the aRegIdx[] array for each index on the table
132271 ** being updated. Fill in aRegIdx[] with a register number that will hold
132272 ** the key for accessing each index.
 
 
132273 */
132274 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
132275 int reg;
132276 if( chngKey || hasFK>1 || pIdx==pPk
132277 || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
132278 ){
132279 reg = ++pParse->nMem;
132280 pParse->nMem += pIdx->nColumn;
132281 }else{
132282 reg = 0;
132283 for(i=0; i<pIdx->nKeyCol; i++){
132284 if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
 
132285 reg = ++pParse->nMem;
132286 pParse->nMem += pIdx->nColumn;
132287 if( (onError==OE_Replace)
132288 || (onError==OE_Default && pIdx->onError==OE_Replace)
132289 ){
@@ -131972,11 +132828,11 @@
132828 for(i=0; i<pTab->nCol; i++){
132829 if( aXRef[i]>=0 ){
132830 sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
132831 }else{
132832 sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
132833 sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
132834 }
132835 }
132836 if( HasRowid(pTab) ){
132837 sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
132838 if( pRowid ){
@@ -132473,11 +133329,12 @@
133329 saved_nChange = db->nChange;
133330 saved_nTotalChange = db->nTotalChange;
133331 saved_mTrace = db->mTrace;
133332 db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
133333 db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
133334 db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder
133335 | SQLITE_Defensive | SQLITE_CountRows);
133336 db->mTrace = 0;
133337
133338 zDbMain = db->aDb[iDb].zDbSName;
133339 pMain = db->aDb[iDb].pBt;
133340 isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
@@ -133015,22 +133872,19 @@
133872 Token *pName1, /* Name of new table, or database name */
133873 Token *pName2, /* Name of new table or NULL */
133874 Token *pModuleName, /* Name of the module for the virtual table */
133875 int ifNotExists /* No error if the table already exists */
133876 ){
 
133877 Table *pTable; /* The new virtual table */
133878 sqlite3 *db; /* Database connection */
133879
133880 sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
133881 pTable = pParse->pNewTable;
133882 if( pTable==0 ) return;
133883 assert( 0==pTable->pIndex );
133884
133885 db = pParse->db;
 
 
133886
133887 assert( pTable->nModuleArg==0 );
133888 addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
133889 addModuleArgument(db, pTable, 0);
133890 addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
@@ -133046,10 +133900,12 @@
133900 ** The first invocation, to obtain permission to INSERT a row into the
133901 ** sqlite_master table, has already been made by sqlite3StartTable().
133902 ** The second call, to obtain permission to create the table, is made now.
133903 */
133904 if( pTable->azModuleArg ){
133905 int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
133906 assert( iDb>=0 ); /* The database the table is being created in */
133907 sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
133908 pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
133909 }
133910 #endif
133911 }
@@ -133740,11 +134596,11 @@
134596 int rc = 0;
134597
134598 /* Check to see the left operand is a column in a virtual table */
134599 if( NEVER(pExpr==0) ) return pDef;
134600 if( pExpr->op!=TK_COLUMN ) return pDef;
134601 pTab = pExpr->y.pTab;
134602 if( pTab==0 ) return pDef;
134603 if( !IsVirtual(pTab) ) return pDef;
134604 pVtab = sqlite3GetVTable(db, pTab)->pVtab;
134605 assert( pVtab!=0 );
134606 assert( pVtab->pModule!=0 );
@@ -134360,15 +135216,36 @@
135216 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
135217 UnpackedRecord *pRec; /* Probe for stat4 (if required) */
135218 int nRecValid; /* Number of valid fields currently in pRec */
135219 #endif
135220 unsigned int bldFlags; /* SQLITE_BLDF_* flags */
135221 unsigned int iPlanLimit; /* Search limiter */
135222 };
135223
135224 /* Allowed values for WhereLoopBuider.bldFlags */
135225 #define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
135226 #define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
135227
135228 /* The WhereLoopBuilder.iPlanLimit is used to limit the number of
135229 ** index+constraint combinations the query planner will consider for a
135230 ** particular query. If this parameter is unlimited, then certain
135231 ** pathological queries can spend excess time in the sqlite3WhereBegin()
135232 ** routine. The limit is high enough that is should not impact real-world
135233 ** queries.
135234 **
135235 ** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is
135236 ** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
135237 ** clause is processed, so that every table in a join is guaranteed to be
135238 ** able to propose a some index+constraint combinations even if the initial
135239 ** baseline limit was exhausted by prior tables of the join.
135240 */
135241 #ifndef SQLITE_QUERY_PLANNER_LIMIT
135242 # define SQLITE_QUERY_PLANNER_LIMIT 20000
135243 #endif
135244 #ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
135245 # define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
135246 #endif
135247
135248 /*
135249 ** The WHERE clause processing routine has two halves. The
135250 ** first part does the start of the WHERE loop and the second
135251 ** half does the tail of the WHERE loop. An instance of
@@ -134927,11 +135804,11 @@
135804 Select *pSelect; /* Pointer to the SELECT on the RHS */
135805
135806 for(i=iEq; i<pLoop->nLTerm; i++){
135807 if( pLoop->aLTerm[i]->pExpr==pX ){
135808 int iField = pLoop->aLTerm[i]->iField - 1;
135809 if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
135810 pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
135811 pOrigRhs->a[iField].pExpr = 0;
135812 assert( pOrigLhs->a[iField].pExpr!=0 );
135813 pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
135814 pOrigLhs->a[iField].pExpr = 0;
@@ -135619,11 +136496,11 @@
136496 IdxExprTrans *pX = p->u.pIdxTrans;
136497 if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
136498 pExpr->op = TK_COLUMN;
136499 pExpr->iTable = pX->iIdxCur;
136500 pExpr->iColumn = pX->iIdxCol;
136501 pExpr->y.pTab = 0;
136502 return WRC_Prune;
136503 }else{
136504 return WRC_Continue;
136505 }
136506 }
@@ -137019,11 +137896,11 @@
137896 || zNew[0]=='-'
137897 || (zNew[0]+1=='0' && iTo==1)
137898 ){
137899 if( pLeft->op!=TK_COLUMN
137900 || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
137901 || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
137902 ){
137903 sqlite3ExprDelete(db, pPrefix);
137904 sqlite3ValueFree(pVal);
137905 return 0;
137906 }
@@ -137120,11 +137997,11 @@
137997 **
137998 ** vtab_column MATCH expression
137999 ** MATCH(expression,vtab_column)
138000 */
138001 pCol = pList->a[1].pExpr;
138002 if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
138003 for(i=0; i<ArraySize(aOp); i++){
138004 if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
138005 *peOp2 = aOp[i].eOp2;
138006 *ppRight = pList->a[0].pExpr;
138007 *ppLeft = pCol;
@@ -137142,16 +138019,16 @@
138019 ** Historically, xFindFunction expected to see lower-case function
138020 ** names. But for this use case, xFindFunction is expected to deal
138021 ** with function names in an arbitrary case.
138022 */
138023 pCol = pList->a[0].pExpr;
138024 if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
138025 sqlite3_vtab *pVtab;
138026 sqlite3_module *pMod;
138027 void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
138028 void *pNotUsed;
138029 pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
138030 assert( pVtab!=0 );
138031 assert( pVtab->pModule!=0 );
138032 pMod = (sqlite3_module *)pVtab->pModule;
138033 if( pMod->xFindFunction!=0 ){
138034 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
@@ -137165,14 +138042,14 @@
138042 }
138043 }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
138044 int res = 0;
138045 Expr *pLeft = pExpr->pLeft;
138046 Expr *pRight = pExpr->pRight;
138047 if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
138048 res++;
138049 }
138050 if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
138051 res++;
138052 SWAP(Expr*, pLeft, pRight);
138053 }
138054 *ppLeft = pLeft;
138055 *ppRight = pRight;
@@ -138120,10 +138997,11 @@
138997 ** Note that the virtual term must be tagged with TERM_VNULL.
138998 */
138999 if( pExpr->op==TK_NOTNULL
139000 && pExpr->pLeft->op==TK_COLUMN
139001 && pExpr->pLeft->iColumn>=0
139002 && !ExprHasProperty(pExpr, EP_FromJoin)
139003 && OptimizationEnabled(db, SQLITE_Stat34)
139004 ){
139005 Expr *pNewExpr;
139006 Expr *pLeft = pExpr->pLeft;
139007 int idxNew;
@@ -138311,10 +139189,11 @@
139189 pTab = pItem->pTab;
139190 assert( pTab!=0 );
139191 pArgs = pItem->u1.pFuncArg;
139192 if( pArgs==0 ) return;
139193 for(j=k=0; j<pArgs->nExpr; j++){
139194 Expr *pRhs;
139195 while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
139196 if( k>=pTab->nCol ){
139197 sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
139198 pTab->zName, j);
139199 return;
@@ -138321,13 +139200,14 @@
139200 }
139201 pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
139202 if( pColRef==0 ) return;
139203 pColRef->iTable = pItem->iCursor;
139204 pColRef->iColumn = k++;
139205 pColRef->y.pTab = pTab;
139206 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
139207 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
139208 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
139209 whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
139210 }
139211 }
139212
139213 /************** End of whereexpr.c *******************************************/
@@ -139186,11 +140066,10 @@
140066 sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
140067 testcase( pParse->db->mallocFailed );
140068 translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
140069 pTabItem->regResult, 1);
140070 sqlite3VdbeGoto(v, addrTop);
 
140071 }else{
140072 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
140073 }
140074 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
140075 sqlite3VdbeJumpHere(v, addrTop);
@@ -139364,13 +140243,15 @@
140243 ** The table object reference passed as the second argument to this function
140244 ** must represent a virtual table. This function invokes the xBestIndex()
140245 ** method of the virtual table with the sqlite3_index_info object that
140246 ** comes in as the 3rd argument to this function.
140247 **
140248 ** If an error occurs, pParse is populated with an error message and an
140249 ** appropriate error code is returned. A return of SQLITE_CONSTRAINT from
140250 ** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that
140251 ** the current configuration of "unusable" flags in sqlite3_index_info can
140252 ** not result in a valid plan.
140253 **
140254 ** Whether or not an error is returned, it is the responsibility of the
140255 ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
140256 ** that this is required.
140257 */
@@ -139380,11 +140261,11 @@
140261
140262 TRACE_IDX_INPUTS(p);
140263 rc = pVtab->pModule->xBestIndex(pVtab, p);
140264 TRACE_IDX_OUTPUTS(p);
140265
140266 if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
140267 if( rc==SQLITE_NOMEM ){
140268 sqlite3OomFault(pParse->db);
140269 }else if( !pVtab->zErrMsg ){
140270 sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
140271 }else{
@@ -139391,23 +140272,11 @@
140272 sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
140273 }
140274 }
140275 sqlite3_free(pVtab->zErrMsg);
140276 pVtab->zErrMsg = 0;
140277 return rc;
 
 
 
 
 
 
 
 
 
 
 
 
140278 }
140279 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
140280
140281 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
140282 /*
@@ -140457,10 +141326,18 @@
141326 static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
141327 WhereLoop **ppPrev, *p;
141328 WhereInfo *pWInfo = pBuilder->pWInfo;
141329 sqlite3 *db = pWInfo->pParse->db;
141330 int rc;
141331
141332 /* Stop the search once we hit the query planner search limit */
141333 if( pBuilder->iPlanLimit==0 ){
141334 WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
141335 if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
141336 return SQLITE_DONE;
141337 }
141338 pBuilder->iPlanLimit--;
141339
141340 /* If pBuilder->pOrSet is defined, then only keep track of the costs
141341 ** and prereqs.
141342 */
141343 if( pBuilder->pOrSet!=0 ){
@@ -141468,11 +142345,21 @@
142345 pIdxInfo->idxFlags = 0;
142346 pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
142347
142348 /* Invoke the virtual table xBestIndex() method */
142349 rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
142350 if( rc ){
142351 if( rc==SQLITE_CONSTRAINT ){
142352 /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
142353 ** that the particular combination of parameters provided is unusable.
142354 ** Make no entries in the loop table.
142355 */
142356 WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n"));
142357 return SQLITE_OK;
142358 }
142359 return rc;
142360 }
142361
142362 mxTerm = -1;
142363 assert( pNew->nLSlot>=nConstraint );
142364 for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
142365 pNew->u.vtab.omitMask = 0;
@@ -141864,13 +142751,15 @@
142751 u8 priorJointype = 0;
142752
142753 /* Loop over the tables in the join, from left to right */
142754 pNew = pBuilder->pNew;
142755 whereLoopInit(pNew);
142756 pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
142757 for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
142758 Bitmask mUnusable = 0;
142759 pNew->iTab = iTab;
142760 pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
142761 pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
142762 if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
142763 /* This condition is true when pItem is the FROM clause term on the
142764 ** right-hand-side of a LEFT or CROSS JOIN. */
142765 mPrereq = mPrior;
@@ -141892,11 +142781,19 @@
142781 }
142782 if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
142783 rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
142784 }
142785 mPrior |= pNew->maskSelf;
142786 if( rc || db->mallocFailed ){
142787 if( rc==SQLITE_DONE ){
142788 /* We hit the query planner search limit set by iPlanLimit */
142789 sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
142790 rc = SQLITE_OK;
142791 }else{
142792 break;
142793 }
142794 }
142795 }
142796
142797 whereLoopClear(db, pNew);
142798 return rc;
142799 }
@@ -144274,16 +145171,16 @@
145171 }
145172
145173 switch( pExpr->op ){
145174
145175 case TK_FUNCTION:
145176 if( !ExprHasProperty(pExpr, EP_WinFunc) ){
145177 break;
145178 }else{
145179 Window *pWin;
145180 for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
145181 if( pExpr->y.pWin==pWin ){
145182 assert( pWin->pOwner==pExpr );
145183 return WRC_Prune;
145184 }
145185 }
145186 }
@@ -144396,11 +145293,11 @@
145293 ** are invoked in the correct order as described under "SELECT REWRITING"
145294 ** at the top of this file.
145295 */
145296 SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
145297 int rc = SQLITE_OK;
145298 if( p->pWin && p->pPrior==0 ){
145299 Vdbe *v = sqlite3GetVdbe(pParse);
145300 sqlite3 *db = pParse->db;
145301 Select *pSub = 0; /* The subquery */
145302 SrcList *pSrc = p->pSrc;
145303 Expr *pWhere = p->pWhere;
@@ -144609,15 +145506,17 @@
145506 /*
145507 ** Attach window object pWin to expression p.
145508 */
145509 SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
145510 if( p ){
145511 assert( p->op==TK_FUNCTION );
145512 /* This routine is only called for the parser. If pWin was not
145513 ** allocated due to an OOM, then the parser would fail before ever
145514 ** invoking this routine */
145515 if( ALWAYS(pWin) ){
145516 p->y.pWin = pWin;
145517 ExprSetProperty(p, EP_WinFunc);
145518 pWin->pOwner = p;
145519 if( p->flags & EP_Distinct ){
145520 sqlite3ErrorMsg(pParse,
145521 "DISTINCT is not supported for window functions");
145522 }
@@ -145776,11 +146675,11 @@
146675 ** third argument. Set the Window.pOwner field of the new object to
146676 ** pOwner.
146677 */
146678 SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
146679 Window *pNew = 0;
146680 if( ALWAYS(p) ){
146681 pNew = sqlite3DbMallocZero(db, sizeof(Window));
146682 if( pNew ){
146683 pNew->zName = sqlite3DbStrDup(db, p->zName);
146684 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
146685 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
@@ -145928,10 +146827,11 @@
146827 **
146828 ** The following is the concatenation of all %include directives from the
146829 ** input grammar file:
146830 */
146831 /* #include <stdio.h> */
146832 /* #include <assert.h> */
146833 /************ Begin %include sections from the grammar ************************/
146834
146835 /* #include "sqliteInt.h" */
146836
146837 /*
@@ -146029,17 +146929,14 @@
146929 p->flags = EP_Leaf;
146930 p->iAgg = -1;
146931 p->pLeft = p->pRight = 0;
146932 p->x.pList = 0;
146933 p->pAggInfo = 0;
146934 p->y.pTab = 0;
146935 p->op2 = 0;
146936 p->iTable = 0;
146937 p->iColumn = 0;
 
 
 
146938 p->u.zToken = (char*)&p[1];
146939 memcpy(p->u.zToken, t.z, t.n);
146940 p->u.zToken[t.n] = 0;
146941 if( sqlite3Isquote(p->u.zToken[0]) ){
146942 if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
@@ -150227,14 +151124,13 @@
151124 #endif
151125 yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
151126 yymajor = YYNOCODE;
151127 }else{
151128 while( yypParser->yytos >= yypParser->yystack
 
151129 && (yyact = yy_find_reduce_action(
151130 yypParser->yytos->stateno,
151131 YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
151132 ){
151133 yy_pop_parser_stack(yypParser);
151134 }
151135 if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
151136 yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
@@ -151197,10 +152093,77 @@
152093 while( IdChar(z[i]) ){ i++; }
152094 *tokenType = TK_ID;
152095 return i;
152096 }
152097
152098 #ifdef SQLITE_ENABLE_NORMALIZE
152099 /*
152100 ** Return the length (in bytes) of the token that begins at z[0].
152101 ** Store the token type in *tokenType before returning. If flags has
152102 ** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
152103 ** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was
152104 ** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags
152105 ** if the token was recognized as a keyword; this is useful when the
152106 ** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
152107 ** to differentiate between a keyword being treated as an identifier
152108 ** (for normalization purposes) and an actual identifier.
152109 */
152110 SQLITE_PRIVATE int sqlite3GetTokenNormalized(
152111 const unsigned char *z,
152112 int *tokenType,
152113 int *flags
152114 ){
152115 int n;
152116 unsigned char iClass = aiClass[*z];
152117 if( iClass==CC_KYWD ){
152118 int i;
152119 for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
152120 if( IdChar(z[i]) ){
152121 /* This token started out using characters that can appear in keywords,
152122 ** but z[i] is a character not allowed within keywords, so this must
152123 ** be an identifier instead */
152124 i++;
152125 while( IdChar(z[i]) ){ i++; }
152126 *tokenType = TK_ID;
152127 return i;
152128 }
152129 *tokenType = TK_ID;
152130 n = keywordCode((char*)z, i, tokenType);
152131 /* If the token is no longer considered to be an identifier, then it is a
152132 ** keyword of some kind. Make the token back into an identifier and then
152133 ** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are
152134 ** used verbatim, including IN, IS, NOT, and NULL. */
152135 switch( *tokenType ){
152136 case TK_ID: {
152137 /* do nothing, handled by caller */
152138 break;
152139 }
152140 case TK_IN:
152141 case TK_IS:
152142 case TK_NOT:
152143 case TK_NULL: {
152144 *flags |= SQLITE_TOKEN_KEYWORD;
152145 break;
152146 }
152147 default: {
152148 *tokenType = TK_ID;
152149 *flags |= SQLITE_TOKEN_KEYWORD;
152150 break;
152151 }
152152 }
152153 }else{
152154 n = sqlite3GetToken(z, tokenType);
152155 /* If the token is considered to be an identifier and the character class
152156 ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
152157 if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
152158 *flags |= SQLITE_TOKEN_QUOTED;
152159 }
152160 }
152161 return n;
152162 }
152163 #endif /* SQLITE_ENABLE_NORMALIZE */
152164
152165 /*
152166 ** Run the parser on the given SQL string. The parser structure is
152167 ** passed in. An SQLITE_ status code is returned. If an error occurs
152168 ** then an and attempt is made to write an error message into
152169 ** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
@@ -152594,10 +153557,11 @@
153557 { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
153558 { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
153559 { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
153560 { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
153561 { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
153562 { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
153563 };
153564 unsigned int i;
153565 rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
153566 for(i=0; i<ArraySize(aFlagOp); i++){
153567 if( aFlagOp[i].op==op ){
@@ -154821,10 +155785,13 @@
155785 | SQLITE_Fts3Tokenizer
155786 #endif
155787 #if defined(SQLITE_ENABLE_QPSG)
155788 | SQLITE_EnableQPSG
155789 #endif
155790 #if defined(SQLITE_DEFAULT_DEFENSIVE)
155791 | SQLITE_Defensive
155792 #endif
155793 ;
155794 sqlite3HashInit(&db->aCollSeq);
155795 #ifndef SQLITE_OMIT_VIRTUALTABLE
155796 sqlite3HashInit(&db->aModule);
155797 #endif
@@ -155708,18 +156675,29 @@
156675 break;
156676 }
156677
156678 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
156679 **
156680 ** If parameter onoff is non-zero, subsequent calls to localtime()
156681 ** and its variants fail. If onoff is zero, undo this setting.
 
156682 */
156683 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
156684 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
156685 break;
156686 }
156687
156688 /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
156689 **
156690 ** If parameter onoff is non-zero, internal-use-only SQL functions
156691 ** are visible to ordinary SQL. This is useful for testing but is
156692 ** unsafe because invalid parameters to those internal-use-only functions
156693 ** can result in crashes or segfaults.
156694 */
156695 case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
156696 sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
156697 break;
156698 }
156699
156700 /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
156701 **
156702 ** Set or clear a flag that indicates that the database file is always well-
156703 ** formed and never corrupt. This flag is clear by default, indicating that
@@ -159159,11 +160137,11 @@
160137 ){
160138 int rc = SQLITE_OK; /* Return code */
160139 const char *zCsr = zNode; /* Cursor to iterate through node */
160140 const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
160141 char *zBuffer = 0; /* Buffer to load terms into */
160142 i64 nAlloc = 0; /* Size of allocated buffer */
160143 int isFirstTerm = 1; /* True when processing first term on page */
160144 sqlite3_int64 iChild; /* Block id of child node to descend to */
160145
160146 /* Skip over the 'height' varint that occurs at the start of every
160147 ** interior node. Then load the blockid of the left-child of the b-tree
@@ -159197,18 +160175,18 @@
160175 }
160176 isFirstTerm = 0;
160177 zCsr += fts3GetVarint32(zCsr, &nSuffix);
160178
160179 assert( nPrefix>=0 && nSuffix>=0 );
160180 if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
160181 rc = FTS_CORRUPT_VTAB;
160182 goto finish_scan;
160183 }
160184 if( (i64)nPrefix+nSuffix>nAlloc ){
160185 char *zNew;
160186 nAlloc = ((i64)nPrefix+nSuffix) * 2;
160187 zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
160188 if( !zNew ){
160189 rc = SQLITE_NOMEM;
160190 goto finish_scan;
160191 }
160192 zBuffer = zNew;
@@ -161183,13 +162161,28 @@
162161 assert( p->mxSavepoint >= iSavepoint );
162162 TESTONLY( p->mxSavepoint = iSavepoint );
162163 sqlite3Fts3PendingTermsClear(p);
162164 return SQLITE_OK;
162165 }
162166
162167 /*
162168 ** Return true if zName is the extension on one of the shadow tables used
162169 ** by this module.
162170 */
162171 static int fts3ShadowName(const char *zName){
162172 static const char *azName[] = {
162173 "content", "docsize", "segdir", "segments", "stat",
162174 };
162175 unsigned int i;
162176 for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
162177 if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
162178 }
162179 return 0;
162180 }
162181
162182 static const sqlite3_module fts3Module = {
162183 /* iVersion */ 3,
162184 /* xCreate */ fts3CreateMethod,
162185 /* xConnect */ fts3ConnectMethod,
162186 /* xBestIndex */ fts3BestIndexMethod,
162187 /* xDisconnect */ fts3DisconnectMethod,
162188 /* xDestroy */ fts3DestroyMethod,
@@ -161208,10 +162201,11 @@
162201 /* xFindFunction */ fts3FindFunctionMethod,
162202 /* xRename */ fts3RenameMethod,
162203 /* xSavepoint */ fts3SavepointMethod,
162204 /* xRelease */ fts3ReleaseMethod,
162205 /* xRollbackTo */ fts3RollbackToMethod,
162206 /* xShadowName */ fts3ShadowName,
162207 };
162208
162209 /*
162210 ** This function is registered as the module destructor (called when an
162211 ** FTS3 enabled database connection is closed). It frees the memory
@@ -161488,10 +162482,11 @@
162482 }
162483
162484 return rc;
162485 }
162486
162487 #ifndef SQLITE_DISABLE_FTS4_DEFERRED
162488 /*
162489 ** This function is called on each phrase after the position lists for
162490 ** any deferred tokens have been loaded into memory. It updates the phrases
162491 ** current position list to include only those positions that are really
162492 ** instances of the phrase (after considering deferred tokens). If this
@@ -161591,10 +162586,11 @@
162586 }
162587 }
162588
162589 return SQLITE_OK;
162590 }
162591 #endif /* SQLITE_DISABLE_FTS4_DEFERRED */
162592
162593 /*
162594 ** Maximum number of tokens a phrase may have to be considered for the
162595 ** incremental doclists strategy.
162596 */
@@ -163839,11 +164835,12 @@
164835 0, /* xRollback */
164836 0, /* xFindFunction */
164837 0, /* xRename */
164838 0, /* xSavepoint */
164839 0, /* xRelease */
164840 0, /* xRollbackTo */
164841 0 /* xShadowName */
164842 };
164843 int rc; /* Return code */
164844
164845 rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
164846 return rc;
@@ -167398,11 +168395,12 @@
168395 0, /* xRollback */
168396 0, /* xFindFunction */
168397 0, /* xRename */
168398 0, /* xSavepoint */
168399 0, /* xRelease */
168400 0, /* xRollbackTo */
168401 0 /* xShadowName */
168402 };
168403 int rc; /* Return code */
168404
168405 rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
168406 return rc;
@@ -168786,19 +169784,23 @@
169784
169785 /* Because of the FTS3_NODE_PADDING bytes of padding, the following is
169786 ** safe (no risk of overread) even if the node data is corrupted. */
169787 pNext += fts3GetVarint32(pNext, &nPrefix);
169788 pNext += fts3GetVarint32(pNext, &nSuffix);
169789 if( nSuffix<=0
169790 || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
169791 || nPrefix>pReader->nTermAlloc
169792 ){
169793 return FTS_CORRUPT_VTAB;
169794 }
169795
169796 /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
169797 ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
169798 ** overflow - hence the (i64) casts. */
169799 if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
169800 i64 nNew = ((i64)nPrefix+nSuffix)*2;
169801 char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
169802 if( !zNew ){
169803 return SQLITE_NOMEM;
169804 }
169805 pReader->zTerm = zNew;
169806 pReader->nTermAlloc = nNew;
@@ -168816,11 +169818,11 @@
169818
169819 /* Check that the doclist does not appear to extend past the end of the
169820 ** b-tree node. And that the final byte of the doclist is 0x00. If either
169821 ** of these statements is untrue, then the data structure is corrupt.
169822 */
169823 if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
169824 || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
169825 ){
169826 return FTS_CORRUPT_VTAB;
169827 }
169828 return SQLITE_OK;
@@ -171142,25 +172144,30 @@
172144 if( bFirst==0 ){
172145 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
172146 }
172147 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
172148
172149 if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
172150 return SQLITE_CORRUPT_VTAB;
172151 }
172152 blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
172153 if( rc==SQLITE_OK ){
172154 memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
172155 p->term.n = nPrefix+nSuffix;
172156 p->iOff += nSuffix;
172157 if( p->iChild==0 ){
172158 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
172159 if( (p->nNode-p->iOff)<p->nDoclist ){
172160 return SQLITE_CORRUPT_VTAB;
172161 }
172162 p->aDoclist = &p->aNode[p->iOff];
172163 p->iOff += p->nDoclist;
172164 }
172165 }
172166 }
172167
172168 assert( p->iOff<=p->nNode );
 
172169 return rc;
172170 }
172171
172172 /*
172173 ** Release all dynamic resources held by node-reader object *p.
@@ -177566,10 +178573,13 @@
178573 #define JEACH_ATOM 3
178574 #define JEACH_ID 4
178575 #define JEACH_PARENT 5
178576 #define JEACH_FULLKEY 6
178577 #define JEACH_PATH 7
178578 /* The xBestIndex method assumes that the JSON and ROOT columns are
178579 ** the last two columns in the table. Should this ever changes, be
178580 ** sure to update the xBestIndex method. */
178581 #define JEACH_JSON 8
178582 #define JEACH_ROOT 9
178583
178584 UNUSED_PARAM(pzErr);
178585 UNUSED_PARAM(argv);
@@ -177823,39 +178833,58 @@
178833 */
178834 static int jsonEachBestIndex(
178835 sqlite3_vtab *tab,
178836 sqlite3_index_info *pIdxInfo
178837 ){
178838 int i; /* Loop counter or computed array index */
178839 int aIdx[2]; /* Index of constraints for JSON and ROOT */
178840 int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */
178841 int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */
178842 const struct sqlite3_index_constraint *pConstraint;
178843
178844 /* This implementation assumes that JSON and ROOT are the last two
178845 ** columns in the table */
178846 assert( JEACH_ROOT == JEACH_JSON+1 );
178847 UNUSED_PARAM(tab);
178848 aIdx[0] = aIdx[1] = -1;
178849 pConstraint = pIdxInfo->aConstraint;
178850 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
178851 int iCol;
178852 int iMask;
178853 if( pConstraint->iColumn < JEACH_JSON ) continue;
178854 iCol = pConstraint->iColumn - JEACH_JSON;
178855 assert( iCol==0 || iCol==1 );
178856 iMask = 1 << iCol;
178857 if( pConstraint->usable==0 ){
178858 unusableMask |= iMask;
178859 }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
178860 aIdx[iCol] = i;
178861 idxMask |= iMask;
178862 }
178863 }
178864 if( (unusableMask & ~idxMask)!=0 ){
178865 /* If there are any unusable constraints on JSON or ROOT, then reject
178866 ** this entire plan */
178867 return SQLITE_CONSTRAINT;
178868 }
178869 if( aIdx[0]<0 ){
178870 /* No JSON input. Leave estimatedCost at the huge value that it was
178871 ** initialized to to discourage the query planner from selecting this
178872 ** plan. */
178873 pIdxInfo->idxNum = 0;
 
178874 }else{
178875 pIdxInfo->estimatedCost = 1.0;
178876 i = aIdx[0];
178877 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
178878 pIdxInfo->aConstraintUsage[i].omit = 1;
178879 if( aIdx[1]<0 ){
178880 pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
178881 }else{
178882 i = aIdx[1];
178883 pIdxInfo->aConstraintUsage[i].argvIndex = 2;
178884 pIdxInfo->aConstraintUsage[i].omit = 1;
178885 pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
178886 }
178887 }
178888 return SQLITE_OK;
178889 }
178890
@@ -177960,11 +178989,12 @@
178989 0, /* xRollback */
178990 0, /* xFindMethod */
178991 0, /* xRename */
178992 0, /* xSavepoint */
178993 0, /* xRelease */
178994 0, /* xRollbackTo */
178995 0 /* xShadowName */
178996 };
178997
178998 /* The methods of the json_tree virtual table. */
178999 static sqlite3_module jsonTreeModule = {
179000 0, /* iVersion */
@@ -177987,11 +179017,12 @@
179017 0, /* xRollback */
179018 0, /* xFindMethod */
179019 0, /* xRename */
179020 0, /* xSavepoint */
179021 0, /* xRelease */
179022 0, /* xRollbackTo */
179023 0 /* xShadowName */
179024 };
179025 #endif /* SQLITE_OMIT_VIRTUALTABLE */
179026
179027 /****************************************************************************
179028 ** The following routines are the only publically visible identifiers in this
@@ -181417,12 +182448,28 @@
182448 }
182449
182450 return rc;
182451 }
182452
182453
182454 /*
182455 ** Return true if zName is the extension on one of the shadow tables used
182456 ** by this module.
182457 */
182458 static int rtreeShadowName(const char *zName){
182459 static const char *azName[] = {
182460 "node", "parent", "rowid"
182461 };
182462 unsigned int i;
182463 for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
182464 if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
182465 }
182466 return 0;
182467 }
182468
182469 static sqlite3_module rtreeModule = {
182470 3, /* iVersion */
182471 rtreeCreate, /* xCreate - create a table */
182472 rtreeConnect, /* xConnect - connect to an existing table */
182473 rtreeBestIndex, /* xBestIndex - Determine search strategy */
182474 rtreeDisconnect, /* xDisconnect - Disconnect from a table */
182475 rtreeDestroy, /* xDestroy - Drop a table */
@@ -181441,10 +182488,11 @@
182488 0, /* xFindFunction - function overloading */
182489 rtreeRename, /* xRename - rename the table */
182490 rtreeSavepoint, /* xSavepoint */
182491 0, /* xRelease */
182492 0, /* xRollbackTo */
182493 rtreeShadowName /* xShadowName */
182494 };
182495
182496 static int rtreeSqlInit(
182497 Rtree *pRtree,
182498 sqlite3 *db,
@@ -182431,17 +183479,27 @@
183479 ** The on-disk representation consists of a 4-byte header followed by
183480 ** the values. The 4-byte header is:
183481 **
183482 ** encoding (1 byte) 0=big-endian, 1=little-endian
183483 ** nvertex (3 bytes) Number of vertexes as a big-endian integer
183484 **
183485 ** Enough space is allocated for 4 coordinates, to work around over-zealous
183486 ** warnings coming from some compiler (notably, clang). In reality, the size
183487 ** of each GeoPoly memory allocate is adjusted as necessary so that the
183488 ** GeoPoly.a[] array at the end is the appropriate size.
183489 */
183490 typedef struct GeoPoly GeoPoly;
183491 struct GeoPoly {
183492 int nVertex; /* Number of vertexes */
183493 unsigned char hdr[4]; /* Header for on-disk representation */
183494 GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */
183495 };
183496
183497 /* The size of a memory allocation needed for a GeoPoly object sufficient
183498 ** to hold N coordinate pairs.
183499 */
183500 #define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
183501
183502 /*
183503 ** State of a parse of a GeoJSON input.
183504 */
183505 typedef struct GeoParse GeoParse;
@@ -182463,11 +183521,11 @@
183521 a[2] = t;
183522 }
183523
183524 /* Skip whitespace. Return the next non-whitespace character. */
183525 static char geopolySkipSpace(GeoParse *p){
183526 while( safe_isspace(p->z[0]) ) p->z++;
183527 return p->z[0];
183528 }
183529
183530 /* Parse out a number. Write the value into *pVal if pVal!=0.
183531 ** return non-zero on success and zero if the next token is not a number.
@@ -182483,11 +183541,11 @@
183541 c = z[j];
183542 }
183543 if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
183544 for(;; j++){
183545 c = z[j];
183546 if( safe_isdigit(c) ) continue;
183547 if( c=='.' ){
183548 if( z[j-1]=='-' ) return 0;
183549 if( seenDP ) return 0;
183550 seenDP = 1;
183551 continue;
@@ -182505,11 +183563,21 @@
183563 continue;
183564 }
183565 break;
183566 }
183567 if( z[j-1]<'0' ) return 0;
183568 if( pVal ){
183569 #ifdef SQLITE_AMALGAMATION
183570 /* The sqlite3AtoF() routine is much much faster than atof(), if it
183571 ** is available */
183572 double r;
183573 (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
183574 *pVal = r;
183575 #else
183576 *pVal = (GeoCoord)atof((const char*)p->z);
183577 #endif
183578 }
183579 p->z += j;
183580 return 1;
183581 }
183582
183583 /*
@@ -182563,16 +183631,14 @@
183631 && s.nVertex>=4
183632 && s.a[0]==s.a[s.nVertex*2-2]
183633 && s.a[1]==s.a[s.nVertex*2-1]
183634 && (s.z++, geopolySkipSpace(&s)==0)
183635 ){
 
183636 GeoPoly *pOut;
183637 int x = 1;
183638 s.nVertex--; /* Remove the redundant vertex at the end */
183639 pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
 
183640 x = 1;
183641 if( pOut==0 ) goto parse_json_err;
183642 pOut->nVertex = s.nVertex;
183643 memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
183644 pOut->hdr[0] = *(unsigned char*)&x;
@@ -182770,10 +183836,31 @@
183836 sqlite3_result_blob(context, p->hdr,
183837 4+8*p->nVertex, SQLITE_TRANSIENT);
183838 sqlite3_free(p);
183839 }
183840 }
183841
183842 /*
183843 ** Compute the area enclosed by the polygon.
183844 **
183845 ** This routine can also be used to detect polygons that rotate in
183846 ** the wrong direction. Polygons are suppose to be counter-clockwise (CCW).
183847 ** This routine returns a negative value for clockwise (CW) polygons.
183848 */
183849 static double geopolyArea(GeoPoly *p){
183850 double rArea = 0.0;
183851 int ii;
183852 for(ii=0; ii<p->nVertex-1; ii++){
183853 rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
183854 * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
183855 * 0.5;
183856 }
183857 rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
183858 * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
183859 * 0.5;
183860 return rArea;
183861 }
183862
183863 /*
183864 ** Implementation of the geopoly_area(X) function.
183865 **
183866 ** If the input is a well-formed Geopoly BLOB then return the area
@@ -182786,24 +183873,109 @@
183873 int argc,
183874 sqlite3_value **argv
183875 ){
183876 GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
183877 if( p ){
183878 sqlite3_result_double(context, geopolyArea(p));
183879 sqlite3_free(p);
183880 }
183881 }
183882
183883 /*
183884 ** Implementation of the geopoly_ccw(X) function.
183885 **
183886 ** If the rotation of polygon X is clockwise (incorrect) instead of
183887 ** counter-clockwise (the correct winding order according to RFC7946)
183888 ** then reverse the order of the vertexes in polygon X.
183889 **
183890 ** In other words, this routine returns a CCW polygon regardless of the
183891 ** winding order of its input.
183892 **
183893 ** Use this routine to sanitize historical inputs that that sometimes
183894 ** contain polygons that wind in the wrong direction.
183895 */
183896 static void geopolyCcwFunc(
183897 sqlite3_context *context,
183898 int argc,
183899 sqlite3_value **argv
183900 ){
183901 GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
183902 if( p ){
183903 if( geopolyArea(p)<0.0 ){
183904 int ii, jj;
183905 for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){
183906 GeoCoord t = p->a[ii];
183907 p->a[ii] = p->a[jj];
183908 p->a[jj] = t;
183909 t = p->a[ii+1];
183910 p->a[ii+1] = p->a[jj+1];
183911 p->a[jj+1] = t;
183912 }
183913 }
183914 sqlite3_result_blob(context, p->hdr,
183915 4+8*p->nVertex, SQLITE_TRANSIENT);
183916 sqlite3_free(p);
183917 }
183918 }
183919
183920 #define GEOPOLY_PI 3.1415926535897932385
183921
183922 /* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
183923 */
183924 static double geopolySine(double r){
183925 assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
183926 if( r>=1.5*GEOPOLY_PI ){
183927 r -= 2.0*GEOPOLY_PI;
183928 }
183929 if( r>=0.5*GEOPOLY_PI ){
183930 return -geopolySine(r-GEOPOLY_PI);
183931 }else{
183932 double r2 = r*r;
183933 double r3 = r2*r;
183934 double r5 = r3*r2;
183935 return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
183936 }
183937 }
183938
183939 /*
183940 ** Function: geopoly_regular(X,Y,R,N)
183941 **
183942 ** Construct a simple, convex, regular polygon centered at X, Y
183943 ** with circumradius R and with N sides.
183944 */
183945 static void geopolyRegularFunc(
183946 sqlite3_context *context,
183947 int argc,
183948 sqlite3_value **argv
183949 ){
183950 double x = sqlite3_value_double(argv[0]);
183951 double y = sqlite3_value_double(argv[1]);
183952 double r = sqlite3_value_double(argv[2]);
183953 int n = sqlite3_value_int(argv[3]);
183954 int i;
183955 GeoPoly *p;
183956
183957 if( n<3 || r<=0.0 ) return;
183958 if( n>1000 ) n = 1000;
183959 p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
183960 if( p==0 ){
183961 sqlite3_result_error_nomem(context);
183962 return;
183963 }
183964 i = 1;
183965 p->hdr[0] = *(unsigned char*)&i;
183966 p->hdr[1] = 0;
183967 p->hdr[2] = (n>>8)&0xff;
183968 p->hdr[3] = n&0xff;
183969 for(i=0; i<n; i++){
183970 double rAngle = 2.0*GEOPOLY_PI*i/n;
183971 p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
183972 p->a[i*2+1] = y + r*geopolySine(rAngle);
183973 }
183974 sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
183975 sqlite3_free(p);
183976 }
183977
183978 /*
183979 ** If pPoly is a polygon, compute its bounding box. Then:
183980 **
183981 ** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
@@ -182845,11 +184017,11 @@
184017 else if( r>mxY ) mxY = (float)r;
184018 }
184019 if( pRc ) *pRc = SQLITE_OK;
184020 if( aCoord==0 ){
184021 geopolyBboxFill:
184022 pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
184023 if( pOut==0 ){
184024 sqlite3_free(p);
184025 if( context ) sqlite3_result_error_nomem(context);
184026 if( pRc ) *pRc = SQLITE_NOMEM;
184027 return 0;
@@ -183873,11 +185045,20 @@
185045 sqlite3_bind_int64(pUp, 1, cell.iRowid);
185046 assert( pRtree->nAux>=1 );
185047 if( sqlite3_value_nochange(aData[2]) ){
185048 sqlite3_bind_null(pUp, 2);
185049 }else{
185050 GeoPoly *p = 0;
185051 if( sqlite3_value_type(aData[2])==SQLITE_TEXT
185052 && (p = geopolyFuncParam(0, aData[2], &rc))!=0
185053 && rc==SQLITE_OK
185054 ){
185055 sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
185056 }else{
185057 sqlite3_bind_value(pUp, 2, aData[2]);
185058 }
185059 sqlite3_free(p);
185060 nChange = 1;
185061 }
185062 for(jj=1; jj<pRtree->nAux; jj++){
185063 nChange++;
185064 sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
@@ -183917,11 +185098,11 @@
185098 return 0;
185099 }
185100
185101
185102 static sqlite3_module geopolyModule = {
185103 3, /* iVersion */
185104 geopolyCreate, /* xCreate - create a table */
185105 geopolyConnect, /* xConnect - connect to an existing table */
185106 geopolyBestIndex, /* xBestIndex - Determine search strategy */
185107 rtreeDisconnect, /* xDisconnect - Disconnect from a table */
185108 rtreeDestroy, /* xDestroy - Drop a table */
@@ -183940,29 +185121,33 @@
185121 geopolyFindFunction, /* xFindFunction - function overloading */
185122 rtreeRename, /* xRename - rename the table */
185123 rtreeSavepoint, /* xSavepoint */
185124 0, /* xRelease */
185125 0, /* xRollbackTo */
185126 rtreeShadowName /* xShadowName */
185127 };
185128
185129 static int sqlite3_geopoly_init(sqlite3 *db){
185130 int rc = SQLITE_OK;
185131 static const struct {
185132 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
185133 signed char nArg;
185134 unsigned char bPure;
185135 const char *zName;
185136 } aFunc[] = {
185137 { geopolyAreaFunc, 1, 1, "geopoly_area" },
185138 { geopolyBlobFunc, 1, 1, "geopoly_blob" },
185139 { geopolyJsonFunc, 1, 1, "geopoly_json" },
185140 { geopolySvgFunc, -1, 1, "geopoly_svg" },
185141 { geopolyWithinFunc, 2, 1, "geopoly_within" },
185142 { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" },
185143 { geopolyOverlapFunc, 2, 1, "geopoly_overlap" },
185144 { geopolyDebugFunc, 1, 0, "geopoly_debug" },
185145 { geopolyBBoxFunc, 1, 1, "geopoly_bbox" },
185146 { geopolyXformFunc, 7, 1, "geopoly_xform" },
185147 { geopolyRegularFunc, 4, 1, "geopoly_regular" },
185148 { geopolyCcwFunc, 1, 1, "geopoly_ccw" },
185149 };
185150 static const struct {
185151 void (*xStep)(sqlite3_context*,int,sqlite3_value**);
185152 void (*xFinal)(sqlite3_context*);
185153 const char *zName;
@@ -183969,12 +185154,13 @@
185154 } aAgg[] = {
185155 { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" },
185156 };
185157 int i;
185158 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
185159 int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8;
185160 rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
185161 enc, 0,
185162 aFunc[i].xFunc, 0, 0);
185163 }
185164 for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
185165 rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0,
185166 0, aAgg[i].xStep, aAgg[i].xFinal);
@@ -185997,11 +187183,12 @@
187183 struct rbu_vfs {
187184 sqlite3_vfs base; /* rbu VFS shim methods */
187185 sqlite3_vfs *pRealVfs; /* Underlying VFS */
187186 sqlite3_mutex *mutex; /* Mutex to protect pMain */
187187 sqlite3rbu *pRbu; /* Owner RBU object */
187188 rbu_file *pMain; /* List of main db files */
187189 rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */
187190 };
187191
187192 /*
187193 ** Each file opened by an rbu VFS is represented by an instance of
187194 ** the following structure.
@@ -186026,10 +187213,11 @@
187213 char *zDel; /* Delete this when closing file */
187214
187215 const char *zWal; /* Wal filename for this main db file */
187216 rbu_file *pWalFd; /* Wal file descriptor for this main db */
187217 rbu_file *pMainNext; /* Next MAIN_DB file */
187218 rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */
187219 };
187220
187221 /*
187222 ** True for an RBU vacuum handle, or false otherwise.
187223 */
@@ -189621,10 +190809,73 @@
190809 pFd->sz = nNew;
190810 assert( pRbu->szTemp>=0 );
190811 if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
190812 return SQLITE_OK;
190813 }
190814
190815 /*
190816 ** Add an item to the main-db lists, if it is not already present.
190817 **
190818 ** There are two main-db lists. One for all file descriptors, and one
190819 ** for all file descriptors with rbu_file.pDb!=0. If the argument has
190820 ** rbu_file.pDb!=0, then it is assumed to already be present on the
190821 ** main list and is only added to the pDb!=0 list.
190822 */
190823 static void rbuMainlistAdd(rbu_file *p){
190824 rbu_vfs *pRbuVfs = p->pRbuVfs;
190825 rbu_file *pIter;
190826 assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
190827 sqlite3_mutex_enter(pRbuVfs->mutex);
190828 if( p->pRbu==0 ){
190829 for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
190830 p->pMainNext = pRbuVfs->pMain;
190831 pRbuVfs->pMain = p;
190832 }else{
190833 for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
190834 if( pIter==0 ){
190835 p->pMainRbuNext = pRbuVfs->pMainRbu;
190836 pRbuVfs->pMainRbu = p;
190837 }
190838 }
190839 sqlite3_mutex_leave(pRbuVfs->mutex);
190840 }
190841
190842 /*
190843 ** Remove an item from the main-db lists.
190844 */
190845 static void rbuMainlistRemove(rbu_file *p){
190846 rbu_file **pp;
190847 sqlite3_mutex_enter(p->pRbuVfs->mutex);
190848 for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
190849 if( *pp ) *pp = p->pMainNext;
190850 p->pMainNext = 0;
190851 for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
190852 if( *pp ) *pp = p->pMainRbuNext;
190853 p->pMainRbuNext = 0;
190854 sqlite3_mutex_leave(p->pRbuVfs->mutex);
190855 }
190856
190857 /*
190858 ** Given that zWal points to a buffer containing a wal file name passed to
190859 ** either the xOpen() or xAccess() VFS method, search the main-db list for
190860 ** a file-handle opened by the same database connection on the corresponding
190861 ** database file.
190862 **
190863 ** If parameter bRbu is true, only search for file-descriptors with
190864 ** rbu_file.pDb!=0.
190865 */
190866 static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
190867 rbu_file *pDb;
190868 sqlite3_mutex_enter(pRbuVfs->mutex);
190869 if( bRbu ){
190870 for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
190871 }else{
190872 for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
190873 }
190874 sqlite3_mutex_leave(pRbuVfs->mutex);
190875 return pDb;
190876 }
190877
190878 /*
190879 ** Close an rbu file.
190880 */
190881 static int rbuVfsClose(sqlite3_file *pFile){
@@ -189639,21 +190890,18 @@
190890 sqlite3_free(p->apShm);
190891 p->apShm = 0;
190892 sqlite3_free(p->zDel);
190893
190894 if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
190895 rbuMainlistRemove(p);
 
 
 
 
190896 rbuUnlockShm(p);
190897 p->pReal->pMethods->xShmUnmap(p->pReal, 0);
190898 }
190899 else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
190900 rbuUpdateTempSize(p, 0);
190901 }
190902 assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
190903
190904 /* Close the underlying file handle */
190905 rc = p->pReal->pMethods->xClose(p->pReal);
190906 return rc;
190907 }
@@ -189908,10 +191156,13 @@
191156 rc = SQLITE_ERROR;
191157 pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
191158 }else if( rc==SQLITE_NOTFOUND ){
191159 pRbu->pTargetFd = p;
191160 p->pRbu = pRbu;
191161 if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
191162 rbuMainlistAdd(p);
191163 }
191164 if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
191165 rc = SQLITE_OK;
191166 }
191167 }
191168 return rc;
@@ -190069,24 +191320,10 @@
191320 rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
191321 }
191322 return rc;
191323 }
191324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191325 /*
191326 ** A main database named zName has just been opened. The following
191327 ** function returns a pointer to a buffer owned by SQLite that contains
191328 ** the name of the *-wal file this db connection will use. SQLite
191329 ** happens to pass a pointer to this buffer when using xAccess()
@@ -190161,11 +191398,11 @@
191398 ** happens to pass a pointer to this buffer when using xAccess()
191399 ** or xOpen() to operate on the *-wal file. */
191400 pFd->zWal = rbuMainToWal(zName, flags);
191401 }
191402 else if( flags & SQLITE_OPEN_WAL ){
191403 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
191404 if( pDb ){
191405 if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
191406 /* This call is to open a *-wal file. Intead, open the *-oal. This
191407 ** code ensures that the string passed to xOpen() is terminated by a
191408 ** pair of '\0' bytes in case the VFS attempts to extract a URI
@@ -190213,14 +191450,11 @@
191450 /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
191451 ** pointer and, if the file is a main database file, link it into the
191452 ** mutex protected linked list of all such files. */
191453 pFile->pMethods = &rbuvfs_io_methods;
191454 if( flags & SQLITE_OPEN_MAIN_DB ){
191455 rbuMainlistAdd(pFd);
 
 
 
191456 }
191457 }else{
191458 sqlite3_free(pFd->zDel);
191459 }
191460
@@ -190264,11 +191498,11 @@
191498 ** causing SQLite to call xOpen() to open it. This call will also
191499 ** be intercepted (see the rbuVfsOpen() function) and the *-oal
191500 ** file opened instead.
191501 */
191502 if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
191503 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
191504 if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
191505 if( *pResOut ){
191506 rc = SQLITE_CANTOPEN;
191507 }else{
191508 sqlite3_int64 sz = 0;
@@ -190677,21 +191911,19 @@
191911 ** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
191912 */
191913 static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
191914 int i;
191915
 
 
191916 /* Look for a valid schema=? constraint. If found, change the idxNum to
191917 ** 1 and request the value of that constraint be sent to xFilter. And
191918 ** lower the cost estimate to encourage the constrained version to be
191919 ** used.
191920 */
191921 for(i=0; i<pIdxInfo->nConstraint; i++){
 
 
191922 if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
191923 if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
191924 if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
191925 pIdxInfo->idxNum = 1;
191926 pIdxInfo->estimatedCost = 1.0;
191927 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
191928 pIdxInfo->aConstraintUsage[i].omit = 1;
191929 break;
@@ -190737,18 +191969,24 @@
191969
191970 *ppCursor = (sqlite3_vtab_cursor *)pCsr;
191971 return SQLITE_OK;
191972 }
191973
191974 static void statClearCells(StatPage *p){
191975 int i;
191976 if( p->aCell ){
191977 for(i=0; i<p->nCell; i++){
191978 sqlite3_free(p->aCell[i].aOvfl);
191979 }
191980 sqlite3_free(p->aCell);
191981 }
191982 p->nCell = 0;
191983 p->aCell = 0;
191984 }
191985
191986 static void statClearPage(StatPage *p){
191987 statClearCells(p);
191988 sqlite3PagerUnref(p->pPg);
191989 sqlite3_free(p->zPath);
191990 memset(p, 0, sizeof(StatPage));
191991 }
191992
@@ -190807,26 +192045,37 @@
192045
192046 u8 *aData = sqlite3PagerGetData(p->pPg);
192047 u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
192048
192049 p->flags = aHdr[0];
192050 if( p->flags==0x0A || p->flags==0x0D ){
192051 isLeaf = 1;
192052 nHdr = 8;
192053 }else if( p->flags==0x05 || p->flags==0x02 ){
192054 isLeaf = 0;
192055 nHdr = 12;
192056 }else{
192057 goto statPageIsCorrupt;
192058 }
192059 if( p->iPgno==1 ) nHdr += 100;
192060 p->nCell = get2byte(&aHdr[3]);
192061 p->nMxPayload = 0;
192062 szPage = sqlite3BtreeGetPageSize(pBt);
 
 
192063
192064 nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
192065 nUnused += (int)aHdr[7];
192066 iOff = get2byte(&aHdr[1]);
192067 while( iOff ){
192068 int iNext;
192069 if( iOff>=szPage ) goto statPageIsCorrupt;
192070 nUnused += get2byte(&aData[iOff+2]);
192071 iNext = get2byte(&aData[iOff]);
192072 if( iNext<iOff+4 && iNext>0 ) goto statPageIsCorrupt;
192073 iOff = iNext;
192074 }
192075 p->nUnused = nUnused;
192076 p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
 
192077
192078 if( p->nCell ){
192079 int i; /* Used to iterate through cells */
192080 int nUsable; /* Usable bytes per page */
192081
@@ -190839,10 +192088,11 @@
192088
192089 for(i=0; i<p->nCell; i++){
192090 StatCell *pCell = &p->aCell[i];
192091
192092 iOff = get2byte(&aData[nHdr+i*2]);
192093 if( iOff<nHdr || iOff>=szPage ) goto statPageIsCorrupt;
192094 if( !isLeaf ){
192095 pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
192096 iOff += 4;
192097 }
192098 if( p->flags==0x05 ){
@@ -190855,17 +192105,18 @@
192105 u64 dummy;
192106 iOff += sqlite3GetVarint(&aData[iOff], &dummy);
192107 }
192108 if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
192109 getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
192110 if( nLocal<0 ) goto statPageIsCorrupt;
192111 pCell->nLocal = nLocal;
 
192112 assert( nPayload>=(u32)nLocal );
192113 assert( nLocal<=(nUsable-35) );
192114 if( nPayload>(u32)nLocal ){
192115 int j;
192116 int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
192117 if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
192118 pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
192119 pCell->nOvfl = nOvfl;
192120 pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
192121 if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
192122 pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
@@ -190885,10 +192136,15 @@
192136 }
192137 }
192138 }
192139
192140 return SQLITE_OK;
192141
192142 statPageIsCorrupt:
192143 p->flags = 0;
192144 statClearCells(p);
192145 return SQLITE_OK;
192146 }
192147
192148 /*
192149 ** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
192150 ** the current value of pCsr->iPageno.
@@ -191180,10 +192436,11 @@
192436 0, /* xFindMethod */
192437 0, /* xRename */
192438 0, /* xSavepoint */
192439 0, /* xRelease */
192440 0, /* xRollbackTo */
192441 0 /* xShadowName */
192442 };
192443 return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
192444 }
192445 #elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
192446 SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191310,13 +192567,12 @@
192567 for(i=0; i<pIdxInfo->nConstraint; i++){
192568 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
192569 if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
192570 if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
192571 if( !p->usable ){
192572 /* No solution. */
192573 return SQLITE_CONSTRAINT;
 
192574 }
192575 iPlan = 2;
192576 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
192577 pIdxInfo->aConstraintUsage[i].omit = 1;
192578 break;
@@ -191504,10 +192760,14 @@
192760 int iDb;
192761 Btree *pBt;
192762 Pager *pPager;
192763 int szPage;
192764
192765 if( pTab->db->flags & SQLITE_Defensive ){
192766 zErr = "read-only";
192767 goto update_fail;
192768 }
192769 if( argc==1 ){
192770 zErr = "cannot delete";
192771 goto update_fail;
192772 }
192773 pgno = sqlite3_value_int(argv[0]);
@@ -191594,10 +192854,11 @@
192854 0, /* xFindMethod */
192855 0, /* xRename */
192856 0, /* xSavepoint */
192857 0, /* xRelease */
192858 0, /* xRollbackTo */
192859 0 /* xShadowName */
192860 };
192861 return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
192862 }
192863 #elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
192864 SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191629,10 +192890,12 @@
192890 # define SESSIONS_STRM_CHUNK_SIZE 64
192891 # else
192892 # define SESSIONS_STRM_CHUNK_SIZE 1024
192893 # endif
192894 #endif
192895
192896 static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
192897
192898 typedef struct SessionHook SessionHook;
192899 struct SessionHook {
192900 void *pCtx;
192901 int (*xOld)(void*,int,sqlite3_value**);
@@ -191692,10 +192955,11 @@
192955 */
192956 struct sqlite3_changeset_iter {
192957 SessionInput in; /* Input buffer or stream */
192958 SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
192959 int bPatchset; /* True if this is a patchset */
192960 int bInvert; /* True to invert changeset */
192961 int rc; /* Iterator error code */
192962 sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
192963 char *zTab; /* Current table */
192964 int nCol; /* Number of columns in zTab */
192965 int op; /* Current operation */
@@ -191848,10 +193112,46 @@
193112 ** and fields associated with modified columns contain the new column values.
193113 **
193114 ** The records associated with INSERT changes are in the same format as for
193115 ** changesets. It is not possible for a record associated with an INSERT
193116 ** change to contain a field set to "undefined".
193117 **
193118 ** REBASE BLOB FORMAT:
193119 **
193120 ** A rebase blob may be output by sqlite3changeset_apply_v2() and its
193121 ** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
193122 ** existing changesets. A rebase blob contains one entry for each conflict
193123 ** resolved using either the OMIT or REPLACE strategies within the apply_v2()
193124 ** call.
193125 **
193126 ** The format used for a rebase blob is very similar to that used for
193127 ** changesets. All entries related to a single table are grouped together.
193128 **
193129 ** Each group of entries begins with a table header in changeset format:
193130 **
193131 ** 1 byte: Constant 0x54 (capital 'T')
193132 ** Varint: Number of columns in the table.
193133 ** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
193134 ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
193135 **
193136 ** Followed by one or more entries associated with the table.
193137 **
193138 ** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
193139 ** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
193140 ** record: (in the record format defined above).
193141 **
193142 ** In a rebase blob, the first field is set to SQLITE_INSERT if the change
193143 ** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
193144 ** it was a DELETE. The second field is set to 0x01 if the conflict
193145 ** resolution strategy was REPLACE, or 0x00 if it was OMIT.
193146 **
193147 ** If the change that caused the conflict was a DELETE, then the single
193148 ** record is a copy of the old.* record from the original changeset. If it
193149 ** was an INSERT, then the single record is a copy of the new.* record. If
193150 ** the conflicting change was an UPDATE, then the single record is a copy
193151 ** of the new.* record with the PK fields filled in based on the original
193152 ** old.* record.
193153 */
193154
193155 /*
193156 ** For each row modified during a session, there exists a single instance of
193157 ** this structure stored in a SessionTable.aChange[] hash table.
@@ -193398,16 +194698,16 @@
194698 ** set *pRc to SQLITE_NOMEM and return non-zero.
194699 */
194700 static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
194701 if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
194702 u8 *aNew;
194703 i64 nNew = p->nAlloc ? p->nAlloc : 128;
194704 do {
194705 nNew = nNew*2;
194706 }while( (nNew-p->nBuf)<nByte );
194707
194708 aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
194709 if( 0==aNew ){
194710 *pRc = SQLITE_NOMEM;
194711 }else{
194712 p->aBuf = aNew;
194713 p->nAlloc = nNew;
@@ -194001,16 +195301,16 @@
195301 }
195302 if( rc==SQLITE_OK ){
195303 rc = sqlite3_reset(pSel);
195304 }
195305
195306 /* If the buffer is now larger than sessions_strm_chunk_size, pass
195307 ** its contents to the xOutput() callback. */
195308 if( xOutput
195309 && rc==SQLITE_OK
195310 && buf.nBuf>nNoop
195311 && buf.nBuf>sessions_strm_chunk_size
195312 ){
195313 rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
195314 nNoop = -1;
195315 buf.nBuf = 0;
195316 }
@@ -194145,11 +195445,12 @@
195445 static int sessionChangesetStart(
195446 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
195447 int (*xInput)(void *pIn, void *pData, int *pnData),
195448 void *pIn,
195449 int nChangeset, /* Size of buffer pChangeset in bytes */
195450 void *pChangeset, /* Pointer to buffer containing changeset */
195451 int bInvert /* True to invert changeset */
195452 ){
195453 sqlite3_changeset_iter *pRet; /* Iterator to return */
195454 int nByte; /* Number of bytes to allocate for iterator */
195455
195456 assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
@@ -194165,10 +195466,11 @@
195466 pRet->in.aData = (u8 *)pChangeset;
195467 pRet->in.nData = nChangeset;
195468 pRet->in.xInput = xInput;
195469 pRet->in.pIn = pIn;
195470 pRet->in.bEof = (xInput ? 0 : 1);
195471 pRet->bInvert = bInvert;
195472
195473 /* Populate the output variable and return success. */
195474 *pp = pRet;
195475 return SQLITE_OK;
195476 }
@@ -194179,11 +195481,20 @@
195481 SQLITE_API int sqlite3changeset_start(
195482 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
195483 int nChangeset, /* Size of buffer pChangeset in bytes */
195484 void *pChangeset /* Pointer to buffer containing changeset */
195485 ){
195486 return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
195487 }
195488 SQLITE_API int sqlite3changeset_start_v2(
195489 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
195490 int nChangeset, /* Size of buffer pChangeset in bytes */
195491 void *pChangeset, /* Pointer to buffer containing changeset */
195492 int flags
195493 ){
195494 int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
195495 return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
195496 }
195497
195498 /*
195499 ** Streaming version of sqlite3changeset_start().
195500 */
@@ -194190,19 +195501,28 @@
195501 SQLITE_API int sqlite3changeset_start_strm(
195502 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
195503 int (*xInput)(void *pIn, void *pData, int *pnData),
195504 void *pIn
195505 ){
195506 return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
195507 }
195508 SQLITE_API int sqlite3changeset_start_v2_strm(
195509 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
195510 int (*xInput)(void *pIn, void *pData, int *pnData),
195511 void *pIn,
195512 int flags
195513 ){
195514 int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
195515 return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
195516 }
195517
195518 /*
195519 ** If the SessionInput object passed as the only argument is a streaming
195520 ** object and the buffer is full, discard some data to free up space.
195521 */
195522 static void sessionDiscardData(SessionInput *pIn){
195523 if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
195524 int nMove = pIn->buf.nBuf - pIn->iNext;
195525 assert( nMove>=0 );
195526 if( nMove>0 ){
195527 memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
195528 }
@@ -194221,11 +195541,11 @@
195541 */
195542 static int sessionInputBuffer(SessionInput *pIn, int nByte){
195543 int rc = SQLITE_OK;
195544 if( pIn->xInput ){
195545 while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
195546 int nNew = sessions_strm_chunk_size;
195547
195548 if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
195549 if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
195550 rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
195551 if( nNew==0 ){
@@ -194569,14 +195889,14 @@
195889 p->in.iCurrent = p->in.iNext;
195890 if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
195891 op = p->in.aData[p->in.iNext++];
195892 }
195893
195894 if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
195895 /* The first record in the changeset is not a table header. Must be a
195896 ** corrupt changeset. */
195897 assert( p->in.iNext==1 || p->zTab );
195898 return (p->rc = SQLITE_CORRUPT_BKPT);
195899 }
195900
195901 p->op = op;
195902 p->bIndirect = p->in.aData[p->in.iNext++];
@@ -194597,37 +195917,43 @@
195917 p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
195918 if( p->rc!=SQLITE_OK ) return p->rc;
195919 *paRec = &p->in.aData[p->in.iNext];
195920 p->in.iNext += *pnRec;
195921 }else{
195922 sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
195923 sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
195924
195925 /* If this is an UPDATE or DELETE, read the old.* record. */
195926 if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
195927 u8 *abPK = p->bPatchset ? p->abPK : 0;
195928 p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
195929 if( p->rc!=SQLITE_OK ) return p->rc;
195930 }
195931
195932 /* If this is an INSERT or UPDATE, read the new.* record. */
195933 if( p->op!=SQLITE_DELETE ){
195934 p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
195935 if( p->rc!=SQLITE_OK ) return p->rc;
195936 }
195937
195938 if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
195939 /* If this is an UPDATE that is part of a patchset, then all PK and
195940 ** modified fields are present in the new.* record. The old.* record
195941 ** is currently completely empty. This block shifts the PK fields from
195942 ** new.* to old.*, to accommodate the code that reads these arrays. */
195943 for(i=0; i<p->nCol; i++){
195944 assert( p->bPatchset==0 || p->apValue[i]==0 );
195945 if( p->abPK[i] ){
195946 assert( p->apValue[i]==0 );
195947 p->apValue[i] = p->apValue[i+p->nCol];
195948 if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
195949 p->apValue[i+p->nCol] = 0;
195950 }
195951 }
195952 }else if( p->bInvert ){
195953 if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
195954 else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
195955 }
195956 }
195957
195958 return SQLITE_ROW;
195959 }
@@ -194940,11 +196266,11 @@
196266 rc = SQLITE_CORRUPT_BKPT;
196267 goto finished_invert;
196268 }
196269
196270 assert( rc==SQLITE_OK );
196271 if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
196272 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
196273 sOut.nBuf = 0;
196274 if( rc!=SQLITE_OK ) goto finished_invert;
196275 }
196276 }
@@ -195019,11 +196345,12 @@
196345 u8 *abPK; /* Boolean array - true if column is in PK */
196346 int bStat1; /* True if table is sqlite_stat1 */
196347 int bDeferConstraints; /* True to defer constraints */
196348 SessionBuffer constraints; /* Deferred constraints are stored here */
196349 SessionBuffer rebase; /* Rebase information (if any) here */
196350 u8 bRebaseStarted; /* If table header is already in rebase */
196351 u8 bRebase; /* True to collect rebase information */
196352 };
196353
196354 /*
196355 ** Formulate a statement to DELETE a row from database db. Assuming a table
196356 ** structure like this:
@@ -195416,39 +196743,40 @@
196743 SessionApplyCtx *p, /* Apply context */
196744 int eType, /* Conflict resolution (OMIT or REPLACE) */
196745 sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
196746 ){
196747 int rc = SQLITE_OK;
196748 if( p->bRebase ){
196749 int i;
196750 int eOp = pIter->op;
196751 if( p->bRebaseStarted==0 ){
196752 /* Append a table-header to the rebase buffer */
196753 const char *zTab = pIter->zTab;
196754 sessionAppendByte(&p->rebase, 'T', &rc);
196755 sessionAppendVarint(&p->rebase, p->nCol, &rc);
196756 sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
196757 sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
196758 p->bRebaseStarted = 1;
196759 }
196760
196761 assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
196762 assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
196763
196764 sessionAppendByte(&p->rebase,
196765 (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
196766 );
196767 sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
196768 for(i=0; i<p->nCol; i++){
196769 sqlite3_value *pVal = 0;
196770 if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
196771 sqlite3changeset_old(pIter, i, &pVal);
196772 }else{
196773 sqlite3changeset_new(pIter, i, &pVal);
196774 }
196775 sessionAppendValue(&p->rebase, pVal, &rc);
196776 }
196777 }
196778 return rc;
196779 }
196780
196781 /*
196782 ** Invoke the conflict handler for the change that the changeset iterator
@@ -195787,11 +197115,11 @@
197115 while( pApply->constraints.nBuf ){
197116 sqlite3_changeset_iter *pIter2 = 0;
197117 SessionBuffer cons = pApply->constraints;
197118 memset(&pApply->constraints, 0, sizeof(SessionBuffer));
197119
197120 rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
197121 if( rc==SQLITE_OK ){
197122 int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
197123 int rc2;
197124 pIter2->bPatchset = bPatchset;
197125 pIter2->zTab = (char*)zTab;
@@ -195853,10 +197181,11 @@
197181
197182 assert( xConflict!=0 );
197183
197184 pIter->in.bNoDiscard = 1;
197185 memset(&sApply, 0, sizeof(sApply));
197186 sApply.bRebase = (ppRebase && pnRebase);
197187 sqlite3_mutex_enter(sqlite3_db_mutex(db));
197188 if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
197189 rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
197190 }
197191 if( rc==SQLITE_OK ){
@@ -196003,11 +197332,12 @@
197332 sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
197333 sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
197334 }
197335 }
197336
197337 assert( sApply.bRebase || sApply.rebase.nBuf==0 );
197338 if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
197339 *ppRebase = (void*)sApply.rebase.aBuf;
197340 *pnRebase = sApply.rebase.nBuf;
197341 sApply.rebase.aBuf = 0;
197342 }
197343 sqlite3_finalize(sApply.pInsert);
@@ -196041,11 +197371,12 @@
197371 void *pCtx, /* First argument passed to xConflict */
197372 void **ppRebase, int *pnRebase,
197373 int flags
197374 ){
197375 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
197376 int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
197377 int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
197378 if( rc==SQLITE_OK ){
197379 rc = sessionChangesetApply(
197380 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
197381 );
197382 }
@@ -196098,11 +197429,12 @@
197429 void *pCtx, /* First argument passed to xConflict */
197430 void **ppRebase, int *pnRebase,
197431 int flags
197432 ){
197433 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
197434 int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
197435 int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
197436 if( rc==SQLITE_OK ){
197437 rc = sessionChangesetApply(
197438 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
197439 );
197440 }
@@ -196471,17 +197803,16 @@
197803 SessionChange *p;
197804 for(p=pTab->apChange[i]; p; p=p->pNext){
197805 sessionAppendByte(&buf, p->op, &rc);
197806 sessionAppendByte(&buf, p->bIndirect, &rc);
197807 sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
197808 if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
197809 rc = xOutput(pOut, buf.aBuf, buf.nBuf);
197810 buf.nBuf = 0;
197811 }
197812 }
197813 }
 
 
 
 
 
197814 }
197815
197816 if( rc==SQLITE_OK ){
197817 if( xOutput ){
197818 if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
@@ -196868,11 +198199,11 @@
198199 if( bDone==0 ){
198200 sessionAppendByte(&sOut, pIter->op, &rc);
198201 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
198202 sessionAppendBlob(&sOut, aRec, nRec, &rc);
198203 }
198204 if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
198205 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
198206 sOut.nBuf = 0;
198207 }
198208 if( rc ) break;
198209 }
@@ -196978,10 +198309,31 @@
198309 if( p ){
198310 sessionDeleteTable(p->grp.pList);
198311 sqlite3_free(p);
198312 }
198313 }
198314
198315 /*
198316 ** Global configuration
198317 */
198318 SQLITE_API int sqlite3session_config(int op, void *pArg){
198319 int rc = SQLITE_OK;
198320 switch( op ){
198321 case SQLITE_SESSION_CONFIG_STRMSIZE: {
198322 int *pInt = (int*)pArg;
198323 if( *pInt>0 ){
198324 sessions_strm_chunk_size = *pInt;
198325 }
198326 *pInt = sessions_strm_chunk_size;
198327 break;
198328 }
198329 default:
198330 rc = SQLITE_MISUSE;
198331 break;
198332 }
198333 return rc;
198334 }
198335
198336 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
198337
198338 /************** End of sqlite3session.c **************************************/
198339 /************** Begin file fts5.c ********************************************/
@@ -198413,10 +199765,11 @@
199765 **
199766 ** The following is the concatenation of all %include directives from the
199767 ** input grammar file:
199768 */
199769 /* #include <stdio.h> */
199770 /* #include <assert.h> */
199771 /************ Begin %include sections from the grammar ************************/
199772
199773 /* #include "fts5Int.h" */
199774 /* #include "fts5parse.h" */
199775
@@ -199740,14 +201093,13 @@
201093 #endif
201094 fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
201095 fts5yymajor = fts5YYNOCODE;
201096 }else{
201097 while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
 
201098 && (fts5yyact = fts5yy_find_reduce_action(
201099 fts5yypParser->fts5yytos->stateno,
201100 fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE
201101 ){
201102 fts5yy_pop_parser_stack(fts5yypParser);
201103 }
201104 if( fts5yypParser->fts5yytos < fts5yypParser->fts5yystack || fts5yymajor==0 ){
201105 fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
@@ -210693,11 +212045,11 @@
212045 sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
212046 pRet = 0;
212047 fts5CloseReader(p);
212048 }
212049
212050 *ppIter = (Fts5IndexIter*)pRet;
212051 sqlite3Fts5BufferFree(&buf);
212052 }
212053 return fts5IndexReturn(p);
212054 }
212055
@@ -214442,16 +215794,31 @@
215794 int nArg, /* Number of args */
215795 sqlite3_value **apUnused /* Function arguments */
215796 ){
215797 assert( nArg==0 );
215798 UNUSED_PARAM2(nArg, apUnused);
215799 sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT);
215800 }
215801
215802 /*
215803 ** Return true if zName is the extension on one of the shadow tables used
215804 ** by this module.
215805 */
215806 static int fts5ShadowName(const char *zName){
215807 static const char *azName[] = {
215808 "config", "content", "data", "docsize", "idx"
215809 };
215810 unsigned int i;
215811 for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
215812 if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
215813 }
215814 return 0;
215815 }
215816
215817 static int fts5Init(sqlite3 *db){
215818 static const sqlite3_module fts5Mod = {
215819 /* iVersion */ 3,
215820 /* xCreate */ fts5CreateMethod,
215821 /* xConnect */ fts5ConnectMethod,
215822 /* xBestIndex */ fts5BestIndexMethod,
215823 /* xDisconnect */ fts5DisconnectMethod,
215824 /* xDestroy */ fts5DestroyMethod,
@@ -214470,10 +215837,11 @@
215837 /* xFindFunction */ fts5FindFunctionMethod,
215838 /* xRename */ fts5RenameMethod,
215839 /* xSavepoint */ fts5SavepointMethod,
215840 /* xRelease */ fts5ReleaseMethod,
215841 /* xRollbackTo */ fts5RollbackToMethod,
215842 /* xShadowName */ fts5ShadowName
215843 };
215844
215845 int rc;
215846 Fts5Global *pGlobal = 0;
215847
@@ -218514,20 +219882,22 @@
219882 int rc = SQLITE_OK;
219883 Fts5IndexIter *pIter = pCsr->pIter;
219884 i64 *pp = &pCsr->iInstPos;
219885 int *po = &pCsr->iInstOff;
219886
219887 assert( sqlite3Fts5IterEof(pIter)==0 );
219888 assert( pCsr->bEof==0 );
219889 while( eDetail==FTS5_DETAIL_NONE
219890 || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
219891 ){
219892 pCsr->iInstPos = 0;
219893 pCsr->iInstOff = 0;
219894
219895 rc = sqlite3Fts5IterNextScan(pCsr->pIter);
219896 if( rc==SQLITE_OK ){
219897 rc = fts5VocabInstanceNewTerm(pCsr);
219898 if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
219899 }
219900 if( rc ){
219901 pCsr->bEof = 1;
219902 break;
219903 }
@@ -218838,17 +220208,16 @@
220208 /* xFindFunction */ 0,
220209 /* xRename */ 0,
220210 /* xSavepoint */ 0,
220211 /* xRelease */ 0,
220212 /* xRollbackTo */ 0,
220213 /* xShadowName */ 0
220214 };
220215 void *p = (void*)pGlobal;
220216
220217 return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
220218 }
 
 
220219
220220
220221
220222 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
220223
@@ -219120,10 +220489,11 @@
220489 0, /* xFindMethod */
220490 0, /* xRename */
220491 0, /* xSavepoint */
220492 0, /* xRelease */
220493 0, /* xRollbackTo */
220494 0, /* xShadowName */
220495 };
220496
220497 #endif /* SQLITE_OMIT_VIRTUALTABLE */
220498
220499 SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){
@@ -219152,12 +220522,12 @@
220522 }
220523 #endif /* SQLITE_CORE */
220524 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
220525
220526 /************** End of stmt.c ************************************************/
220527 #if __LINE__!=220527
220528 #undef SQLITE_SOURCE_ID
220529 #define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2"
220530 #endif
220531 /* Return the source-id for this library */
220532 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
220533 /************************** End of sqlite3.c ******************************/
220534
+130 -12
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -121,13 +121,13 @@
121121
**
122122
** See also: [sqlite3_libversion()],
123123
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124124
** [sqlite_version()] and [sqlite_source_id()].
125125
*/
126
-#define SQLITE_VERSION "3.25.2"
127
-#define SQLITE_VERSION_NUMBER 3025002
128
-#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
126
+#define SQLITE_VERSION "3.26.0"
127
+#define SQLITE_VERSION_NUMBER 3026000
128
+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
129129
130130
/*
131131
** CAPI3REF: Run-Time Library Version Numbers
132132
** KEYWORDS: sqlite3_version sqlite3_sourceid
133133
**
@@ -2015,10 +2015,11 @@
20152015
** the call worked. ^The [sqlite3_db_config()] interface will return a
20162016
** non-zero [error code] if a discontinued or unsupported configuration option
20172017
** is invoked.
20182018
**
20192019
** <dl>
2020
+** [[SQLITE_DBCONFIG_LOOKASIDE]]
20202021
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
20212022
** <dd> ^This option takes three additional arguments that determine the
20222023
** [lookaside memory allocator] configuration for the [database connection].
20232024
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
20242025
** pointer to a memory buffer to use for lookaside memory.
@@ -2037,10 +2038,11 @@
20372038
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
20382039
** Any attempt to change the lookaside memory configuration when lookaside
20392040
** memory is in use leaves the configuration unchanged and returns
20402041
** [SQLITE_BUSY].)^</dd>
20412042
**
2043
+** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
20422044
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
20432045
** <dd> ^This option is used to enable or disable the enforcement of
20442046
** [foreign key constraints]. There should be two additional arguments.
20452047
** The first argument is an integer which is 0 to disable FK enforcement,
20462048
** positive to enable FK enforcement or negative to leave FK enforcement
@@ -2047,10 +2049,11 @@
20472049
** unchanged. The second parameter is a pointer to an integer into which
20482050
** is written 0 or 1 to indicate whether FK enforcement is off or on
20492051
** following this call. The second parameter may be a NULL pointer, in
20502052
** which case the FK enforcement setting is not reported back. </dd>
20512053
**
2054
+** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
20522055
** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
20532056
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
20542057
** There should be two additional arguments.
20552058
** The first argument is an integer which is 0 to disable triggers,
20562059
** positive to enable triggers or negative to leave the setting unchanged.
@@ -2057,10 +2060,11 @@
20572060
** The second parameter is a pointer to an integer into which
20582061
** is written 0 or 1 to indicate whether triggers are disabled or enabled
20592062
** following this call. The second parameter may be a NULL pointer, in
20602063
** which case the trigger setting is not reported back. </dd>
20612064
**
2065
+** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
20622066
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
20632067
** <dd> ^This option is used to enable or disable the two-argument
20642068
** version of the [fts3_tokenizer()] function which is part of the
20652069
** [FTS3] full-text search engine extension.
20662070
** There should be two additional arguments.
@@ -2070,10 +2074,11 @@
20702074
** The second parameter is a pointer to an integer into which
20712075
** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
20722076
** following this call. The second parameter may be a NULL pointer, in
20732077
** which case the new setting is not reported back. </dd>
20742078
**
2079
+** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
20752080
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
20762081
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
20772082
** interface independently of the [load_extension()] SQL function.
20782083
** The [sqlite3_enable_load_extension()] API enables or disables both the
20792084
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -2087,19 +2092,20 @@
20872092
** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
20882093
** is disabled or enabled following this call. The second parameter may
20892094
** be a NULL pointer, in which case the new setting is not reported back.
20902095
** </dd>
20912096
**
2092
-** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
2097
+** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
20932098
** <dd> ^This option is used to change the name of the "main" database
20942099
** schema. ^The sole argument is a pointer to a constant UTF8 string
20952100
** which will become the new schema name in place of "main". ^SQLite
20962101
** does not make a copy of the new main schema name string, so the application
20972102
** must ensure that the argument passed into this DBCONFIG option is unchanged
20982103
** until after the database connection closes.
20992104
** </dd>
21002105
**
2106
+** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
21012107
** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
21022108
** <dd> Usually, when a database in wal mode is closed or detached from a
21032109
** database handle, SQLite checks if this will mean that there are now no
21042110
** connections at all to the database. If so, it performs a checkpoint
21052111
** operation before closing the connection. This option may be used to
@@ -2109,11 +2115,11 @@
21092115
** The second parameter is a pointer to an integer
21102116
** into which is written 0 or 1 to indicate whether checkpoints-on-close
21112117
** have been disabled - 0 if they are not disabled, 1 if they are.
21122118
** </dd>
21132119
**
2114
-** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
2120
+** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
21152121
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
21162122
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
21172123
** a single SQL query statement will always use the same algorithm regardless
21182124
** of values of [bound parameters].)^ The QPSG disables some query optimizations
21192125
** that look at the values of bound parameters, which can make some queries
@@ -2125,11 +2131,11 @@
21252131
** unchanged. The second parameter is a pointer to an integer into which
21262132
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
21272133
** following this call.
21282134
** </dd>
21292135
**
2130
-** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
2136
+** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
21312137
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
21322138
** include output for any operations performed by trigger programs. This
21332139
** option is used to set or clear (the default) a flag that governs this
21342140
** behavior. The first parameter passed to this operation is an integer -
21352141
** positive to enable output for trigger programs, or zero to disable it,
@@ -2137,11 +2143,11 @@
21372143
** The second parameter is a pointer to an integer into which is written
21382144
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
21392145
** it is not disabled, 1 if it is.
21402146
** </dd>
21412147
**
2142
-** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
2148
+** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
21432149
** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
21442150
** [VACUUM] in order to reset a database back to an empty database
21452151
** with no schema and no content. The following process works even for
21462152
** a badly corrupted database file:
21472153
** <ol>
@@ -2156,10 +2162,22 @@
21562162
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
21572163
** </ol>
21582164
** Because resetting a database is destructive and irreversible, the
21592165
** process requires the use of this obscure API and multiple steps to help
21602166
** ensure that it does not happen by accident.
2167
+**
2168
+** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
2169
+** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
2170
+** "defensive" flag for a database connection. When the defensive
2171
+** flag is enabled, language features that allow ordinary SQL to
2172
+** deliberately corrupt the database file are disabled. The disabled
2173
+** features include but are not limited to the following:
2174
+** <ul>
2175
+** <li> The [PRAGMA writable_schema=ON] statement.
2176
+** <li> Writes to the [sqlite_dbpage] virtual table.
2177
+** <li> Direct writes to [shadow tables].
2178
+** </ul>
21612179
** </dd>
21622180
** </dl>
21632181
*/
21642182
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
21652183
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -2169,11 +2187,12 @@
21692187
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
21702188
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
21712189
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
21722190
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
21732191
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
2174
-#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
2192
+#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
2193
+#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
21752194
21762195
/*
21772196
** CAPI3REF: Enable Or Disable Extended Result Codes
21782197
** METHOD: sqlite3
21792198
**
@@ -3607,13 +3626,23 @@
36073626
** be used just once or at most a few times and then destroyed using
36083627
** [sqlite3_finalize()] relatively soon. The current implementation acts
36093628
** on this hint by avoiding the use of [lookaside memory] so as not to
36103629
** deplete the limited store of lookaside memory. Future versions of
36113630
** SQLite may act on this hint differently.
3631
+**
3632
+** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
3633
+** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
3634
+** representation of the SQL statement should be calculated and then
3635
+** associated with the prepared statement, which can be obtained via
3636
+** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
3637
+** normalize a SQL statement are unspecified and subject to change.
3638
+** At a minimum, literal values will be replaced with suitable
3639
+** placeholders.
36123640
** </dl>
36133641
*/
36143642
#define SQLITE_PREPARE_PERSISTENT 0x01
3643
+#define SQLITE_PREPARE_NORMALIZE 0x02
36153644
36163645
/*
36173646
** CAPI3REF: Compiling An SQL Statement
36183647
** KEYWORDS: {SQL statement compiler}
36193648
** METHOD: sqlite3
@@ -3767,10 +3796,15 @@
37673796
** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
37683797
** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
37693798
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
37703799
** string containing the SQL text of prepared statement P with
37713800
** [bound parameters] expanded.
3801
+** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
3802
+** string containing the normalized SQL text of prepared statement P. The
3803
+** semantics used to normalize a SQL statement are unspecified and subject
3804
+** to change. At a minimum, literal values will be replaced with suitable
3805
+** placeholders.
37723806
**
37733807
** ^(For example, if a prepared statement is created using the SQL
37743808
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
37753809
** and parameter :xyz is unbound, then sqlite3_sql() will return
37763810
** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -3782,18 +3816,20 @@
37823816
**
37833817
** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
37843818
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
37853819
** option causes sqlite3_expanded_sql() to always return NULL.
37863820
**
3787
-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
3788
-** automatically freed when the prepared statement is finalized.
3821
+** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
3822
+** are managed by SQLite and are automatically freed when the prepared
3823
+** statement is finalized.
37893824
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
37903825
** is obtained from [sqlite3_malloc()] and must be free by the application
37913826
** by passing it to [sqlite3_free()].
37923827
*/
37933828
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
37943829
SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
3830
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
37953831
37963832
/*
37973833
** CAPI3REF: Determine If An SQL Statement Writes The Database
37983834
** METHOD: sqlite3_stmt
37993835
**
@@ -6279,10 +6315,13 @@
62796315
/* The methods above are in version 1 of the sqlite_module object. Those
62806316
** below are for version 2 and greater. */
62816317
int (*xSavepoint)(sqlite3_vtab *pVTab, int);
62826318
int (*xRelease)(sqlite3_vtab *pVTab, int);
62836319
int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
6320
+ /* The methods above are in versions 1 and 2 of the sqlite_module object.
6321
+ ** Those below are for version 3 and greater. */
6322
+ int (*xShadowName)(const char*);
62846323
};
62856324
62866325
/*
62876326
** CAPI3REF: Virtual Table Indexing Information
62886327
** KEYWORDS: sqlite3_index_info
@@ -7201,10 +7240,11 @@
72017240
#define SQLITE_TESTCTRL_ALWAYS 13
72027241
#define SQLITE_TESTCTRL_RESERVE 14
72037242
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
72047243
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
72057244
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
7245
+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
72067246
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
72077247
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
72087248
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
72097249
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
72107250
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -8613,10 +8653,11 @@
86138653
** These macros define the various options to the
86148654
** [sqlite3_vtab_config()] interface that [virtual table] implementations
86158655
** can use to customize and optimize their behavior.
86168656
**
86178657
** <dl>
8658
+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
86188659
** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
86198660
** <dd>Calls of the form
86208661
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
86218662
** where X is an integer. If X is zero, then the [virtual table] whose
86228663
** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -9382,11 +9423,11 @@
93829423
int iLevel; /* Level of current node or entry */
93839424
int mxLevel; /* The largest iLevel value in the tree */
93849425
sqlite3_int64 iRowid; /* Rowid for current entry */
93859426
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
93869427
int eParentWithin; /* Visibility of parent node */
9387
- int eWithin; /* OUT: Visiblity */
9428
+ int eWithin; /* OUT: Visibility */
93889429
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
93899430
/* The following fields are only available in 3.8.11 and later */
93909431
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
93919432
};
93929433
@@ -9878,16 +9919,42 @@
98789919
** an application iterates through a changeset using an iterator created by
98799920
** this function, all changes that relate to a single table are visited
98809921
** consecutively. There is no chance that the iterator will visit a change
98819922
** the applies to table X, then one for table Y, and then later on visit
98829923
** another change for table X.
9924
+**
9925
+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
9926
+** may be modified by passing a combination of
9927
+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
9928
+**
9929
+** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
9930
+** and therefore subject to change.
98839931
*/
98849932
SQLITE_API int sqlite3changeset_start(
98859933
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
98869934
int nChangeset, /* Size of changeset blob in bytes */
98879935
void *pChangeset /* Pointer to blob containing changeset */
98889936
);
9937
+SQLITE_API int sqlite3changeset_start_v2(
9938
+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
9939
+ int nChangeset, /* Size of changeset blob in bytes */
9940
+ void *pChangeset, /* Pointer to blob containing changeset */
9941
+ int flags /* SESSION_CHANGESETSTART_* flags */
9942
+);
9943
+
9944
+/*
9945
+** CAPI3REF: Flags for sqlite3changeset_start_v2
9946
+**
9947
+** The following flags may passed via the 4th parameter to
9948
+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
9949
+**
9950
+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
9951
+** Invert the changeset while iterating through it. This is equivalent to
9952
+** inverting a changeset using sqlite3changeset_invert() before applying it.
9953
+** It is an error to specify this flag with a patchset.
9954
+*/
9955
+#define SQLITE_CHANGESETSTART_INVERT 0x0002
98899956
98909957
98919958
/*
98929959
** CAPI3REF: Advance A Changeset Iterator
98939960
** METHOD: sqlite3_changeset_iter
@@ -10538,11 +10605,11 @@
1053810605
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
1053910606
sqlite3_changeset_iter *p /* Handle describing change and conflict */
1054010607
),
1054110608
void *pCtx, /* First argument passed to xConflict */
1054210609
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
10543
- int flags /* Combination of SESSION_APPLY_* flags */
10610
+ int flags /* SESSION_CHANGESETAPPLY_* flags */
1054410611
);
1054510612
1054610613
/*
1054710614
** CAPI3REF: Flags for sqlite3changeset_apply_v2
1054810615
**
@@ -10556,12 +10623,18 @@
1055610623
** SAVEPOINT is committed if the changeset or patchset is successfully
1055710624
** applied, or rolled back if an error occurs. Specifying this flag
1055810625
** causes the sessions module to omit this savepoint. In this case, if the
1055910626
** caller has an open transaction or savepoint when apply_v2() is called,
1056010627
** it may revert the partially applied changeset by rolling it back.
10628
+**
10629
+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
10630
+** Invert the changeset before applying it. This is equivalent to inverting
10631
+** a changeset using sqlite3changeset_invert() before applying it. It is
10632
+** an error to specify this flag with a patchset.
1056110633
*/
1056210634
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
10635
+#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
1056310636
1056410637
/*
1056510638
** CAPI3REF: Constants Passed To The Conflict Handler
1056610639
**
1056710640
** Values that may be passed as the second argument to a conflict-handler.
@@ -10950,10 +11023,16 @@
1095011023
);
1095111024
SQLITE_API int sqlite3changeset_start_strm(
1095211025
sqlite3_changeset_iter **pp,
1095311026
int (*xInput)(void *pIn, void *pData, int *pnData),
1095411027
void *pIn
11028
+);
11029
+SQLITE_API int sqlite3changeset_start_v2_strm(
11030
+ sqlite3_changeset_iter **pp,
11031
+ int (*xInput)(void *pIn, void *pData, int *pnData),
11032
+ void *pIn,
11033
+ int flags
1095511034
);
1095611035
SQLITE_API int sqlite3session_changeset_strm(
1095711036
sqlite3_session *pSession,
1095811037
int (*xOutput)(void *pOut, const void *pData, int nData),
1095911038
void *pOut
@@ -10977,10 +11056,49 @@
1097711056
void *pIn,
1097811057
int (*xOutput)(void *pOut, const void *pData, int nData),
1097911058
void *pOut
1098011059
);
1098111060
11061
+/*
11062
+** CAPI3REF: Configure global parameters
11063
+**
11064
+** The sqlite3session_config() interface is used to make global configuration
11065
+** changes to the sessions module in order to tune it to the specific needs
11066
+** of the application.
11067
+**
11068
+** The sqlite3session_config() interface is not threadsafe. If it is invoked
11069
+** while any other thread is inside any other sessions method then the
11070
+** results are undefined. Furthermore, if it is invoked after any sessions
11071
+** related objects have been created, the results are also undefined.
11072
+**
11073
+** The first argument to the sqlite3session_config() function must be one
11074
+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
11075
+** interpretation of the (void*) value passed as the second parameter and
11076
+** the effect of calling this function depends on the value of the first
11077
+** parameter.
11078
+**
11079
+** <dl>
11080
+** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
11081
+** By default, the sessions module streaming interfaces attempt to input
11082
+** and output data in approximately 1 KiB chunks. This operand may be used
11083
+** to set and query the value of this configuration setting. The pointer
11084
+** passed as the second argument must point to a value of type (int).
11085
+** If this value is greater than 0, it is used as the new streaming data
11086
+** chunk size for both input and output. Before returning, the (int) value
11087
+** pointed to by pArg is set to the final value of the streaming interface
11088
+** chunk size.
11089
+** </dl>
11090
+**
11091
+** This function returns SQLITE_OK if successful, or an SQLite error code
11092
+** otherwise.
11093
+*/
11094
+SQLITE_API int sqlite3session_config(int op, void *pArg);
11095
+
11096
+/*
11097
+** CAPI3REF: Values for sqlite3session_config().
11098
+*/
11099
+#define SQLITE_SESSION_CONFIG_STRMSIZE 1
1098211100
1098311101
/*
1098411102
** Make sure we can call this stuff from C++.
1098511103
*/
1098611104
#ifdef __cplusplus
1098711105
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -121,13 +121,13 @@
121 **
122 ** See also: [sqlite3_libversion()],
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.25.2"
127 #define SQLITE_VERSION_NUMBER 3025002
128 #define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
@@ -2015,10 +2015,11 @@
2015 ** the call worked. ^The [sqlite3_db_config()] interface will return a
2016 ** non-zero [error code] if a discontinued or unsupported configuration option
2017 ** is invoked.
2018 **
2019 ** <dl>
 
2020 ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
2021 ** <dd> ^This option takes three additional arguments that determine the
2022 ** [lookaside memory allocator] configuration for the [database connection].
2023 ** ^The first argument (the third parameter to [sqlite3_db_config()] is a
2024 ** pointer to a memory buffer to use for lookaside memory.
@@ -2037,10 +2038,11 @@
2037 ** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
2038 ** Any attempt to change the lookaside memory configuration when lookaside
2039 ** memory is in use leaves the configuration unchanged and returns
2040 ** [SQLITE_BUSY].)^</dd>
2041 **
 
2042 ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
2043 ** <dd> ^This option is used to enable or disable the enforcement of
2044 ** [foreign key constraints]. There should be two additional arguments.
2045 ** The first argument is an integer which is 0 to disable FK enforcement,
2046 ** positive to enable FK enforcement or negative to leave FK enforcement
@@ -2047,10 +2049,11 @@
2047 ** unchanged. The second parameter is a pointer to an integer into which
2048 ** is written 0 or 1 to indicate whether FK enforcement is off or on
2049 ** following this call. The second parameter may be a NULL pointer, in
2050 ** which case the FK enforcement setting is not reported back. </dd>
2051 **
 
2052 ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
2053 ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
2054 ** There should be two additional arguments.
2055 ** The first argument is an integer which is 0 to disable triggers,
2056 ** positive to enable triggers or negative to leave the setting unchanged.
@@ -2057,10 +2060,11 @@
2057 ** The second parameter is a pointer to an integer into which
2058 ** is written 0 or 1 to indicate whether triggers are disabled or enabled
2059 ** following this call. The second parameter may be a NULL pointer, in
2060 ** which case the trigger setting is not reported back. </dd>
2061 **
 
2062 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2063 ** <dd> ^This option is used to enable or disable the two-argument
2064 ** version of the [fts3_tokenizer()] function which is part of the
2065 ** [FTS3] full-text search engine extension.
2066 ** There should be two additional arguments.
@@ -2070,10 +2074,11 @@
2070 ** The second parameter is a pointer to an integer into which
2071 ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
2072 ** following this call. The second parameter may be a NULL pointer, in
2073 ** which case the new setting is not reported back. </dd>
2074 **
 
2075 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
2076 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
2077 ** interface independently of the [load_extension()] SQL function.
2078 ** The [sqlite3_enable_load_extension()] API enables or disables both the
2079 ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -2087,19 +2092,20 @@
2087 ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
2088 ** is disabled or enabled following this call. The second parameter may
2089 ** be a NULL pointer, in which case the new setting is not reported back.
2090 ** </dd>
2091 **
2092 ** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
2093 ** <dd> ^This option is used to change the name of the "main" database
2094 ** schema. ^The sole argument is a pointer to a constant UTF8 string
2095 ** which will become the new schema name in place of "main". ^SQLite
2096 ** does not make a copy of the new main schema name string, so the application
2097 ** must ensure that the argument passed into this DBCONFIG option is unchanged
2098 ** until after the database connection closes.
2099 ** </dd>
2100 **
 
2101 ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
2102 ** <dd> Usually, when a database in wal mode is closed or detached from a
2103 ** database handle, SQLite checks if this will mean that there are now no
2104 ** connections at all to the database. If so, it performs a checkpoint
2105 ** operation before closing the connection. This option may be used to
@@ -2109,11 +2115,11 @@
2109 ** The second parameter is a pointer to an integer
2110 ** into which is written 0 or 1 to indicate whether checkpoints-on-close
2111 ** have been disabled - 0 if they are not disabled, 1 if they are.
2112 ** </dd>
2113 **
2114 ** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
2115 ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
2116 ** the [query planner stability guarantee] (QPSG). When the QPSG is active,
2117 ** a single SQL query statement will always use the same algorithm regardless
2118 ** of values of [bound parameters].)^ The QPSG disables some query optimizations
2119 ** that look at the values of bound parameters, which can make some queries
@@ -2125,11 +2131,11 @@
2125 ** unchanged. The second parameter is a pointer to an integer into which
2126 ** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
2127 ** following this call.
2128 ** </dd>
2129 **
2130 ** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
2131 ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
2132 ** include output for any operations performed by trigger programs. This
2133 ** option is used to set or clear (the default) a flag that governs this
2134 ** behavior. The first parameter passed to this operation is an integer -
2135 ** positive to enable output for trigger programs, or zero to disable it,
@@ -2137,11 +2143,11 @@
2137 ** The second parameter is a pointer to an integer into which is written
2138 ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
2139 ** it is not disabled, 1 if it is.
2140 ** </dd>
2141 **
2142 ** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
2143 ** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
2144 ** [VACUUM] in order to reset a database back to an empty database
2145 ** with no schema and no content. The following process works even for
2146 ** a badly corrupted database file:
2147 ** <ol>
@@ -2156,10 +2162,22 @@
2156 ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
2157 ** </ol>
2158 ** Because resetting a database is destructive and irreversible, the
2159 ** process requires the use of this obscure API and multiple steps to help
2160 ** ensure that it does not happen by accident.
 
 
 
 
 
 
 
 
 
 
 
 
2161 ** </dd>
2162 ** </dl>
2163 */
2164 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
2165 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -2169,11 +2187,12 @@
2169 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
2170 #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
2171 #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
2172 #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
2173 #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
2174 #define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
 
2175
2176 /*
2177 ** CAPI3REF: Enable Or Disable Extended Result Codes
2178 ** METHOD: sqlite3
2179 **
@@ -3607,13 +3626,23 @@
3607 ** be used just once or at most a few times and then destroyed using
3608 ** [sqlite3_finalize()] relatively soon. The current implementation acts
3609 ** on this hint by avoiding the use of [lookaside memory] so as not to
3610 ** deplete the limited store of lookaside memory. Future versions of
3611 ** SQLite may act on this hint differently.
 
 
 
 
 
 
 
 
 
3612 ** </dl>
3613 */
3614 #define SQLITE_PREPARE_PERSISTENT 0x01
 
3615
3616 /*
3617 ** CAPI3REF: Compiling An SQL Statement
3618 ** KEYWORDS: {SQL statement compiler}
3619 ** METHOD: sqlite3
@@ -3767,10 +3796,15 @@
3767 ** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
3768 ** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
3769 ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
3770 ** string containing the SQL text of prepared statement P with
3771 ** [bound parameters] expanded.
 
 
 
 
 
3772 **
3773 ** ^(For example, if a prepared statement is created using the SQL
3774 ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
3775 ** and parameter :xyz is unbound, then sqlite3_sql() will return
3776 ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -3782,18 +3816,20 @@
3782 **
3783 ** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
3784 ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
3785 ** option causes sqlite3_expanded_sql() to always return NULL.
3786 **
3787 ** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
3788 ** automatically freed when the prepared statement is finalized.
 
3789 ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
3790 ** is obtained from [sqlite3_malloc()] and must be free by the application
3791 ** by passing it to [sqlite3_free()].
3792 */
3793 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
3794 SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
 
3795
3796 /*
3797 ** CAPI3REF: Determine If An SQL Statement Writes The Database
3798 ** METHOD: sqlite3_stmt
3799 **
@@ -6279,10 +6315,13 @@
6279 /* The methods above are in version 1 of the sqlite_module object. Those
6280 ** below are for version 2 and greater. */
6281 int (*xSavepoint)(sqlite3_vtab *pVTab, int);
6282 int (*xRelease)(sqlite3_vtab *pVTab, int);
6283 int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
 
 
 
6284 };
6285
6286 /*
6287 ** CAPI3REF: Virtual Table Indexing Information
6288 ** KEYWORDS: sqlite3_index_info
@@ -7201,10 +7240,11 @@
7201 #define SQLITE_TESTCTRL_ALWAYS 13
7202 #define SQLITE_TESTCTRL_RESERVE 14
7203 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
7204 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
7205 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
 
7206 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
7207 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
7208 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
7209 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
7210 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -8613,10 +8653,11 @@
8613 ** These macros define the various options to the
8614 ** [sqlite3_vtab_config()] interface that [virtual table] implementations
8615 ** can use to customize and optimize their behavior.
8616 **
8617 ** <dl>
 
8618 ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
8619 ** <dd>Calls of the form
8620 ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
8621 ** where X is an integer. If X is zero, then the [virtual table] whose
8622 ** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -9382,11 +9423,11 @@
9382 int iLevel; /* Level of current node or entry */
9383 int mxLevel; /* The largest iLevel value in the tree */
9384 sqlite3_int64 iRowid; /* Rowid for current entry */
9385 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
9386 int eParentWithin; /* Visibility of parent node */
9387 int eWithin; /* OUT: Visiblity */
9388 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
9389 /* The following fields are only available in 3.8.11 and later */
9390 sqlite3_value **apSqlParam; /* Original SQL values of parameters */
9391 };
9392
@@ -9878,16 +9919,42 @@
9878 ** an application iterates through a changeset using an iterator created by
9879 ** this function, all changes that relate to a single table are visited
9880 ** consecutively. There is no chance that the iterator will visit a change
9881 ** the applies to table X, then one for table Y, and then later on visit
9882 ** another change for table X.
 
 
 
 
 
 
 
9883 */
9884 SQLITE_API int sqlite3changeset_start(
9885 sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
9886 int nChangeset, /* Size of changeset blob in bytes */
9887 void *pChangeset /* Pointer to blob containing changeset */
9888 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9889
9890
9891 /*
9892 ** CAPI3REF: Advance A Changeset Iterator
9893 ** METHOD: sqlite3_changeset_iter
@@ -10538,11 +10605,11 @@
10538 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
10539 sqlite3_changeset_iter *p /* Handle describing change and conflict */
10540 ),
10541 void *pCtx, /* First argument passed to xConflict */
10542 void **ppRebase, int *pnRebase, /* OUT: Rebase data */
10543 int flags /* Combination of SESSION_APPLY_* flags */
10544 );
10545
10546 /*
10547 ** CAPI3REF: Flags for sqlite3changeset_apply_v2
10548 **
@@ -10556,12 +10623,18 @@
10556 ** SAVEPOINT is committed if the changeset or patchset is successfully
10557 ** applied, or rolled back if an error occurs. Specifying this flag
10558 ** causes the sessions module to omit this savepoint. In this case, if the
10559 ** caller has an open transaction or savepoint when apply_v2() is called,
10560 ** it may revert the partially applied changeset by rolling it back.
 
 
 
 
 
10561 */
10562 #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
 
10563
10564 /*
10565 ** CAPI3REF: Constants Passed To The Conflict Handler
10566 **
10567 ** Values that may be passed as the second argument to a conflict-handler.
@@ -10950,10 +11023,16 @@
10950 );
10951 SQLITE_API int sqlite3changeset_start_strm(
10952 sqlite3_changeset_iter **pp,
10953 int (*xInput)(void *pIn, void *pData, int *pnData),
10954 void *pIn
 
 
 
 
 
 
10955 );
10956 SQLITE_API int sqlite3session_changeset_strm(
10957 sqlite3_session *pSession,
10958 int (*xOutput)(void *pOut, const void *pData, int nData),
10959 void *pOut
@@ -10977,10 +11056,49 @@
10977 void *pIn,
10978 int (*xOutput)(void *pOut, const void *pData, int nData),
10979 void *pOut
10980 );
10981
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10982
10983 /*
10984 ** Make sure we can call this stuff from C++.
10985 */
10986 #ifdef __cplusplus
10987
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -121,13 +121,13 @@
121 **
122 ** See also: [sqlite3_libversion()],
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.26.0"
127 #define SQLITE_VERSION_NUMBER 3026000
128 #define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
@@ -2015,10 +2015,11 @@
2015 ** the call worked. ^The [sqlite3_db_config()] interface will return a
2016 ** non-zero [error code] if a discontinued or unsupported configuration option
2017 ** is invoked.
2018 **
2019 ** <dl>
2020 ** [[SQLITE_DBCONFIG_LOOKASIDE]]
2021 ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
2022 ** <dd> ^This option takes three additional arguments that determine the
2023 ** [lookaside memory allocator] configuration for the [database connection].
2024 ** ^The first argument (the third parameter to [sqlite3_db_config()] is a
2025 ** pointer to a memory buffer to use for lookaside memory.
@@ -2037,10 +2038,11 @@
2038 ** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
2039 ** Any attempt to change the lookaside memory configuration when lookaside
2040 ** memory is in use leaves the configuration unchanged and returns
2041 ** [SQLITE_BUSY].)^</dd>
2042 **
2043 ** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
2044 ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
2045 ** <dd> ^This option is used to enable or disable the enforcement of
2046 ** [foreign key constraints]. There should be two additional arguments.
2047 ** The first argument is an integer which is 0 to disable FK enforcement,
2048 ** positive to enable FK enforcement or negative to leave FK enforcement
@@ -2047,10 +2049,11 @@
2049 ** unchanged. The second parameter is a pointer to an integer into which
2050 ** is written 0 or 1 to indicate whether FK enforcement is off or on
2051 ** following this call. The second parameter may be a NULL pointer, in
2052 ** which case the FK enforcement setting is not reported back. </dd>
2053 **
2054 ** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
2055 ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
2056 ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
2057 ** There should be two additional arguments.
2058 ** The first argument is an integer which is 0 to disable triggers,
2059 ** positive to enable triggers or negative to leave the setting unchanged.
@@ -2057,10 +2060,11 @@
2060 ** The second parameter is a pointer to an integer into which
2061 ** is written 0 or 1 to indicate whether triggers are disabled or enabled
2062 ** following this call. The second parameter may be a NULL pointer, in
2063 ** which case the trigger setting is not reported back. </dd>
2064 **
2065 ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
2066 ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
2067 ** <dd> ^This option is used to enable or disable the two-argument
2068 ** version of the [fts3_tokenizer()] function which is part of the
2069 ** [FTS3] full-text search engine extension.
2070 ** There should be two additional arguments.
@@ -2070,10 +2074,11 @@
2074 ** The second parameter is a pointer to an integer into which
2075 ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
2076 ** following this call. The second parameter may be a NULL pointer, in
2077 ** which case the new setting is not reported back. </dd>
2078 **
2079 ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
2080 ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
2081 ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
2082 ** interface independently of the [load_extension()] SQL function.
2083 ** The [sqlite3_enable_load_extension()] API enables or disables both the
2084 ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -2087,19 +2092,20 @@
2092 ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
2093 ** is disabled or enabled following this call. The second parameter may
2094 ** be a NULL pointer, in which case the new setting is not reported back.
2095 ** </dd>
2096 **
2097 ** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
2098 ** <dd> ^This option is used to change the name of the "main" database
2099 ** schema. ^The sole argument is a pointer to a constant UTF8 string
2100 ** which will become the new schema name in place of "main". ^SQLite
2101 ** does not make a copy of the new main schema name string, so the application
2102 ** must ensure that the argument passed into this DBCONFIG option is unchanged
2103 ** until after the database connection closes.
2104 ** </dd>
2105 **
2106 ** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
2107 ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
2108 ** <dd> Usually, when a database in wal mode is closed or detached from a
2109 ** database handle, SQLite checks if this will mean that there are now no
2110 ** connections at all to the database. If so, it performs a checkpoint
2111 ** operation before closing the connection. This option may be used to
@@ -2109,11 +2115,11 @@
2115 ** The second parameter is a pointer to an integer
2116 ** into which is written 0 or 1 to indicate whether checkpoints-on-close
2117 ** have been disabled - 0 if they are not disabled, 1 if they are.
2118 ** </dd>
2119 **
2120 ** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
2121 ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
2122 ** the [query planner stability guarantee] (QPSG). When the QPSG is active,
2123 ** a single SQL query statement will always use the same algorithm regardless
2124 ** of values of [bound parameters].)^ The QPSG disables some query optimizations
2125 ** that look at the values of bound parameters, which can make some queries
@@ -2125,11 +2131,11 @@
2131 ** unchanged. The second parameter is a pointer to an integer into which
2132 ** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
2133 ** following this call.
2134 ** </dd>
2135 **
2136 ** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
2137 ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
2138 ** include output for any operations performed by trigger programs. This
2139 ** option is used to set or clear (the default) a flag that governs this
2140 ** behavior. The first parameter passed to this operation is an integer -
2141 ** positive to enable output for trigger programs, or zero to disable it,
@@ -2137,11 +2143,11 @@
2143 ** The second parameter is a pointer to an integer into which is written
2144 ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
2145 ** it is not disabled, 1 if it is.
2146 ** </dd>
2147 **
2148 ** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
2149 ** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
2150 ** [VACUUM] in order to reset a database back to an empty database
2151 ** with no schema and no content. The following process works even for
2152 ** a badly corrupted database file:
2153 ** <ol>
@@ -2156,10 +2162,22 @@
2162 ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
2163 ** </ol>
2164 ** Because resetting a database is destructive and irreversible, the
2165 ** process requires the use of this obscure API and multiple steps to help
2166 ** ensure that it does not happen by accident.
2167 **
2168 ** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
2169 ** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
2170 ** "defensive" flag for a database connection. When the defensive
2171 ** flag is enabled, language features that allow ordinary SQL to
2172 ** deliberately corrupt the database file are disabled. The disabled
2173 ** features include but are not limited to the following:
2174 ** <ul>
2175 ** <li> The [PRAGMA writable_schema=ON] statement.
2176 ** <li> Writes to the [sqlite_dbpage] virtual table.
2177 ** <li> Direct writes to [shadow tables].
2178 ** </ul>
2179 ** </dd>
2180 ** </dl>
2181 */
2182 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
2183 #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -2169,11 +2187,12 @@
2187 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
2188 #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
2189 #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
2190 #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
2191 #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
2192 #define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
2193 #define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
2194
2195 /*
2196 ** CAPI3REF: Enable Or Disable Extended Result Codes
2197 ** METHOD: sqlite3
2198 **
@@ -3607,13 +3626,23 @@
3626 ** be used just once or at most a few times and then destroyed using
3627 ** [sqlite3_finalize()] relatively soon. The current implementation acts
3628 ** on this hint by avoiding the use of [lookaside memory] so as not to
3629 ** deplete the limited store of lookaside memory. Future versions of
3630 ** SQLite may act on this hint differently.
3631 **
3632 ** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
3633 ** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
3634 ** representation of the SQL statement should be calculated and then
3635 ** associated with the prepared statement, which can be obtained via
3636 ** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
3637 ** normalize a SQL statement are unspecified and subject to change.
3638 ** At a minimum, literal values will be replaced with suitable
3639 ** placeholders.
3640 ** </dl>
3641 */
3642 #define SQLITE_PREPARE_PERSISTENT 0x01
3643 #define SQLITE_PREPARE_NORMALIZE 0x02
3644
3645 /*
3646 ** CAPI3REF: Compiling An SQL Statement
3647 ** KEYWORDS: {SQL statement compiler}
3648 ** METHOD: sqlite3
@@ -3767,10 +3796,15 @@
3796 ** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
3797 ** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
3798 ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
3799 ** string containing the SQL text of prepared statement P with
3800 ** [bound parameters] expanded.
3801 ** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
3802 ** string containing the normalized SQL text of prepared statement P. The
3803 ** semantics used to normalize a SQL statement are unspecified and subject
3804 ** to change. At a minimum, literal values will be replaced with suitable
3805 ** placeholders.
3806 **
3807 ** ^(For example, if a prepared statement is created using the SQL
3808 ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
3809 ** and parameter :xyz is unbound, then sqlite3_sql() will return
3810 ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -3782,18 +3816,20 @@
3816 **
3817 ** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
3818 ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
3819 ** option causes sqlite3_expanded_sql() to always return NULL.
3820 **
3821 ** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
3822 ** are managed by SQLite and are automatically freed when the prepared
3823 ** statement is finalized.
3824 ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
3825 ** is obtained from [sqlite3_malloc()] and must be free by the application
3826 ** by passing it to [sqlite3_free()].
3827 */
3828 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
3829 SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
3830 SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
3831
3832 /*
3833 ** CAPI3REF: Determine If An SQL Statement Writes The Database
3834 ** METHOD: sqlite3_stmt
3835 **
@@ -6279,10 +6315,13 @@
6315 /* The methods above are in version 1 of the sqlite_module object. Those
6316 ** below are for version 2 and greater. */
6317 int (*xSavepoint)(sqlite3_vtab *pVTab, int);
6318 int (*xRelease)(sqlite3_vtab *pVTab, int);
6319 int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
6320 /* The methods above are in versions 1 and 2 of the sqlite_module object.
6321 ** Those below are for version 3 and greater. */
6322 int (*xShadowName)(const char*);
6323 };
6324
6325 /*
6326 ** CAPI3REF: Virtual Table Indexing Information
6327 ** KEYWORDS: sqlite3_index_info
@@ -7201,10 +7240,11 @@
7240 #define SQLITE_TESTCTRL_ALWAYS 13
7241 #define SQLITE_TESTCTRL_RESERVE 14
7242 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
7243 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
7244 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
7245 #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
7246 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
7247 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
7248 #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
7249 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
7250 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -8613,10 +8653,11 @@
8653 ** These macros define the various options to the
8654 ** [sqlite3_vtab_config()] interface that [virtual table] implementations
8655 ** can use to customize and optimize their behavior.
8656 **
8657 ** <dl>
8658 ** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
8659 ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
8660 ** <dd>Calls of the form
8661 ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
8662 ** where X is an integer. If X is zero, then the [virtual table] whose
8663 ** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -9382,11 +9423,11 @@
9423 int iLevel; /* Level of current node or entry */
9424 int mxLevel; /* The largest iLevel value in the tree */
9425 sqlite3_int64 iRowid; /* Rowid for current entry */
9426 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
9427 int eParentWithin; /* Visibility of parent node */
9428 int eWithin; /* OUT: Visibility */
9429 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
9430 /* The following fields are only available in 3.8.11 and later */
9431 sqlite3_value **apSqlParam; /* Original SQL values of parameters */
9432 };
9433
@@ -9878,16 +9919,42 @@
9919 ** an application iterates through a changeset using an iterator created by
9920 ** this function, all changes that relate to a single table are visited
9921 ** consecutively. There is no chance that the iterator will visit a change
9922 ** the applies to table X, then one for table Y, and then later on visit
9923 ** another change for table X.
9924 **
9925 ** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
9926 ** may be modified by passing a combination of
9927 ** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
9928 **
9929 ** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
9930 ** and therefore subject to change.
9931 */
9932 SQLITE_API int sqlite3changeset_start(
9933 sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
9934 int nChangeset, /* Size of changeset blob in bytes */
9935 void *pChangeset /* Pointer to blob containing changeset */
9936 );
9937 SQLITE_API int sqlite3changeset_start_v2(
9938 sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
9939 int nChangeset, /* Size of changeset blob in bytes */
9940 void *pChangeset, /* Pointer to blob containing changeset */
9941 int flags /* SESSION_CHANGESETSTART_* flags */
9942 );
9943
9944 /*
9945 ** CAPI3REF: Flags for sqlite3changeset_start_v2
9946 **
9947 ** The following flags may passed via the 4th parameter to
9948 ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
9949 **
9950 ** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
9951 ** Invert the changeset while iterating through it. This is equivalent to
9952 ** inverting a changeset using sqlite3changeset_invert() before applying it.
9953 ** It is an error to specify this flag with a patchset.
9954 */
9955 #define SQLITE_CHANGESETSTART_INVERT 0x0002
9956
9957
9958 /*
9959 ** CAPI3REF: Advance A Changeset Iterator
9960 ** METHOD: sqlite3_changeset_iter
@@ -10538,11 +10605,11 @@
10605 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
10606 sqlite3_changeset_iter *p /* Handle describing change and conflict */
10607 ),
10608 void *pCtx, /* First argument passed to xConflict */
10609 void **ppRebase, int *pnRebase, /* OUT: Rebase data */
10610 int flags /* SESSION_CHANGESETAPPLY_* flags */
10611 );
10612
10613 /*
10614 ** CAPI3REF: Flags for sqlite3changeset_apply_v2
10615 **
@@ -10556,12 +10623,18 @@
10623 ** SAVEPOINT is committed if the changeset or patchset is successfully
10624 ** applied, or rolled back if an error occurs. Specifying this flag
10625 ** causes the sessions module to omit this savepoint. In this case, if the
10626 ** caller has an open transaction or savepoint when apply_v2() is called,
10627 ** it may revert the partially applied changeset by rolling it back.
10628 **
10629 ** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
10630 ** Invert the changeset before applying it. This is equivalent to inverting
10631 ** a changeset using sqlite3changeset_invert() before applying it. It is
10632 ** an error to specify this flag with a patchset.
10633 */
10634 #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
10635 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002
10636
10637 /*
10638 ** CAPI3REF: Constants Passed To The Conflict Handler
10639 **
10640 ** Values that may be passed as the second argument to a conflict-handler.
@@ -10950,10 +11023,16 @@
11023 );
11024 SQLITE_API int sqlite3changeset_start_strm(
11025 sqlite3_changeset_iter **pp,
11026 int (*xInput)(void *pIn, void *pData, int *pnData),
11027 void *pIn
11028 );
11029 SQLITE_API int sqlite3changeset_start_v2_strm(
11030 sqlite3_changeset_iter **pp,
11031 int (*xInput)(void *pIn, void *pData, int *pnData),
11032 void *pIn,
11033 int flags
11034 );
11035 SQLITE_API int sqlite3session_changeset_strm(
11036 sqlite3_session *pSession,
11037 int (*xOutput)(void *pOut, const void *pData, int nData),
11038 void *pOut
@@ -10977,10 +11056,49 @@
11056 void *pIn,
11057 int (*xOutput)(void *pOut, const void *pData, int nData),
11058 void *pOut
11059 );
11060
11061 /*
11062 ** CAPI3REF: Configure global parameters
11063 **
11064 ** The sqlite3session_config() interface is used to make global configuration
11065 ** changes to the sessions module in order to tune it to the specific needs
11066 ** of the application.
11067 **
11068 ** The sqlite3session_config() interface is not threadsafe. If it is invoked
11069 ** while any other thread is inside any other sessions method then the
11070 ** results are undefined. Furthermore, if it is invoked after any sessions
11071 ** related objects have been created, the results are also undefined.
11072 **
11073 ** The first argument to the sqlite3session_config() function must be one
11074 ** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
11075 ** interpretation of the (void*) value passed as the second parameter and
11076 ** the effect of calling this function depends on the value of the first
11077 ** parameter.
11078 **
11079 ** <dl>
11080 ** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
11081 ** By default, the sessions module streaming interfaces attempt to input
11082 ** and output data in approximately 1 KiB chunks. This operand may be used
11083 ** to set and query the value of this configuration setting. The pointer
11084 ** passed as the second argument must point to a value of type (int).
11085 ** If this value is greater than 0, it is used as the new streaming data
11086 ** chunk size for both input and output. Before returning, the (int) value
11087 ** pointed to by pArg is set to the final value of the streaming interface
11088 ** chunk size.
11089 ** </dl>
11090 **
11091 ** This function returns SQLITE_OK if successful, or an SQLite error code
11092 ** otherwise.
11093 */
11094 SQLITE_API int sqlite3session_config(int op, void *pArg);
11095
11096 /*
11097 ** CAPI3REF: Values for sqlite3session_config().
11098 */
11099 #define SQLITE_SESSION_CONFIG_STRMSIZE 1
11100
11101 /*
11102 ** Make sure we can call this stuff from C++.
11103 */
11104 #ifdef __cplusplus
11105
+1 -1
--- src/th_main.c
+++ src/th_main.c
@@ -416,11 +416,11 @@
416416
417417
/*
418418
** TH1 command: puts STRING
419419
** TH1 command: html STRING
420420
**
421
-** Output STRING escaped for HTML (html) or unchanged (puts).
421
+** Output STRING escaped for HTML (puts) or unchanged (html).
422422
*/
423423
static int putsCmd(
424424
Th_Interp *interp,
425425
void *pConvert,
426426
int argc,
427427
--- src/th_main.c
+++ src/th_main.c
@@ -416,11 +416,11 @@
416
417 /*
418 ** TH1 command: puts STRING
419 ** TH1 command: html STRING
420 **
421 ** Output STRING escaped for HTML (html) or unchanged (puts).
422 */
423 static int putsCmd(
424 Th_Interp *interp,
425 void *pConvert,
426 int argc,
427
--- src/th_main.c
+++ src/th_main.c
@@ -416,11 +416,11 @@
416
417 /*
418 ** TH1 command: puts STRING
419 ** TH1 command: html STRING
420 **
421 ** Output STRING escaped for HTML (puts) or unchanged (html).
422 */
423 static int putsCmd(
424 Th_Interp *interp,
425 void *pConvert,
426 int argc,
427
+4 -4
--- src/timeline.c
+++ src/timeline.c
@@ -78,13 +78,13 @@
7878
void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
7979
if( zU==0 || zU[0]==0 ) zU = "anonymous";
8080
if( zSuf==0 ) zSuf = "";
8181
if( g.perm.Hyperlink ){
8282
if( zD && zD[0] ){
83
- @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf)
83
+ @ %z(href("%R/timeline?c=%T&u=%T&y=a",zD,zU))%h(zU)</a>%s(zSuf)
8484
}else{
85
- @ %z(href("%R/timeline?u=%T",zU))%h(zU)</a>%s(zSuf)
85
+ @ %z(href("%R/timeline?u=%T&y=a",zU))%h(zU)</a>%s(zSuf)
8686
}
8787
}else{
8888
@ %s(zU)
8989
}
9090
}
@@ -580,11 +580,11 @@
580580
}else if( zType[0]=='g' || zType[0]=='w' || zType[0]=='t' || zType[0]=='f'){
581581
cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
582582
}
583583
584584
if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
585
- char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate);
585
+ char *zLink = mprintf("%R/timeline?u=%h&c=%t&y=a", zDispUser, zDate);
586586
cgi_printf("user:&nbsp;%z%h</a>", href("%z",zLink), zDispUser);
587587
}else{
588588
cgi_printf("user:&nbsp;%h", zDispUser);
589589
}
590590
@@ -601,11 +601,11 @@
601601
while( z && z[0] ){
602602
for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
603603
if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
604604
blob_appendf(&links,
605605
"%z%#h</a>%.2s",
606
- href("%R/timeline?r=%#t&nd&c=%t&n=200",i,z,zDate), i,z, &z[i]
606
+ href("%R/timeline?r=%#t&c=%t",i,z,zDate), i,z, &z[i]
607607
);
608608
}else{
609609
blob_appendf(&links, "%#h", i+2, z);
610610
}
611611
if( z[i]==0 ) break;
612612
--- src/timeline.c
+++ src/timeline.c
@@ -78,13 +78,13 @@
78 void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
79 if( zU==0 || zU[0]==0 ) zU = "anonymous";
80 if( zSuf==0 ) zSuf = "";
81 if( g.perm.Hyperlink ){
82 if( zD && zD[0] ){
83 @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf)
84 }else{
85 @ %z(href("%R/timeline?u=%T",zU))%h(zU)</a>%s(zSuf)
86 }
87 }else{
88 @ %s(zU)
89 }
90 }
@@ -580,11 +580,11 @@
580 }else if( zType[0]=='g' || zType[0]=='w' || zType[0]=='t' || zType[0]=='f'){
581 cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
582 }
583
584 if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
585 char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate);
586 cgi_printf("user:&nbsp;%z%h</a>", href("%z",zLink), zDispUser);
587 }else{
588 cgi_printf("user:&nbsp;%h", zDispUser);
589 }
590
@@ -601,11 +601,11 @@
601 while( z && z[0] ){
602 for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
603 if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
604 blob_appendf(&links,
605 "%z%#h</a>%.2s",
606 href("%R/timeline?r=%#t&nd&c=%t&n=200",i,z,zDate), i,z, &z[i]
607 );
608 }else{
609 blob_appendf(&links, "%#h", i+2, z);
610 }
611 if( z[i]==0 ) break;
612
--- src/timeline.c
+++ src/timeline.c
@@ -78,13 +78,13 @@
78 void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
79 if( zU==0 || zU[0]==0 ) zU = "anonymous";
80 if( zSuf==0 ) zSuf = "";
81 if( g.perm.Hyperlink ){
82 if( zD && zD[0] ){
83 @ %z(href("%R/timeline?c=%T&u=%T&y=a",zD,zU))%h(zU)</a>%s(zSuf)
84 }else{
85 @ %z(href("%R/timeline?u=%T&y=a",zU))%h(zU)</a>%s(zSuf)
86 }
87 }else{
88 @ %s(zU)
89 }
90 }
@@ -580,11 +580,11 @@
580 }else if( zType[0]=='g' || zType[0]=='w' || zType[0]=='t' || zType[0]=='f'){
581 cgi_printf("artifact:&nbsp;%z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
582 }
583
584 if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
585 char *zLink = mprintf("%R/timeline?u=%h&c=%t&y=a", zDispUser, zDate);
586 cgi_printf("user:&nbsp;%z%h</a>", href("%z",zLink), zDispUser);
587 }else{
588 cgi_printf("user:&nbsp;%h", zDispUser);
589 }
590
@@ -601,11 +601,11 @@
601 while( z && z[0] ){
602 for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
603 if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
604 blob_appendf(&links,
605 "%z%#h</a>%.2s",
606 href("%R/timeline?r=%#t&c=%t",i,z,zDate), i,z, &z[i]
607 );
608 }else{
609 blob_appendf(&links, "%#h", i+2, z);
610 }
611 if( z[i]==0 ) break;
612
+1 -1
--- src/wiki.c
+++ src/wiki.c
@@ -611,11 +611,11 @@
611611
}
612612
@ <input type="submit" name="preview" value="Preview Your Changes" />
613613
}else{
614614
/* Wysiwyg editing */
615615
Blob html, temp;
616
- form_begin("onsubmit='wysiwygSubmit()'", "%R/wikiedit");
616
+ form_begin("", "%R/wikiedit");
617617
@ <div>
618618
@ <input type="hidden" name="wysiwyg" value="1" />
619619
blob_zero(&temp);
620620
wiki_convert(&wiki, &temp, 0);
621621
blob_zero(&html);
622622
--- src/wiki.c
+++ src/wiki.c
@@ -611,11 +611,11 @@
611 }
612 @ <input type="submit" name="preview" value="Preview Your Changes" />
613 }else{
614 /* Wysiwyg editing */
615 Blob html, temp;
616 form_begin("onsubmit='wysiwygSubmit()'", "%R/wikiedit");
617 @ <div>
618 @ <input type="hidden" name="wysiwyg" value="1" />
619 blob_zero(&temp);
620 wiki_convert(&wiki, &temp, 0);
621 blob_zero(&html);
622
--- src/wiki.c
+++ src/wiki.c
@@ -611,11 +611,11 @@
611 }
612 @ <input type="submit" name="preview" value="Preview Your Changes" />
613 }else{
614 /* Wysiwyg editing */
615 Blob html, temp;
616 form_begin("", "%R/wikiedit");
617 @ <div>
618 @ <input type="hidden" name="wysiwyg" value="1" />
619 blob_zero(&temp);
620 wiki_convert(&wiki, &temp, 0);
621 blob_zero(&html);
622
+64 -42
--- src/wysiwyg.c
+++ src/wysiwyg.c
@@ -49,17 +49,16 @@
4949
@ #editMode label { cursor: pointer; }
5050
@ </style>
5151
5252
@ <input id="wysiwygValue" type="hidden" name="%s(zId)">
5353
@ <div id="editModeDiv">Edit mode:
54
- @ <select id="editMode" size=1 onchange="setDocMode(this.selectedIndex)">
54
+ @ <select id="editMode" size=1>
5555
@ <option value="0">WYSIWYG</option>
5656
@ <option value="1">Raw HTML</option>
5757
@ </select></div>
5858
@ <div id="toolBar1">
59
- @ <select onchange="formatDoc('formatblock',this[this.selectedIndex].value);
60
- @ this.selectedIndex=0;">
59
+ @ <select class="format" data-format="formatblock">
6160
@ <option selected>- formatting -</option>
6261
@ <option value="h1">Title 1 &lt;h1&gt;</option>
6362
@ <option value="h2">Title 2 &lt;h2&gt;</option>
6463
@ <option value="h3">Title 3 &lt;h3&gt;</option>
6564
@ <option value="h4">Title 4 &lt;h4&gt;</option>
@@ -66,52 +65,48 @@
6665
@ <option value="h5">Title 5 &lt;h5&gt;</option>
6766
@ <option value="h6">Subtitle &lt;h6&gt;</option>
6867
@ <option value="p">Paragraph &lt;p&gt;</option>
6968
@ <option value="pre">Preformatted &lt;pre&gt;</option>
7069
@ </select>
71
- @ <select onchange="formatDoc('fontname',this[this.selectedIndex].value);
72
- @ this.selectedIndex=0;">
70
+ @ <select class="format" data-format="fontname">
7371
@ <option class="heading" selected>- font -</option>
7472
@ <option>Arial</option>
7573
@ <option>Arial Black</option>
7674
@ <option>Courier New</option>
7775
@ <option>Times New Roman</option>
7876
@ </select>
79
- @ <select onchange="formatDoc('fontsize',this[this.selectedIndex].value);
80
- @ this.selectedIndex=0;">
77
+ @ <select class="format" data-format="fontsize">
8178
@ <option class="heading" selected>- size -</option>
8279
@ <option value="1">Very small</option>
8380
@ <option value="2">A bit small</option>
8481
@ <option value="3">Normal</option>
8582
@ <option value="4">Medium-large</option>
8683
@ <option value="5">Big</option>
8784
@ <option value="6">Very big</option>
8885
@ <option value="7">Maximum</option>
8986
@ </select>
90
- @ <select onchange="formatDoc('forecolor',this[this.selectedIndex].value);
91
- @ this.selectedIndex=0;">
87
+ @ <select class="format" data-format="forecolor">
9288
@ <option class="heading" selected>- color -</option>
9389
@ <option value="red">Red</option>
9490
@ <option value="blue">Blue</option>
9591
@ <option value="green">Green</option>
9692
@ <option value="black">Black</option>
9793
@ </select>
9894
@ </div>
9995
@ <div id="toolBar2">
100
- @ <img class="intLink" title="Undo" onclick="formatDoc('undo');"
96
+ @ <img class="intLink" title="Undo" data-format="undo"
10197
@ src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7
10298
@ /I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq704680
10399
@ 7TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfE
104100
@ whdRIH4fh/DZMICe3/C4nBQBADs=">
105101
106
- @ <img class="intLink" title="Redo" onclick="formatDoc('redo');"
102
+ @ <img class="intLink" title="Redo" data-format="redo"
107103
@ src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1/
108104
@ ///yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9Na
109105
@ EDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==">
110106
111
- @ <img class="intLink" title="Remove formatting"
112
- @ onclick="formatDoc('removeFormat')"
107
+ @ <img class="intLink" title="Remove formatting" data-format="removeFormat"
113108
@ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AA
114109
@ AABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwA
115110
@ AAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB5
116111
@ 01ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqG
117112
@ Xz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMz
@@ -126,98 +121,87 @@
126121
@ b/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCc
127122
@ XmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc66
128123
@ 6s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH
129124
@ 6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
130125
131
- @ <img class="intLink" title="Bold" onclick="formatDoc('bold');"
126
+ @ <img class="intLink" title="Bold" data-format="bold"
132127
@ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
133128
@ YAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
134129
135
- @ <img class="intLink" title="Italic" onclick="formatDoc('italic');"
130
+ @ <img class="intLink" title="Italic" data-format="italic"
136131
@ src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALA
137132
@ AAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
138133
139
- @ <img class="intLink" title="Underline" onclick="formatDoc('underline');"
134
+ @ <img class="intLink" title="Underline" data-format="underline"
140135
@ src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALA
141136
@ AAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA
142137
@ 7" />
143138
144
- @ <img class="intLink" title="Left align"
145
- @ onclick="formatDoc('justifyleft');"
139
+ @ <img class="intLink" title="Left align" data-format="justifyleft"
146140
@ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
147141
@ YAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
148142
149
- @ <img class="intLink" title="Center align"
150
- @ onclick="formatDoc('justifycenter');"
143
+ @ <img class="intLink" title="Center align" data-format="justifycenter"
151144
@ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
152145
@ YAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
153146
154
- @ <img class="intLink" title="Right align"
155
- @ onclick="formatDoc('justifyright');"
147
+ @ <img class="intLink" title="Right align" data-format="justifyright"
156148
@ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
157149
@ YAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
158150
@ <img class="intLink" title="Numbered list"
159
- @ onclick="formatDoc('insertorderedlist');"
151
+ @ data-format="insertorderedlist"
160152
@ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P////
161153
@ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEO
162154
@ zyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
163155
164
- @ <img class="intLink" title="Dotted list"
165
- @ onclick="formatDoc('insertunorderedlist');"
156
+ @ <img class="intLink" title="Dotted list"
157
+ @ data-format="insertunorderedlist"
166158
@ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv////
167159
@ ///yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud6
168160
@ 4UwiuKnigGQliQuWOyKQykgAAOw==" />
169161
170
- @ <img class="intLink" title="Quote"
171
- @ onclick="formatDoc('formatblock','blockquote');"
162
+ @ <img class="intLink" title="Quote" data-format="formatblock"
172163
@ src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2
173164
@ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P/////////
174165
@ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk
175166
@ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT
176167
@ q/b7/i8fp8PAQA7" />
177168
178
- @ <img class="intLink" title="Delete indentation"
179
- @ onclick="formatDoc('outdent');"
169
+ @ <img class="intLink" title="Delete indentation" data-format="outdent"
180170
@ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P
181171
@ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz
182172
@ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
183173
184
- @ <img class="intLink" title="Add indentation"
185
- @ onclick="formatDoc('indent');"
174
+ @ <img class="intLink" title="Add indentation" data-format="indent"
186175
@ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N
187176
@ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650
188177
@ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==">
189178
190
- @ <img class="intLink" title="Hyperlink"
191
- @ onclick="var sLnk=prompt('Target URL:','');
192
- @ if(sLnk&&sLnk!=''){formatDoc('createlink',sLnk)}"
179
+ @ <img class="intLink" title="Hyperlink" data-format="createlink"
193180
@ src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb
194181
@ /I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq704682
195182
@ 7/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghG
196183
@ i9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
197184
198185
#if 0 /* Cut/Copy/Paste requires special browser permissions for security
199186
** reasons. So omit these buttons */
200
- @ <img class="intLink" title="Cut"
201
- @ onclick="formatDoc('cut');"
187
+ @ <img class="intLink" title="Cut" data-format="cut"
202188
@ src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1
203189
@ dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P/////////////////////////////
204190
@ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnE
205191
@ bGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9
206192
@ ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
207193
208
- @ <img class="intLink" title="Copy"
209
- @ onclick="formatDoc('copy');"
194
+ @ <img class="intLink" title="Copy" data-format="copy"
210195
@ src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31
211196
@ iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OP
212197
@ s++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/
213198
@ kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQ
214199
@ ACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAA
215200
@ Grpy+wsbKzIiEAOw==" />
216201
217
- @ <img class="intLink" title="Paste"
218
- @ onclick="formatDoc('paste');"
202
+ @ <img class="intLink" title="Paste" data-format="paste"
219203
@ src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrp
220204
@ qbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f/////////////////////
221205
@ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvB
222206
@ SyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQ
223207
@ o9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAA
@@ -224,20 +208,58 @@
224208
@ MOaK+bLAOrtLUyt7i5uiUhADs=" />
225209
#endif
226210
227211
@ </div>
228212
@ <div id="wysiwygBox"
229
- @ style="resize:both; overflow:auto; width: %d(w)em; height: %d(h)em;"
213
+ @ style="resize:both;overflow:auto;width:95%%;min-height:%d(h)em;"
230214
@ contenteditable="true">%s(zContent)</div>
231
- @ <script>
215
+ @ <script nonce="%h(style_nonce())">
232216
@ var oDoc;
233217
@
234218
@ /* Initialize the document editor */
235219
@ function initDoc() {
220
+ @ initEventHandlers();
236221
@ oDoc = document.getElementById("wysiwygBox");
237222
@ if (!isWysiwyg()) { setDocMode(true); }
238223
@ }
224
+ @
225
+ @ function initEventHandlers() {
226
+ @ document.querySelector('form').onsubmit = wysiwygSubmit;
227
+ @ document.querySelector('#editMode').onchange = function() {
228
+ @ setDocMode(this.selectedIndex)
229
+ @ };
230
+ @ var controls = document.querySelectorAll('select.format');
231
+ @ for(var i = 0; i < controls.length; i++) {
232
+ @ controls[i].onchange = handleDropDown;
233
+ @ }
234
+ @ controls = document.querySelectorAll('.intLink');
235
+ @ for(i = 0; i < controls.length; i++) {
236
+ @ controls[i].onclick = handleFormatButton;
237
+ @ }
238
+ @
239
+ @ function handleDropDown() {
240
+ @ formatDoc(this.dataset.format,this[this.selectedIndex].value);
241
+ @ this.selectedIndex = 0;
242
+ @ }
243
+ @
244
+ @ function handleFormatButton() {
245
+ @ var extra;
246
+ @ switch (this.dataset.format) {
247
+ @ case 'createlink':
248
+ @ var sLnk = prompt('Target URL:','');
249
+ @ if(sLnk && sLnk != '')
250
+ @ {
251
+ @ extra = sLnk;
252
+ @ }
253
+ @ break;
254
+ @ case 'formatblock':
255
+ @ extra = 'blockquote';
256
+ @ break;
257
+ @ }
258
+ @ formatDoc(this.dataset.format, extra);
259
+ @ }
260
+ @ }
239261
@
240262
@ /* Return true if the document editor is in WYSIWYG mode. Return
241263
@ ** false if it is in Markup mode */
242264
@ function isWysiwyg() {
243265
@ return document.getElementById("editMode").selectedIndex==0;
244266
--- src/wysiwyg.c
+++ src/wysiwyg.c
@@ -49,17 +49,16 @@
49 @ #editMode label { cursor: pointer; }
50 @ </style>
51
52 @ <input id="wysiwygValue" type="hidden" name="%s(zId)">
53 @ <div id="editModeDiv">Edit mode:
54 @ <select id="editMode" size=1 onchange="setDocMode(this.selectedIndex)">
55 @ <option value="0">WYSIWYG</option>
56 @ <option value="1">Raw HTML</option>
57 @ </select></div>
58 @ <div id="toolBar1">
59 @ <select onchange="formatDoc('formatblock',this[this.selectedIndex].value);
60 @ this.selectedIndex=0;">
61 @ <option selected>- formatting -</option>
62 @ <option value="h1">Title 1 &lt;h1&gt;</option>
63 @ <option value="h2">Title 2 &lt;h2&gt;</option>
64 @ <option value="h3">Title 3 &lt;h3&gt;</option>
65 @ <option value="h4">Title 4 &lt;h4&gt;</option>
@@ -66,52 +65,48 @@
66 @ <option value="h5">Title 5 &lt;h5&gt;</option>
67 @ <option value="h6">Subtitle &lt;h6&gt;</option>
68 @ <option value="p">Paragraph &lt;p&gt;</option>
69 @ <option value="pre">Preformatted &lt;pre&gt;</option>
70 @ </select>
71 @ <select onchange="formatDoc('fontname',this[this.selectedIndex].value);
72 @ this.selectedIndex=0;">
73 @ <option class="heading" selected>- font -</option>
74 @ <option>Arial</option>
75 @ <option>Arial Black</option>
76 @ <option>Courier New</option>
77 @ <option>Times New Roman</option>
78 @ </select>
79 @ <select onchange="formatDoc('fontsize',this[this.selectedIndex].value);
80 @ this.selectedIndex=0;">
81 @ <option class="heading" selected>- size -</option>
82 @ <option value="1">Very small</option>
83 @ <option value="2">A bit small</option>
84 @ <option value="3">Normal</option>
85 @ <option value="4">Medium-large</option>
86 @ <option value="5">Big</option>
87 @ <option value="6">Very big</option>
88 @ <option value="7">Maximum</option>
89 @ </select>
90 @ <select onchange="formatDoc('forecolor',this[this.selectedIndex].value);
91 @ this.selectedIndex=0;">
92 @ <option class="heading" selected>- color -</option>
93 @ <option value="red">Red</option>
94 @ <option value="blue">Blue</option>
95 @ <option value="green">Green</option>
96 @ <option value="black">Black</option>
97 @ </select>
98 @ </div>
99 @ <div id="toolBar2">
100 @ <img class="intLink" title="Undo" onclick="formatDoc('undo');"
101 @ src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7
102 @ /I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq704680
103 @ 7TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfE
104 @ whdRIH4fh/DZMICe3/C4nBQBADs=">
105
106 @ <img class="intLink" title="Redo" onclick="formatDoc('redo');"
107 @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1/
108 @ ///yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9Na
109 @ EDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==">
110
111 @ <img class="intLink" title="Remove formatting"
112 @ onclick="formatDoc('removeFormat')"
113 @ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AA
114 @ AABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwA
115 @ AAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB5
116 @ 01ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqG
117 @ Xz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMz
@@ -126,98 +121,87 @@
126 @ b/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCc
127 @ XmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc66
128 @ 6s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH
129 @ 6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
130
131 @ <img class="intLink" title="Bold" onclick="formatDoc('bold');"
132 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
133 @ YAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
134
135 @ <img class="intLink" title="Italic" onclick="formatDoc('italic');"
136 @ src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALA
137 @ AAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
138
139 @ <img class="intLink" title="Underline" onclick="formatDoc('underline');"
140 @ src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALA
141 @ AAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA
142 @ 7" />
143
144 @ <img class="intLink" title="Left align"
145 @ onclick="formatDoc('justifyleft');"
146 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
147 @ YAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
148
149 @ <img class="intLink" title="Center align"
150 @ onclick="formatDoc('justifycenter');"
151 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
152 @ YAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
153
154 @ <img class="intLink" title="Right align"
155 @ onclick="formatDoc('justifyright');"
156 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
157 @ YAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
158 @ <img class="intLink" title="Numbered list"
159 @ onclick="formatDoc('insertorderedlist');"
160 @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P////
161 @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEO
162 @ zyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
163
164 @ <img class="intLink" title="Dotted list"
165 @ onclick="formatDoc('insertunorderedlist');"
166 @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv////
167 @ ///yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud6
168 @ 4UwiuKnigGQliQuWOyKQykgAAOw==" />
169
170 @ <img class="intLink" title="Quote"
171 @ onclick="formatDoc('formatblock','blockquote');"
172 @ src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2
173 @ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P/////////
174 @ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk
175 @ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT
176 @ q/b7/i8fp8PAQA7" />
177
178 @ <img class="intLink" title="Delete indentation"
179 @ onclick="formatDoc('outdent');"
180 @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P
181 @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz
182 @ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
183
184 @ <img class="intLink" title="Add indentation"
185 @ onclick="formatDoc('indent');"
186 @ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N
187 @ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650
188 @ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==">
189
190 @ <img class="intLink" title="Hyperlink"
191 @ onclick="var sLnk=prompt('Target URL:','');
192 @ if(sLnk&&sLnk!=''){formatDoc('createlink',sLnk)}"
193 @ src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb
194 @ /I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq704682
195 @ 7/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghG
196 @ i9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
197
198 #if 0 /* Cut/Copy/Paste requires special browser permissions for security
199 ** reasons. So omit these buttons */
200 @ <img class="intLink" title="Cut"
201 @ onclick="formatDoc('cut');"
202 @ src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1
203 @ dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P/////////////////////////////
204 @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnE
205 @ bGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9
206 @ ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
207
208 @ <img class="intLink" title="Copy"
209 @ onclick="formatDoc('copy');"
210 @ src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31
211 @ iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OP
212 @ s++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/
213 @ kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQ
214 @ ACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAA
215 @ Grpy+wsbKzIiEAOw==" />
216
217 @ <img class="intLink" title="Paste"
218 @ onclick="formatDoc('paste');"
219 @ src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrp
220 @ qbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f/////////////////////
221 @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvB
222 @ SyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQ
223 @ o9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAA
@@ -224,20 +208,58 @@
224 @ MOaK+bLAOrtLUyt7i5uiUhADs=" />
225 #endif
226
227 @ </div>
228 @ <div id="wysiwygBox"
229 @ style="resize:both; overflow:auto; width: %d(w)em; height: %d(h)em;"
230 @ contenteditable="true">%s(zContent)</div>
231 @ <script>
232 @ var oDoc;
233 @
234 @ /* Initialize the document editor */
235 @ function initDoc() {
 
236 @ oDoc = document.getElementById("wysiwygBox");
237 @ if (!isWysiwyg()) { setDocMode(true); }
238 @ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239 @
240 @ /* Return true if the document editor is in WYSIWYG mode. Return
241 @ ** false if it is in Markup mode */
242 @ function isWysiwyg() {
243 @ return document.getElementById("editMode").selectedIndex==0;
244
--- src/wysiwyg.c
+++ src/wysiwyg.c
@@ -49,17 +49,16 @@
49 @ #editMode label { cursor: pointer; }
50 @ </style>
51
52 @ <input id="wysiwygValue" type="hidden" name="%s(zId)">
53 @ <div id="editModeDiv">Edit mode:
54 @ <select id="editMode" size=1>
55 @ <option value="0">WYSIWYG</option>
56 @ <option value="1">Raw HTML</option>
57 @ </select></div>
58 @ <div id="toolBar1">
59 @ <select class="format" data-format="formatblock">
 
60 @ <option selected>- formatting -</option>
61 @ <option value="h1">Title 1 &lt;h1&gt;</option>
62 @ <option value="h2">Title 2 &lt;h2&gt;</option>
63 @ <option value="h3">Title 3 &lt;h3&gt;</option>
64 @ <option value="h4">Title 4 &lt;h4&gt;</option>
@@ -66,52 +65,48 @@
65 @ <option value="h5">Title 5 &lt;h5&gt;</option>
66 @ <option value="h6">Subtitle &lt;h6&gt;</option>
67 @ <option value="p">Paragraph &lt;p&gt;</option>
68 @ <option value="pre">Preformatted &lt;pre&gt;</option>
69 @ </select>
70 @ <select class="format" data-format="fontname">
 
71 @ <option class="heading" selected>- font -</option>
72 @ <option>Arial</option>
73 @ <option>Arial Black</option>
74 @ <option>Courier New</option>
75 @ <option>Times New Roman</option>
76 @ </select>
77 @ <select class="format" data-format="fontsize">
 
78 @ <option class="heading" selected>- size -</option>
79 @ <option value="1">Very small</option>
80 @ <option value="2">A bit small</option>
81 @ <option value="3">Normal</option>
82 @ <option value="4">Medium-large</option>
83 @ <option value="5">Big</option>
84 @ <option value="6">Very big</option>
85 @ <option value="7">Maximum</option>
86 @ </select>
87 @ <select class="format" data-format="forecolor">
 
88 @ <option class="heading" selected>- color -</option>
89 @ <option value="red">Red</option>
90 @ <option value="blue">Blue</option>
91 @ <option value="green">Green</option>
92 @ <option value="black">Black</option>
93 @ </select>
94 @ </div>
95 @ <div id="toolBar2">
96 @ <img class="intLink" title="Undo" data-format="undo"
97 @ src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7
98 @ /I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq704680
99 @ 7TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfE
100 @ whdRIH4fh/DZMICe3/C4nBQBADs=">
101
102 @ <img class="intLink" title="Redo" data-format="redo"
103 @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1/
104 @ ///yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9Na
105 @ EDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==">
106
107 @ <img class="intLink" title="Remove formatting" data-format="removeFormat"
 
108 @ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AA
109 @ AABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwA
110 @ AAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB5
111 @ 01ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqG
112 @ Xz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMz
@@ -126,98 +121,87 @@
121 @ b/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCc
122 @ XmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc66
123 @ 6s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH
124 @ 6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
125
126 @ <img class="intLink" title="Bold" data-format="bold"
127 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
128 @ YAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
129
130 @ <img class="intLink" title="Italic" data-format="italic"
131 @ src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALA
132 @ AAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
133
134 @ <img class="intLink" title="Underline" data-format="underline"
135 @ src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALA
136 @ AAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA
137 @ 7" />
138
139 @ <img class="intLink" title="Left align" data-format="justifyleft"
 
140 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
141 @ YAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
142
143 @ <img class="intLink" title="Center align" data-format="justifycenter"
 
144 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
145 @ YAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
146
147 @ <img class="intLink" title="Right align" data-format="justifyright"
 
148 @ src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWAB
149 @ YAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
150 @ <img class="intLink" title="Numbered list"
151 @ data-format="insertorderedlist"
152 @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P////
153 @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEO
154 @ zyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
155
156 @ <img class="intLink" title="Dotted list"
157 @ data-format="insertunorderedlist"
158 @ src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv////
159 @ ///yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud6
160 @ 4UwiuKnigGQliQuWOyKQykgAAOw==" />
161
162 @ <img class="intLink" title="Quote" data-format="formatblock"
 
163 @ src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2
164 @ R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P/////////
165 @ //////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2Cekk
166 @ ErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrT
167 @ q/b7/i8fp8PAQA7" />
168
169 @ <img class="intLink" title="Delete indentation" data-format="outdent"
 
170 @ src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P
171 @ ///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMcz
172 @ sYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
173
174 @ <img class="intLink" title="Add indentation" data-format="indent"
 
175 @ src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3N
176 @ Ha7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650
177 @ B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==">
178
179 @ <img class="intLink" title="Hyperlink" data-format="createlink"
 
 
180 @ src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb
181 @ /I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq704682
182 @ 7/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghG
183 @ i9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
184
185 #if 0 /* Cut/Copy/Paste requires special browser permissions for security
186 ** reasons. So omit these buttons */
187 @ <img class="intLink" title="Cut" data-format="cut"
 
188 @ src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1
189 @ dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P/////////////////////////////
190 @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnE
191 @ bGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9
192 @ ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
193
194 @ <img class="intLink" title="Copy" data-format="copy"
 
195 @ src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31
196 @ iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OP
197 @ s++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/
198 @ kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQ
199 @ ACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAA
200 @ Grpy+wsbKzIiEAOw==" />
201
202 @ <img class="intLink" title="Paste" data-format="paste"
 
203 @ src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrp
204 @ qbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f/////////////////////
205 @ //////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvB
206 @ SyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQ
207 @ o9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAA
@@ -224,20 +208,58 @@
208 @ MOaK+bLAOrtLUyt7i5uiUhADs=" />
209 #endif
210
211 @ </div>
212 @ <div id="wysiwygBox"
213 @ style="resize:both;overflow:auto;width:95%%;min-height:%d(h)em;"
214 @ contenteditable="true">%s(zContent)</div>
215 @ <script nonce="%h(style_nonce())">
216 @ var oDoc;
217 @
218 @ /* Initialize the document editor */
219 @ function initDoc() {
220 @ initEventHandlers();
221 @ oDoc = document.getElementById("wysiwygBox");
222 @ if (!isWysiwyg()) { setDocMode(true); }
223 @ }
224 @
225 @ function initEventHandlers() {
226 @ document.querySelector('form').onsubmit = wysiwygSubmit;
227 @ document.querySelector('#editMode').onchange = function() {
228 @ setDocMode(this.selectedIndex)
229 @ };
230 @ var controls = document.querySelectorAll('select.format');
231 @ for(var i = 0; i < controls.length; i++) {
232 @ controls[i].onchange = handleDropDown;
233 @ }
234 @ controls = document.querySelectorAll('.intLink');
235 @ for(i = 0; i < controls.length; i++) {
236 @ controls[i].onclick = handleFormatButton;
237 @ }
238 @
239 @ function handleDropDown() {
240 @ formatDoc(this.dataset.format,this[this.selectedIndex].value);
241 @ this.selectedIndex = 0;
242 @ }
243 @
244 @ function handleFormatButton() {
245 @ var extra;
246 @ switch (this.dataset.format) {
247 @ case 'createlink':
248 @ var sLnk = prompt('Target URL:','');
249 @ if(sLnk && sLnk != '')
250 @ {
251 @ extra = sLnk;
252 @ }
253 @ break;
254 @ case 'formatblock':
255 @ extra = 'blockquote';
256 @ break;
257 @ }
258 @ formatDoc(this.dataset.format, extra);
259 @ }
260 @ }
261 @
262 @ /* Return true if the document editor is in WYSIWYG mode. Return
263 @ ** false if it is in Markup mode */
264 @ function isWysiwyg() {
265 @ return document.getElementById("editMode").selectedIndex==0;
266
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -83,17 +83,17 @@
8383
8484
# define the SQLite files, which need special flags on compile
8585
SQLITESRC=sqlite3.c
8686
ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
8787
SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
88
-SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_WIN32_NO_ANSI
88
+SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_WIN32_NO_ANSI
8989
9090
# define the SQLite shell files, which need special flags on compile
9191
SQLITESHELLSRC=shell.c
9292
ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
9393
SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
94
-SQLITESHELLDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
94
+SQLITESHELLDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
9595
9696
# define the th scripting files, which need special flags on compile
9797
THSRC=th.c th_lang.c
9898
ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
9999
THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
100100
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -83,17 +83,17 @@
83
84 # define the SQLite files, which need special flags on compile
85 SQLITESRC=sqlite3.c
86 ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
87 SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
88 SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_WIN32_NO_ANSI
89
90 # define the SQLite shell files, which need special flags on compile
91 SQLITESHELLSRC=shell.c
92 ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
93 SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
94 SQLITESHELLDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
95
96 # define the th scripting files, which need special flags on compile
97 THSRC=th.c th_lang.c
98 ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
99 THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
100
--- win/Makefile.PellesCGMake
+++ win/Makefile.PellesCGMake
@@ -83,17 +83,17 @@
83
84 # define the SQLite files, which need special flags on compile
85 SQLITESRC=sqlite3.c
86 ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf))
87 SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
88 SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_WIN32_NO_ANSI
89
90 # define the SQLite shell files, which need special flags on compile
91 SQLITESHELLSRC=shell.c
92 ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf))
93 SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
94 SQLITESHELLDEFINES=-DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
95
96 # define the th scripting files, which need special flags on compile
97 THSRC=th.c th_lang.c
98 ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
99 THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
100
+12 -6
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -24,17 +24,17 @@
2424
CFLAGS = -o
2525
BCC = $(DMDIR)\bin\dmc $(CFLAGS)
2626
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
2727
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
2828
29
-SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB
29
+SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB
3030
31
-SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
31
+SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
3232
33
-SRC = add_.c alerts_.c allrepo_.c attach_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
33
+SRC = add_.c alerts_.c allrepo_.c attach_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
3434
35
-OBJ = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
35
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3636
3737
3838
RC=$(DMDIR)\bin\rcc
3939
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
4040
@@ -49,11 +49,11 @@
4949
5050
$(OBJDIR)\fossil.res: $B\win\fossil.rc
5151
$(RC) $(RCFLAGS) -o$@ $**
5252
5353
$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54
- +echo add alerts allrepo attach backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci forum fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
54
+ +echo add alerts allrepo attach backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci forum fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
5555
+echo fossil >> $@
5656
+echo fossil >> $@
5757
+echo $(LIBS) >> $@
5858
+echo. >> $@
5959
+echo fossil >> $@
@@ -668,10 +668,16 @@
668668
$(OBJDIR)\regexp$O : regexp_.c regexp.h
669669
$(TCC) -o$@ -c regexp_.c
670670
671671
regexp_.c : $(SRCDIR)\regexp.c
672672
+translate$E $** > $@
673
+
674
+$(OBJDIR)\repolist$O : repolist_.c repolist.h
675
+ $(TCC) -o$@ -c repolist_.c
676
+
677
+repolist_.c : $(SRCDIR)\repolist.c
678
+ +translate$E $** > $@
673679
674680
$(OBJDIR)\report$O : report_.c report.h
675681
$(TCC) -o$@ -c report_.c
676682
677683
report_.c : $(SRCDIR)\report.c
@@ -940,7 +946,7 @@
940946
941947
zip_.c : $(SRCDIR)\zip.c
942948
+translate$E $** > $@
943949
944950
headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
945
- +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
951
+ +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
946952
@copy /Y nul: headers
947953
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -24,17 +24,17 @@
24 CFLAGS = -o
25 BCC = $(DMDIR)\bin\dmc $(CFLAGS)
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB
30
31 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c alerts_.c allrepo_.c attach_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
34
35 OBJ = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
@@ -49,11 +49,11 @@
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
53 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54 +echo add alerts allrepo attach backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci forum fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
55 +echo fossil >> $@
56 +echo fossil >> $@
57 +echo $(LIBS) >> $@
58 +echo. >> $@
59 +echo fossil >> $@
@@ -668,10 +668,16 @@
668 $(OBJDIR)\regexp$O : regexp_.c regexp.h
669 $(TCC) -o$@ -c regexp_.c
670
671 regexp_.c : $(SRCDIR)\regexp.c
672 +translate$E $** > $@
 
 
 
 
 
 
673
674 $(OBJDIR)\report$O : report_.c report.h
675 $(TCC) -o$@ -c report_.c
676
677 report_.c : $(SRCDIR)\report.c
@@ -940,7 +946,7 @@
940
941 zip_.c : $(SRCDIR)\zip.c
942 +translate$E $** > $@
943
944 headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
945 +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
946 @copy /Y nul: headers
947
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -24,17 +24,17 @@
24 CFLAGS = -o
25 BCC = $(DMDIR)\bin\dmc $(CFLAGS)
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB
30
31 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
32
33 SRC = add_.c alerts_.c allrepo_.c attach_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
34
35 OBJ = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
36
37
38 RC=$(DMDIR)\bin\rcc
39 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
40
@@ -49,11 +49,11 @@
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
53 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
54 +echo add alerts allrepo attach backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci forum fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
55 +echo fossil >> $@
56 +echo fossil >> $@
57 +echo $(LIBS) >> $@
58 +echo. >> $@
59 +echo fossil >> $@
@@ -668,10 +668,16 @@
668 $(OBJDIR)\regexp$O : regexp_.c regexp.h
669 $(TCC) -o$@ -c regexp_.c
670
671 regexp_.c : $(SRCDIR)\regexp.c
672 +translate$E $** > $@
673
674 $(OBJDIR)\repolist$O : repolist_.c repolist.h
675 $(TCC) -o$@ -c repolist_.c
676
677 repolist_.c : $(SRCDIR)\repolist.c
678 +translate$E $** > $@
679
680 $(OBJDIR)\report$O : report_.c report.h
681 $(TCC) -o$@ -c report_.c
682
683 report_.c : $(SRCDIR)\report.c
@@ -940,7 +946,7 @@
946
947 zip_.c : $(SRCDIR)\zip.c
948 +translate$E $** > $@
949
950 headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
951 +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
952 @copy /Y nul: headers
953
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -174,11 +174,11 @@
174174
#### The directories where the OpenSSL include and library files are located.
175175
# The recommended usage here is to use the Sysinternals junction tool
176176
# to create a hard link between an "openssl-1.x" sub-directory of the
177177
# Fossil source code directory and the target OpenSSL source directory.
178178
#
179
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
179
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180180
OPENSSLINCDIR = $(OPENSSLDIR)/include
181181
OPENSSLLIBDIR = $(OPENSSLDIR)
182182
183183
#### Either the directory where the Tcl library is installed or the Tcl
184184
# source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526526
$(SRCDIR)/printf.c \
527527
$(SRCDIR)/publish.c \
528528
$(SRCDIR)/purge.c \
529529
$(SRCDIR)/rebuild.c \
530530
$(SRCDIR)/regexp.c \
531
+ $(SRCDIR)/repolist.c \
531532
$(SRCDIR)/report.c \
532533
$(SRCDIR)/rss.c \
533534
$(SRCDIR)/schema.c \
534535
$(SRCDIR)/search.c \
535536
$(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736737
$(OBJDIR)/printf_.c \
737738
$(OBJDIR)/publish_.c \
738739
$(OBJDIR)/purge_.c \
739740
$(OBJDIR)/rebuild_.c \
740741
$(OBJDIR)/regexp_.c \
742
+ $(OBJDIR)/repolist_.c \
741743
$(OBJDIR)/report_.c \
742744
$(OBJDIR)/rss_.c \
743745
$(OBJDIR)/schema_.c \
744746
$(OBJDIR)/search_.c \
745747
$(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873875
$(OBJDIR)/printf.o \
874876
$(OBJDIR)/publish.o \
875877
$(OBJDIR)/purge.o \
876878
$(OBJDIR)/rebuild.o \
877879
$(OBJDIR)/regexp.o \
880
+ $(OBJDIR)/repolist.o \
878881
$(OBJDIR)/report.o \
879882
$(OBJDIR)/rss.o \
880883
$(OBJDIR)/schema.o \
881884
$(OBJDIR)/search.o \
882885
$(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
12291232
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
12301233
$(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
12311234
$(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
12321235
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
12331236
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237
+ $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
12341238
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
12351239
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
12361240
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
12371241
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
12381242
$(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
20022006
20032007
$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
20042008
$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
20052009
20062010
$(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
+
2012
+$(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013
+ $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
+
2015
+$(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016
+ $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
+
2018
+$(OBJDIR)/repolist.h: $(OBJDIR)/headers
20072019
20082020
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
20092021
$(TRANSLATE) $(SRCDIR)/report.c >$@
20102022
20112023
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
23822394
-DSQLITE_USE_ALLOCA \
23832395
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
23842396
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
23852397
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
23862398
-DSQLITE_ENABLE_FTS4 \
2387
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
23882399
-DSQLITE_ENABLE_DBSTAT_VTAB \
23892400
-DSQLITE_ENABLE_JSON1 \
23902401
-DSQLITE_ENABLE_FTS5 \
23912402
-DSQLITE_ENABLE_STMTVTAB \
23922403
-DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
24122423
-DSQLITE_USE_ALLOCA \
24132424
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
24142425
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
24152426
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
24162427
-DSQLITE_ENABLE_FTS4 \
2417
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
24182428
-DSQLITE_ENABLE_DBSTAT_VTAB \
24192429
-DSQLITE_ENABLE_JSON1 \
24202430
-DSQLITE_ENABLE_FTS5 \
24212431
-DSQLITE_ENABLE_STMTVTAB \
24222432
-DSQLITE_HAVE_ZLIB \
24232433
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
 
531 $(SRCDIR)/report.c \
532 $(SRCDIR)/rss.c \
533 $(SRCDIR)/schema.c \
534 $(SRCDIR)/search.c \
535 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736 $(OBJDIR)/printf_.c \
737 $(OBJDIR)/publish_.c \
738 $(OBJDIR)/purge_.c \
739 $(OBJDIR)/rebuild_.c \
740 $(OBJDIR)/regexp_.c \
 
741 $(OBJDIR)/report_.c \
742 $(OBJDIR)/rss_.c \
743 $(OBJDIR)/schema_.c \
744 $(OBJDIR)/search_.c \
745 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873 $(OBJDIR)/printf.o \
874 $(OBJDIR)/publish.o \
875 $(OBJDIR)/purge.o \
876 $(OBJDIR)/rebuild.o \
877 $(OBJDIR)/regexp.o \
 
878 $(OBJDIR)/report.o \
879 $(OBJDIR)/rss.o \
880 $(OBJDIR)/schema.o \
881 $(OBJDIR)/search.o \
882 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1229 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1230 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1231 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1232 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1233 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
 
1234 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1235 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1236 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1237 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1238 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2002
2003 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2004 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2005
2006 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
2007
2008 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2009 $(TRANSLATE) $(SRCDIR)/report.c >$@
2010
2011 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2382 -DSQLITE_USE_ALLOCA \
2383 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2384 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2385 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2386 -DSQLITE_ENABLE_FTS4 \
2387 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2388 -DSQLITE_ENABLE_DBSTAT_VTAB \
2389 -DSQLITE_ENABLE_JSON1 \
2390 -DSQLITE_ENABLE_FTS5 \
2391 -DSQLITE_ENABLE_STMTVTAB \
2392 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2412 -DSQLITE_USE_ALLOCA \
2413 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2414 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2415 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2416 -DSQLITE_ENABLE_FTS4 \
2417 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2418 -DSQLITE_ENABLE_DBSTAT_VTAB \
2419 -DSQLITE_ENABLE_JSON1 \
2420 -DSQLITE_ENABLE_FTS5 \
2421 -DSQLITE_ENABLE_STMTVTAB \
2422 -DSQLITE_HAVE_ZLIB \
2423
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
531 $(SRCDIR)/repolist.c \
532 $(SRCDIR)/report.c \
533 $(SRCDIR)/rss.c \
534 $(SRCDIR)/schema.c \
535 $(SRCDIR)/search.c \
536 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
737 $(OBJDIR)/printf_.c \
738 $(OBJDIR)/publish_.c \
739 $(OBJDIR)/purge_.c \
740 $(OBJDIR)/rebuild_.c \
741 $(OBJDIR)/regexp_.c \
742 $(OBJDIR)/repolist_.c \
743 $(OBJDIR)/report_.c \
744 $(OBJDIR)/rss_.c \
745 $(OBJDIR)/schema_.c \
746 $(OBJDIR)/search_.c \
747 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
875 $(OBJDIR)/printf.o \
876 $(OBJDIR)/publish.o \
877 $(OBJDIR)/purge.o \
878 $(OBJDIR)/rebuild.o \
879 $(OBJDIR)/regexp.o \
880 $(OBJDIR)/repolist.o \
881 $(OBJDIR)/report.o \
882 $(OBJDIR)/rss.o \
883 $(OBJDIR)/schema.o \
884 $(OBJDIR)/search.o \
885 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1232 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1233 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1234 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1235 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1236 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237 $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
1238 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1239 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1240 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1241 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1242 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2006
2007 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2008 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2009
2010 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
2012 $(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013 $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
2015 $(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016 $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
2018 $(OBJDIR)/repolist.h: $(OBJDIR)/headers
2019
2020 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2021 $(TRANSLATE) $(SRCDIR)/report.c >$@
2022
2023 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2394 -DSQLITE_USE_ALLOCA \
2395 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2396 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2397 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2398 -DSQLITE_ENABLE_FTS4 \
 
2399 -DSQLITE_ENABLE_DBSTAT_VTAB \
2400 -DSQLITE_ENABLE_JSON1 \
2401 -DSQLITE_ENABLE_FTS5 \
2402 -DSQLITE_ENABLE_STMTVTAB \
2403 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2423 -DSQLITE_USE_ALLOCA \
2424 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2425 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2426 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2427 -DSQLITE_ENABLE_FTS4 \
 
2428 -DSQLITE_ENABLE_DBSTAT_VTAB \
2429 -DSQLITE_ENABLE_JSON1 \
2430 -DSQLITE_ENABLE_FTS5 \
2431 -DSQLITE_ENABLE_STMTVTAB \
2432 -DSQLITE_HAVE_ZLIB \
2433
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -174,11 +174,11 @@
174174
#### The directories where the OpenSSL include and library files are located.
175175
# The recommended usage here is to use the Sysinternals junction tool
176176
# to create a hard link between an "openssl-1.x" sub-directory of the
177177
# Fossil source code directory and the target OpenSSL source directory.
178178
#
179
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
179
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180180
OPENSSLINCDIR = $(OPENSSLDIR)/include
181181
OPENSSLLIBDIR = $(OPENSSLDIR)
182182
183183
#### Either the directory where the Tcl library is installed or the Tcl
184184
# source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526526
$(SRCDIR)/printf.c \
527527
$(SRCDIR)/publish.c \
528528
$(SRCDIR)/purge.c \
529529
$(SRCDIR)/rebuild.c \
530530
$(SRCDIR)/regexp.c \
531
+ $(SRCDIR)/repolist.c \
531532
$(SRCDIR)/report.c \
532533
$(SRCDIR)/rss.c \
533534
$(SRCDIR)/schema.c \
534535
$(SRCDIR)/search.c \
535536
$(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736737
$(OBJDIR)/printf_.c \
737738
$(OBJDIR)/publish_.c \
738739
$(OBJDIR)/purge_.c \
739740
$(OBJDIR)/rebuild_.c \
740741
$(OBJDIR)/regexp_.c \
742
+ $(OBJDIR)/repolist_.c \
741743
$(OBJDIR)/report_.c \
742744
$(OBJDIR)/rss_.c \
743745
$(OBJDIR)/schema_.c \
744746
$(OBJDIR)/search_.c \
745747
$(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873875
$(OBJDIR)/printf.o \
874876
$(OBJDIR)/publish.o \
875877
$(OBJDIR)/purge.o \
876878
$(OBJDIR)/rebuild.o \
877879
$(OBJDIR)/regexp.o \
880
+ $(OBJDIR)/repolist.o \
878881
$(OBJDIR)/report.o \
879882
$(OBJDIR)/rss.o \
880883
$(OBJDIR)/schema.o \
881884
$(OBJDIR)/search.o \
882885
$(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
12291232
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
12301233
$(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
12311234
$(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
12321235
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
12331236
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237
+ $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
12341238
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
12351239
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
12361240
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
12371241
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
12381242
$(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
20022006
20032007
$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
20042008
$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
20052009
20062010
$(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
+
2012
+$(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013
+ $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
+
2015
+$(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016
+ $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
+
2018
+$(OBJDIR)/repolist.h: $(OBJDIR)/headers
20072019
20082020
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
20092021
$(TRANSLATE) $(SRCDIR)/report.c >$@
20102022
20112023
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
23822394
-DSQLITE_USE_ALLOCA \
23832395
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
23842396
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
23852397
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
23862398
-DSQLITE_ENABLE_FTS4 \
2387
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
23882399
-DSQLITE_ENABLE_DBSTAT_VTAB \
23892400
-DSQLITE_ENABLE_JSON1 \
23902401
-DSQLITE_ENABLE_FTS5 \
23912402
-DSQLITE_ENABLE_STMTVTAB \
23922403
-DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
24122423
-DSQLITE_USE_ALLOCA \
24132424
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
24142425
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
24152426
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
24162427
-DSQLITE_ENABLE_FTS4 \
2417
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
24182428
-DSQLITE_ENABLE_DBSTAT_VTAB \
24192429
-DSQLITE_ENABLE_JSON1 \
24202430
-DSQLITE_ENABLE_FTS5 \
24212431
-DSQLITE_ENABLE_STMTVTAB \
24222432
-DSQLITE_HAVE_ZLIB \
24232433
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
 
531 $(SRCDIR)/report.c \
532 $(SRCDIR)/rss.c \
533 $(SRCDIR)/schema.c \
534 $(SRCDIR)/search.c \
535 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736 $(OBJDIR)/printf_.c \
737 $(OBJDIR)/publish_.c \
738 $(OBJDIR)/purge_.c \
739 $(OBJDIR)/rebuild_.c \
740 $(OBJDIR)/regexp_.c \
 
741 $(OBJDIR)/report_.c \
742 $(OBJDIR)/rss_.c \
743 $(OBJDIR)/schema_.c \
744 $(OBJDIR)/search_.c \
745 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873 $(OBJDIR)/printf.o \
874 $(OBJDIR)/publish.o \
875 $(OBJDIR)/purge.o \
876 $(OBJDIR)/rebuild.o \
877 $(OBJDIR)/regexp.o \
 
878 $(OBJDIR)/report.o \
879 $(OBJDIR)/rss.o \
880 $(OBJDIR)/schema.o \
881 $(OBJDIR)/search.o \
882 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1229 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1230 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1231 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1232 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1233 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
 
1234 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1235 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1236 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1237 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1238 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2002
2003 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2004 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2005
2006 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
2007
2008 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2009 $(TRANSLATE) $(SRCDIR)/report.c >$@
2010
2011 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2382 -DSQLITE_USE_ALLOCA \
2383 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2384 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2385 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2386 -DSQLITE_ENABLE_FTS4 \
2387 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2388 -DSQLITE_ENABLE_DBSTAT_VTAB \
2389 -DSQLITE_ENABLE_JSON1 \
2390 -DSQLITE_ENABLE_FTS5 \
2391 -DSQLITE_ENABLE_STMTVTAB \
2392 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2412 -DSQLITE_USE_ALLOCA \
2413 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2414 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2415 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2416 -DSQLITE_ENABLE_FTS4 \
2417 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2418 -DSQLITE_ENABLE_DBSTAT_VTAB \
2419 -DSQLITE_ENABLE_JSON1 \
2420 -DSQLITE_ENABLE_FTS5 \
2421 -DSQLITE_ENABLE_STMTVTAB \
2422 -DSQLITE_HAVE_ZLIB \
2423
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
531 $(SRCDIR)/repolist.c \
532 $(SRCDIR)/report.c \
533 $(SRCDIR)/rss.c \
534 $(SRCDIR)/schema.c \
535 $(SRCDIR)/search.c \
536 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
737 $(OBJDIR)/printf_.c \
738 $(OBJDIR)/publish_.c \
739 $(OBJDIR)/purge_.c \
740 $(OBJDIR)/rebuild_.c \
741 $(OBJDIR)/regexp_.c \
742 $(OBJDIR)/repolist_.c \
743 $(OBJDIR)/report_.c \
744 $(OBJDIR)/rss_.c \
745 $(OBJDIR)/schema_.c \
746 $(OBJDIR)/search_.c \
747 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
875 $(OBJDIR)/printf.o \
876 $(OBJDIR)/publish.o \
877 $(OBJDIR)/purge.o \
878 $(OBJDIR)/rebuild.o \
879 $(OBJDIR)/regexp.o \
880 $(OBJDIR)/repolist.o \
881 $(OBJDIR)/report.o \
882 $(OBJDIR)/rss.o \
883 $(OBJDIR)/schema.o \
884 $(OBJDIR)/search.o \
885 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1232 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1233 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1234 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1235 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1236 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237 $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
1238 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1239 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1240 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1241 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1242 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2006
2007 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2008 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2009
2010 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
2012 $(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013 $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
2015 $(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016 $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
2018 $(OBJDIR)/repolist.h: $(OBJDIR)/headers
2019
2020 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2021 $(TRANSLATE) $(SRCDIR)/report.c >$@
2022
2023 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2394 -DSQLITE_USE_ALLOCA \
2395 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2396 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2397 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2398 -DSQLITE_ENABLE_FTS4 \
 
2399 -DSQLITE_ENABLE_DBSTAT_VTAB \
2400 -DSQLITE_ENABLE_JSON1 \
2401 -DSQLITE_ENABLE_FTS5 \
2402 -DSQLITE_ENABLE_STMTVTAB \
2403 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2423 -DSQLITE_USE_ALLOCA \
2424 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2425 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2426 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2427 -DSQLITE_ENABLE_FTS4 \
 
2428 -DSQLITE_ENABLE_DBSTAT_VTAB \
2429 -DSQLITE_ENABLE_JSON1 \
2430 -DSQLITE_ENABLE_FTS5 \
2431 -DSQLITE_ENABLE_STMTVTAB \
2432 -DSQLITE_HAVE_ZLIB \
2433
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -174,11 +174,11 @@
174174
#### The directories where the OpenSSL include and library files are located.
175175
# The recommended usage here is to use the Sysinternals junction tool
176176
# to create a hard link between an "openssl-1.x" sub-directory of the
177177
# Fossil source code directory and the target OpenSSL source directory.
178178
#
179
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
179
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180180
OPENSSLINCDIR = $(OPENSSLDIR)/include
181181
OPENSSLLIBDIR = $(OPENSSLDIR)
182182
183183
#### Either the directory where the Tcl library is installed or the Tcl
184184
# source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526526
$(SRCDIR)/printf.c \
527527
$(SRCDIR)/publish.c \
528528
$(SRCDIR)/purge.c \
529529
$(SRCDIR)/rebuild.c \
530530
$(SRCDIR)/regexp.c \
531
+ $(SRCDIR)/repolist.c \
531532
$(SRCDIR)/report.c \
532533
$(SRCDIR)/rss.c \
533534
$(SRCDIR)/schema.c \
534535
$(SRCDIR)/search.c \
535536
$(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736737
$(OBJDIR)/printf_.c \
737738
$(OBJDIR)/publish_.c \
738739
$(OBJDIR)/purge_.c \
739740
$(OBJDIR)/rebuild_.c \
740741
$(OBJDIR)/regexp_.c \
742
+ $(OBJDIR)/repolist_.c \
741743
$(OBJDIR)/report_.c \
742744
$(OBJDIR)/rss_.c \
743745
$(OBJDIR)/schema_.c \
744746
$(OBJDIR)/search_.c \
745747
$(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873875
$(OBJDIR)/printf.o \
874876
$(OBJDIR)/publish.o \
875877
$(OBJDIR)/purge.o \
876878
$(OBJDIR)/rebuild.o \
877879
$(OBJDIR)/regexp.o \
880
+ $(OBJDIR)/repolist.o \
878881
$(OBJDIR)/report.o \
879882
$(OBJDIR)/rss.o \
880883
$(OBJDIR)/schema.o \
881884
$(OBJDIR)/search.o \
882885
$(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
12291232
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
12301233
$(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
12311234
$(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
12321235
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
12331236
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237
+ $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
12341238
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
12351239
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
12361240
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
12371241
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
12381242
$(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
20022006
20032007
$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
20042008
$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
20052009
20062010
$(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
+
2012
+$(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013
+ $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
+
2015
+$(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016
+ $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
+
2018
+$(OBJDIR)/repolist.h: $(OBJDIR)/headers
20072019
20082020
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
20092021
$(TRANSLATE) $(SRCDIR)/report.c >$@
20102022
20112023
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
23822394
-DSQLITE_USE_ALLOCA \
23832395
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
23842396
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
23852397
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
23862398
-DSQLITE_ENABLE_FTS4 \
2387
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
23882399
-DSQLITE_ENABLE_DBSTAT_VTAB \
23892400
-DSQLITE_ENABLE_JSON1 \
23902401
-DSQLITE_ENABLE_FTS5 \
23912402
-DSQLITE_ENABLE_STMTVTAB \
23922403
-DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
24122423
-DSQLITE_USE_ALLOCA \
24132424
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
24142425
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
24152426
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
24162427
-DSQLITE_ENABLE_FTS4 \
2417
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
24182428
-DSQLITE_ENABLE_DBSTAT_VTAB \
24192429
-DSQLITE_ENABLE_JSON1 \
24202430
-DSQLITE_ENABLE_FTS5 \
24212431
-DSQLITE_ENABLE_STMTVTAB \
24222432
-DSQLITE_HAVE_ZLIB \
24232433
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
 
531 $(SRCDIR)/report.c \
532 $(SRCDIR)/rss.c \
533 $(SRCDIR)/schema.c \
534 $(SRCDIR)/search.c \
535 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736 $(OBJDIR)/printf_.c \
737 $(OBJDIR)/publish_.c \
738 $(OBJDIR)/purge_.c \
739 $(OBJDIR)/rebuild_.c \
740 $(OBJDIR)/regexp_.c \
 
741 $(OBJDIR)/report_.c \
742 $(OBJDIR)/rss_.c \
743 $(OBJDIR)/schema_.c \
744 $(OBJDIR)/search_.c \
745 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873 $(OBJDIR)/printf.o \
874 $(OBJDIR)/publish.o \
875 $(OBJDIR)/purge.o \
876 $(OBJDIR)/rebuild.o \
877 $(OBJDIR)/regexp.o \
 
878 $(OBJDIR)/report.o \
879 $(OBJDIR)/rss.o \
880 $(OBJDIR)/schema.o \
881 $(OBJDIR)/search.o \
882 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1229 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1230 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1231 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1232 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1233 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
 
1234 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1235 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1236 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1237 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1238 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2002
2003 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2004 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2005
2006 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
2007
2008 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2009 $(TRANSLATE) $(SRCDIR)/report.c >$@
2010
2011 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2382 -DSQLITE_USE_ALLOCA \
2383 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2384 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2385 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2386 -DSQLITE_ENABLE_FTS4 \
2387 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2388 -DSQLITE_ENABLE_DBSTAT_VTAB \
2389 -DSQLITE_ENABLE_JSON1 \
2390 -DSQLITE_ENABLE_FTS5 \
2391 -DSQLITE_ENABLE_STMTVTAB \
2392 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2412 -DSQLITE_USE_ALLOCA \
2413 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2414 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2415 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2416 -DSQLITE_ENABLE_FTS4 \
2417 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2418 -DSQLITE_ENABLE_DBSTAT_VTAB \
2419 -DSQLITE_ENABLE_JSON1 \
2420 -DSQLITE_ENABLE_FTS5 \
2421 -DSQLITE_ENABLE_STMTVTAB \
2422 -DSQLITE_HAVE_ZLIB \
2423
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
531 $(SRCDIR)/repolist.c \
532 $(SRCDIR)/report.c \
533 $(SRCDIR)/rss.c \
534 $(SRCDIR)/schema.c \
535 $(SRCDIR)/search.c \
536 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
737 $(OBJDIR)/printf_.c \
738 $(OBJDIR)/publish_.c \
739 $(OBJDIR)/purge_.c \
740 $(OBJDIR)/rebuild_.c \
741 $(OBJDIR)/regexp_.c \
742 $(OBJDIR)/repolist_.c \
743 $(OBJDIR)/report_.c \
744 $(OBJDIR)/rss_.c \
745 $(OBJDIR)/schema_.c \
746 $(OBJDIR)/search_.c \
747 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
875 $(OBJDIR)/printf.o \
876 $(OBJDIR)/publish.o \
877 $(OBJDIR)/purge.o \
878 $(OBJDIR)/rebuild.o \
879 $(OBJDIR)/regexp.o \
880 $(OBJDIR)/repolist.o \
881 $(OBJDIR)/report.o \
882 $(OBJDIR)/rss.o \
883 $(OBJDIR)/schema.o \
884 $(OBJDIR)/search.o \
885 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1232 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1233 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1234 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1235 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1236 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237 $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
1238 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1239 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1240 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1241 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1242 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2006
2007 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2008 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2009
2010 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
2012 $(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013 $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
2015 $(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016 $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
2018 $(OBJDIR)/repolist.h: $(OBJDIR)/headers
2019
2020 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2021 $(TRANSLATE) $(SRCDIR)/report.c >$@
2022
2023 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2394 -DSQLITE_USE_ALLOCA \
2395 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2396 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2397 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2398 -DSQLITE_ENABLE_FTS4 \
 
2399 -DSQLITE_ENABLE_DBSTAT_VTAB \
2400 -DSQLITE_ENABLE_JSON1 \
2401 -DSQLITE_ENABLE_FTS5 \
2402 -DSQLITE_ENABLE_STMTVTAB \
2403 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2423 -DSQLITE_USE_ALLOCA \
2424 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2425 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2426 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2427 -DSQLITE_ENABLE_FTS4 \
 
2428 -DSQLITE_ENABLE_DBSTAT_VTAB \
2429 -DSQLITE_ENABLE_JSON1 \
2430 -DSQLITE_ENABLE_FTS5 \
2431 -DSQLITE_ENABLE_STMTVTAB \
2432 -DSQLITE_HAVE_ZLIB \
2433
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -174,11 +174,11 @@
174174
#### The directories where the OpenSSL include and library files are located.
175175
# The recommended usage here is to use the Sysinternals junction tool
176176
# to create a hard link between an "openssl-1.x" sub-directory of the
177177
# Fossil source code directory and the target OpenSSL source directory.
178178
#
179
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
179
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180180
OPENSSLINCDIR = $(OPENSSLDIR)/include
181181
OPENSSLLIBDIR = $(OPENSSLDIR)
182182
183183
#### Either the directory where the Tcl library is installed or the Tcl
184184
# source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526526
$(SRCDIR)/printf.c \
527527
$(SRCDIR)/publish.c \
528528
$(SRCDIR)/purge.c \
529529
$(SRCDIR)/rebuild.c \
530530
$(SRCDIR)/regexp.c \
531
+ $(SRCDIR)/repolist.c \
531532
$(SRCDIR)/report.c \
532533
$(SRCDIR)/rss.c \
533534
$(SRCDIR)/schema.c \
534535
$(SRCDIR)/search.c \
535536
$(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736737
$(OBJDIR)/printf_.c \
737738
$(OBJDIR)/publish_.c \
738739
$(OBJDIR)/purge_.c \
739740
$(OBJDIR)/rebuild_.c \
740741
$(OBJDIR)/regexp_.c \
742
+ $(OBJDIR)/repolist_.c \
741743
$(OBJDIR)/report_.c \
742744
$(OBJDIR)/rss_.c \
743745
$(OBJDIR)/schema_.c \
744746
$(OBJDIR)/search_.c \
745747
$(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873875
$(OBJDIR)/printf.o \
874876
$(OBJDIR)/publish.o \
875877
$(OBJDIR)/purge.o \
876878
$(OBJDIR)/rebuild.o \
877879
$(OBJDIR)/regexp.o \
880
+ $(OBJDIR)/repolist.o \
878881
$(OBJDIR)/report.o \
879882
$(OBJDIR)/rss.o \
880883
$(OBJDIR)/schema.o \
881884
$(OBJDIR)/search.o \
882885
$(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
12291232
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
12301233
$(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
12311234
$(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
12321235
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
12331236
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237
+ $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
12341238
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
12351239
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
12361240
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
12371241
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
12381242
$(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
20022006
20032007
$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
20042008
$(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
20052009
20062010
$(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
+
2012
+$(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013
+ $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
+
2015
+$(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016
+ $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
+
2018
+$(OBJDIR)/repolist.h: $(OBJDIR)/headers
20072019
20082020
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
20092021
$(TRANSLATE) $(SRCDIR)/report.c >$@
20102022
20112023
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
23822394
-DSQLITE_USE_ALLOCA \
23832395
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
23842396
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
23852397
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
23862398
-DSQLITE_ENABLE_FTS4 \
2387
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
23882399
-DSQLITE_ENABLE_DBSTAT_VTAB \
23892400
-DSQLITE_ENABLE_JSON1 \
23902401
-DSQLITE_ENABLE_FTS5 \
23912402
-DSQLITE_ENABLE_STMTVTAB \
23922403
-DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
24122423
-DSQLITE_USE_ALLOCA \
24132424
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
24142425
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
24152426
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
24162427
-DSQLITE_ENABLE_FTS4 \
2417
- -DSQLITE_ENABLE_FTS3_PARENTHESIS \
24182428
-DSQLITE_ENABLE_DBSTAT_VTAB \
24192429
-DSQLITE_ENABLE_JSON1 \
24202430
-DSQLITE_ENABLE_FTS5 \
24212431
-DSQLITE_ENABLE_STMTVTAB \
24222432
-DSQLITE_HAVE_ZLIB \
24232433
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
 
531 $(SRCDIR)/report.c \
532 $(SRCDIR)/rss.c \
533 $(SRCDIR)/schema.c \
534 $(SRCDIR)/search.c \
535 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
736 $(OBJDIR)/printf_.c \
737 $(OBJDIR)/publish_.c \
738 $(OBJDIR)/purge_.c \
739 $(OBJDIR)/rebuild_.c \
740 $(OBJDIR)/regexp_.c \
 
741 $(OBJDIR)/report_.c \
742 $(OBJDIR)/rss_.c \
743 $(OBJDIR)/schema_.c \
744 $(OBJDIR)/search_.c \
745 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
873 $(OBJDIR)/printf.o \
874 $(OBJDIR)/publish.o \
875 $(OBJDIR)/purge.o \
876 $(OBJDIR)/rebuild.o \
877 $(OBJDIR)/regexp.o \
 
878 $(OBJDIR)/report.o \
879 $(OBJDIR)/rss.o \
880 $(OBJDIR)/schema.o \
881 $(OBJDIR)/search.o \
882 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1229 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1230 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1231 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1232 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1233 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
 
1234 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1235 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1236 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1237 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1238 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2002
2003 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2004 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2005
2006 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
2007
2008 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2009 $(TRANSLATE) $(SRCDIR)/report.c >$@
2010
2011 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2382 -DSQLITE_USE_ALLOCA \
2383 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2384 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2385 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2386 -DSQLITE_ENABLE_FTS4 \
2387 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2388 -DSQLITE_ENABLE_DBSTAT_VTAB \
2389 -DSQLITE_ENABLE_JSON1 \
2390 -DSQLITE_ENABLE_FTS5 \
2391 -DSQLITE_ENABLE_STMTVTAB \
2392 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2412 -DSQLITE_USE_ALLOCA \
2413 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2414 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2415 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2416 -DSQLITE_ENABLE_FTS4 \
2417 -DSQLITE_ENABLE_FTS3_PARENTHESIS \
2418 -DSQLITE_ENABLE_DBSTAT_VTAB \
2419 -DSQLITE_ENABLE_JSON1 \
2420 -DSQLITE_ENABLE_FTS5 \
2421 -DSQLITE_ENABLE_STMTVTAB \
2422 -DSQLITE_HAVE_ZLIB \
2423
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1a
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -526,10 +526,11 @@
526 $(SRCDIR)/printf.c \
527 $(SRCDIR)/publish.c \
528 $(SRCDIR)/purge.c \
529 $(SRCDIR)/rebuild.c \
530 $(SRCDIR)/regexp.c \
531 $(SRCDIR)/repolist.c \
532 $(SRCDIR)/report.c \
533 $(SRCDIR)/rss.c \
534 $(SRCDIR)/schema.c \
535 $(SRCDIR)/search.c \
536 $(SRCDIR)/security_audit.c \
@@ -736,10 +737,11 @@
737 $(OBJDIR)/printf_.c \
738 $(OBJDIR)/publish_.c \
739 $(OBJDIR)/purge_.c \
740 $(OBJDIR)/rebuild_.c \
741 $(OBJDIR)/regexp_.c \
742 $(OBJDIR)/repolist_.c \
743 $(OBJDIR)/report_.c \
744 $(OBJDIR)/rss_.c \
745 $(OBJDIR)/schema_.c \
746 $(OBJDIR)/search_.c \
747 $(OBJDIR)/security_audit_.c \
@@ -873,10 +875,11 @@
875 $(OBJDIR)/printf.o \
876 $(OBJDIR)/publish.o \
877 $(OBJDIR)/purge.o \
878 $(OBJDIR)/rebuild.o \
879 $(OBJDIR)/regexp.o \
880 $(OBJDIR)/repolist.o \
881 $(OBJDIR)/report.o \
882 $(OBJDIR)/rss.o \
883 $(OBJDIR)/schema.o \
884 $(OBJDIR)/search.o \
885 $(OBJDIR)/security_audit.o \
@@ -1229,10 +1232,11 @@
1232 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
1233 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
1234 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1235 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1236 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1237 $(OBJDIR)/repolist_.c:$(OBJDIR)/repolist.h \
1238 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1239 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1240 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1241 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1242 $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \
@@ -2002,10 +2006,18 @@
2006
2007 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
2008 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
2009
2010 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
2011
2012 $(OBJDIR)/repolist_.c: $(SRCDIR)/repolist.c $(TRANSLATE)
2013 $(TRANSLATE) $(SRCDIR)/repolist.c >$@
2014
2015 $(OBJDIR)/repolist.o: $(OBJDIR)/repolist_.c $(OBJDIR)/repolist.h $(SRCDIR)/config.h
2016 $(XTCC) -o $(OBJDIR)/repolist.o -c $(OBJDIR)/repolist_.c
2017
2018 $(OBJDIR)/repolist.h: $(OBJDIR)/headers
2019
2020 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(TRANSLATE)
2021 $(TRANSLATE) $(SRCDIR)/report.c >$@
2022
2023 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -2382,11 +2394,10 @@
2394 -DSQLITE_USE_ALLOCA \
2395 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2396 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2397 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2398 -DSQLITE_ENABLE_FTS4 \
 
2399 -DSQLITE_ENABLE_DBSTAT_VTAB \
2400 -DSQLITE_ENABLE_JSON1 \
2401 -DSQLITE_ENABLE_FTS5 \
2402 -DSQLITE_ENABLE_STMTVTAB \
2403 -DSQLITE_HAVE_ZLIB \
@@ -2412,11 +2423,10 @@
2423 -DSQLITE_USE_ALLOCA \
2424 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2425 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2426 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2427 -DSQLITE_ENABLE_FTS4 \
 
2428 -DSQLITE_ENABLE_DBSTAT_VTAB \
2429 -DSQLITE_ENABLE_JSON1 \
2430 -DSQLITE_ENABLE_FTS5 \
2431 -DSQLITE_ENABLE_STMTVTAB \
2432 -DSQLITE_HAVE_ZLIB \
2433
+15 -3
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,11 +98,11 @@
9898
!ifndef USE_SEE
9999
USE_SEE = 0
100100
!endif
101101
102102
!if $(FOSSIL_ENABLE_SSL)!=0
103
-SSLDIR = $(B)\compat\openssl-1.1.1
103
+SSLDIR = $(B)\compat\openssl-1.1.1a
104104
SSLINCDIR = $(SSLDIR)\include
105105
!if $(FOSSIL_DYNAMIC_BUILD)!=0
106106
SSLLIBDIR = $(SSLDIR)
107107
!else
108108
SSLLIBDIR = $(SSLDIR)
@@ -292,11 +292,10 @@
292292
/DSQLITE_USE_ALLOCA \
293293
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
294294
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
295295
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
296296
/DSQLITE_ENABLE_FTS4 \
297
- /DSQLITE_ENABLE_FTS3_PARENTHESIS \
298297
/DSQLITE_ENABLE_DBSTAT_VTAB \
299298
/DSQLITE_ENABLE_JSON1 \
300299
/DSQLITE_ENABLE_FTS5 \
301300
/DSQLITE_ENABLE_STMTVTAB \
302301
/DSQLITE_HAVE_ZLIB \
@@ -319,11 +318,10 @@
319318
/DSQLITE_USE_ALLOCA \
320319
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
321320
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
322321
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
323322
/DSQLITE_ENABLE_FTS4 \
324
- /DSQLITE_ENABLE_FTS3_PARENTHESIS \
325323
/DSQLITE_ENABLE_DBSTAT_VTAB \
326324
/DSQLITE_ENABLE_JSON1 \
327325
/DSQLITE_ENABLE_FTS5 \
328326
/DSQLITE_ENABLE_STMTVTAB \
329327
/DSQLITE_HAVE_ZLIB \
@@ -432,10 +430,11 @@
432430
printf_.c \
433431
publish_.c \
434432
purge_.c \
435433
rebuild_.c \
436434
regexp_.c \
435
+ repolist_.c \
437436
report_.c \
438437
rss_.c \
439438
schema_.c \
440439
search_.c \
441440
security_audit_.c \
@@ -641,10 +640,11 @@
641640
$(OX)\printf$O \
642641
$(OX)\publish$O \
643642
$(OX)\purge$O \
644643
$(OX)\rebuild$O \
645644
$(OX)\regexp$O \
645
+ $(OX)\repolist$O \
646646
$(OX)\report$O \
647647
$(OX)\rss$O \
648648
$(OX)\schema$O \
649649
$(OX)\search$O \
650650
$(OX)\security_audit$O \
@@ -718,11 +718,15 @@
718718
@echo Building OpenSSL from "$(SSLDIR)"...
719719
!if "$(PERLDIR)" != ""
720720
@set PATH=$(PERLDIR);$(PATH)
721721
!endif
722722
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
723
+!if $(FOSSIL_ENABLE_WINXP)!=0
724
+ @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
725
+!else
723726
@pushd "$(SSLDIR)" && $(MAKE) && popd
727
+!endif
724728
!endif
725729
726730
!if $(FOSSIL_ENABLE_MINIZ)==0
727731
!if $(FOSSIL_BUILD_ZLIB)!=0
728732
APPTARGETS = $(APPTARGETS) zlib
@@ -832,10 +836,11 @@
832836
echo $(OX)\printf.obj >> $@
833837
echo $(OX)\publish.obj >> $@
834838
echo $(OX)\purge.obj >> $@
835839
echo $(OX)\rebuild.obj >> $@
836840
echo $(OX)\regexp.obj >> $@
841
+ echo $(OX)\repolist.obj >> $@
837842
echo $(OX)\report.obj >> $@
838843
echo $(OX)\rss.obj >> $@
839844
echo $(OX)\schema.obj >> $@
840845
echo $(OX)\search.obj >> $@
841846
echo $(OX)\security_audit.obj >> $@
@@ -1539,10 +1544,16 @@
15391544
$(OX)\regexp$O : regexp_.c regexp.h
15401545
$(TCC) /Fo$@ -c regexp_.c
15411546
15421547
regexp_.c : $(SRCDIR)\regexp.c
15431548
translate$E $** > $@
1549
+
1550
+$(OX)\repolist$O : repolist_.c repolist.h
1551
+ $(TCC) /Fo$@ -c repolist_.c
1552
+
1553
+repolist_.c : $(SRCDIR)\repolist.c
1554
+ translate$E $** > $@
15441555
15451556
$(OX)\report$O : report_.c report.h
15461557
$(TCC) /Fo$@ -c report_.c
15471558
15481559
report_.c : $(SRCDIR)\report.c
@@ -1904,10 +1915,11 @@
19041915
printf_.c:printf.h \
19051916
publish_.c:publish.h \
19061917
purge_.c:purge.h \
19071918
rebuild_.c:rebuild.h \
19081919
regexp_.c:regexp.h \
1920
+ repolist_.c:repolist.h \
19091921
report_.c:report.h \
19101922
rss_.c:rss.h \
19111923
schema_.c:schema.h \
19121924
search_.c:search.h \
19131925
security_audit_.c:security_audit.h \
19141926
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,11 +98,11 @@
98 !ifndef USE_SEE
99 USE_SEE = 0
100 !endif
101
102 !if $(FOSSIL_ENABLE_SSL)!=0
103 SSLDIR = $(B)\compat\openssl-1.1.1
104 SSLINCDIR = $(SSLDIR)\include
105 !if $(FOSSIL_DYNAMIC_BUILD)!=0
106 SSLLIBDIR = $(SSLDIR)
107 !else
108 SSLLIBDIR = $(SSLDIR)
@@ -292,11 +292,10 @@
292 /DSQLITE_USE_ALLOCA \
293 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
294 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
295 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
296 /DSQLITE_ENABLE_FTS4 \
297 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
298 /DSQLITE_ENABLE_DBSTAT_VTAB \
299 /DSQLITE_ENABLE_JSON1 \
300 /DSQLITE_ENABLE_FTS5 \
301 /DSQLITE_ENABLE_STMTVTAB \
302 /DSQLITE_HAVE_ZLIB \
@@ -319,11 +318,10 @@
319 /DSQLITE_USE_ALLOCA \
320 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
321 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
322 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
323 /DSQLITE_ENABLE_FTS4 \
324 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
325 /DSQLITE_ENABLE_DBSTAT_VTAB \
326 /DSQLITE_ENABLE_JSON1 \
327 /DSQLITE_ENABLE_FTS5 \
328 /DSQLITE_ENABLE_STMTVTAB \
329 /DSQLITE_HAVE_ZLIB \
@@ -432,10 +430,11 @@
432 printf_.c \
433 publish_.c \
434 purge_.c \
435 rebuild_.c \
436 regexp_.c \
 
437 report_.c \
438 rss_.c \
439 schema_.c \
440 search_.c \
441 security_audit_.c \
@@ -641,10 +640,11 @@
641 $(OX)\printf$O \
642 $(OX)\publish$O \
643 $(OX)\purge$O \
644 $(OX)\rebuild$O \
645 $(OX)\regexp$O \
 
646 $(OX)\report$O \
647 $(OX)\rss$O \
648 $(OX)\schema$O \
649 $(OX)\search$O \
650 $(OX)\security_audit$O \
@@ -718,11 +718,15 @@
718 @echo Building OpenSSL from "$(SSLDIR)"...
719 !if "$(PERLDIR)" != ""
720 @set PATH=$(PERLDIR);$(PATH)
721 !endif
722 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
 
 
 
723 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
724 !endif
725
726 !if $(FOSSIL_ENABLE_MINIZ)==0
727 !if $(FOSSIL_BUILD_ZLIB)!=0
728 APPTARGETS = $(APPTARGETS) zlib
@@ -832,10 +836,11 @@
832 echo $(OX)\printf.obj >> $@
833 echo $(OX)\publish.obj >> $@
834 echo $(OX)\purge.obj >> $@
835 echo $(OX)\rebuild.obj >> $@
836 echo $(OX)\regexp.obj >> $@
 
837 echo $(OX)\report.obj >> $@
838 echo $(OX)\rss.obj >> $@
839 echo $(OX)\schema.obj >> $@
840 echo $(OX)\search.obj >> $@
841 echo $(OX)\security_audit.obj >> $@
@@ -1539,10 +1544,16 @@
1539 $(OX)\regexp$O : regexp_.c regexp.h
1540 $(TCC) /Fo$@ -c regexp_.c
1541
1542 regexp_.c : $(SRCDIR)\regexp.c
1543 translate$E $** > $@
 
 
 
 
 
 
1544
1545 $(OX)\report$O : report_.c report.h
1546 $(TCC) /Fo$@ -c report_.c
1547
1548 report_.c : $(SRCDIR)\report.c
@@ -1904,10 +1915,11 @@
1904 printf_.c:printf.h \
1905 publish_.c:publish.h \
1906 purge_.c:purge.h \
1907 rebuild_.c:rebuild.h \
1908 regexp_.c:regexp.h \
 
1909 report_.c:report.h \
1910 rss_.c:rss.h \
1911 schema_.c:schema.h \
1912 search_.c:search.h \
1913 security_audit_.c:security_audit.h \
1914
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,11 +98,11 @@
98 !ifndef USE_SEE
99 USE_SEE = 0
100 !endif
101
102 !if $(FOSSIL_ENABLE_SSL)!=0
103 SSLDIR = $(B)\compat\openssl-1.1.1a
104 SSLINCDIR = $(SSLDIR)\include
105 !if $(FOSSIL_DYNAMIC_BUILD)!=0
106 SSLLIBDIR = $(SSLDIR)
107 !else
108 SSLLIBDIR = $(SSLDIR)
@@ -292,11 +292,10 @@
292 /DSQLITE_USE_ALLOCA \
293 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
294 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
295 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
296 /DSQLITE_ENABLE_FTS4 \
 
297 /DSQLITE_ENABLE_DBSTAT_VTAB \
298 /DSQLITE_ENABLE_JSON1 \
299 /DSQLITE_ENABLE_FTS5 \
300 /DSQLITE_ENABLE_STMTVTAB \
301 /DSQLITE_HAVE_ZLIB \
@@ -319,11 +318,10 @@
318 /DSQLITE_USE_ALLOCA \
319 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
320 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
321 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
322 /DSQLITE_ENABLE_FTS4 \
 
323 /DSQLITE_ENABLE_DBSTAT_VTAB \
324 /DSQLITE_ENABLE_JSON1 \
325 /DSQLITE_ENABLE_FTS5 \
326 /DSQLITE_ENABLE_STMTVTAB \
327 /DSQLITE_HAVE_ZLIB \
@@ -432,10 +430,11 @@
430 printf_.c \
431 publish_.c \
432 purge_.c \
433 rebuild_.c \
434 regexp_.c \
435 repolist_.c \
436 report_.c \
437 rss_.c \
438 schema_.c \
439 search_.c \
440 security_audit_.c \
@@ -641,10 +640,11 @@
640 $(OX)\printf$O \
641 $(OX)\publish$O \
642 $(OX)\purge$O \
643 $(OX)\rebuild$O \
644 $(OX)\regexp$O \
645 $(OX)\repolist$O \
646 $(OX)\report$O \
647 $(OX)\rss$O \
648 $(OX)\schema$O \
649 $(OX)\search$O \
650 $(OX)\security_audit$O \
@@ -718,11 +718,15 @@
718 @echo Building OpenSSL from "$(SSLDIR)"...
719 !if "$(PERLDIR)" != ""
720 @set PATH=$(PERLDIR);$(PATH)
721 !endif
722 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
723 !if $(FOSSIL_ENABLE_WINXP)!=0
724 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
725 !else
726 @pushd "$(SSLDIR)" && $(MAKE) && popd
727 !endif
728 !endif
729
730 !if $(FOSSIL_ENABLE_MINIZ)==0
731 !if $(FOSSIL_BUILD_ZLIB)!=0
732 APPTARGETS = $(APPTARGETS) zlib
@@ -832,10 +836,11 @@
836 echo $(OX)\printf.obj >> $@
837 echo $(OX)\publish.obj >> $@
838 echo $(OX)\purge.obj >> $@
839 echo $(OX)\rebuild.obj >> $@
840 echo $(OX)\regexp.obj >> $@
841 echo $(OX)\repolist.obj >> $@
842 echo $(OX)\report.obj >> $@
843 echo $(OX)\rss.obj >> $@
844 echo $(OX)\schema.obj >> $@
845 echo $(OX)\search.obj >> $@
846 echo $(OX)\security_audit.obj >> $@
@@ -1539,10 +1544,16 @@
1544 $(OX)\regexp$O : regexp_.c regexp.h
1545 $(TCC) /Fo$@ -c regexp_.c
1546
1547 regexp_.c : $(SRCDIR)\regexp.c
1548 translate$E $** > $@
1549
1550 $(OX)\repolist$O : repolist_.c repolist.h
1551 $(TCC) /Fo$@ -c repolist_.c
1552
1553 repolist_.c : $(SRCDIR)\repolist.c
1554 translate$E $** > $@
1555
1556 $(OX)\report$O : report_.c report.h
1557 $(TCC) /Fo$@ -c report_.c
1558
1559 report_.c : $(SRCDIR)\report.c
@@ -1904,10 +1915,11 @@
1915 printf_.c:printf.h \
1916 publish_.c:publish.h \
1917 purge_.c:purge.h \
1918 rebuild_.c:rebuild.h \
1919 regexp_.c:regexp.h \
1920 repolist_.c:repolist.h \
1921 report_.c:report.h \
1922 rss_.c:rss.h \
1923 schema_.c:schema.h \
1924 search_.c:search.h \
1925 security_audit_.c:security_audit.h \
1926
+15 -3
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,11 +98,11 @@
9898
!ifndef USE_SEE
9999
USE_SEE = 0
100100
!endif
101101
102102
!if $(FOSSIL_ENABLE_SSL)!=0
103
-SSLDIR = $(B)\compat\openssl-1.1.1
103
+SSLDIR = $(B)\compat\openssl-1.1.1a
104104
SSLINCDIR = $(SSLDIR)\include
105105
!if $(FOSSIL_DYNAMIC_BUILD)!=0
106106
SSLLIBDIR = $(SSLDIR)
107107
!else
108108
SSLLIBDIR = $(SSLDIR)
@@ -292,11 +292,10 @@
292292
/DSQLITE_USE_ALLOCA \
293293
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
294294
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
295295
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
296296
/DSQLITE_ENABLE_FTS4 \
297
- /DSQLITE_ENABLE_FTS3_PARENTHESIS \
298297
/DSQLITE_ENABLE_DBSTAT_VTAB \
299298
/DSQLITE_ENABLE_JSON1 \
300299
/DSQLITE_ENABLE_FTS5 \
301300
/DSQLITE_ENABLE_STMTVTAB \
302301
/DSQLITE_HAVE_ZLIB \
@@ -319,11 +318,10 @@
319318
/DSQLITE_USE_ALLOCA \
320319
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
321320
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
322321
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
323322
/DSQLITE_ENABLE_FTS4 \
324
- /DSQLITE_ENABLE_FTS3_PARENTHESIS \
325323
/DSQLITE_ENABLE_DBSTAT_VTAB \
326324
/DSQLITE_ENABLE_JSON1 \
327325
/DSQLITE_ENABLE_FTS5 \
328326
/DSQLITE_ENABLE_STMTVTAB \
329327
/DSQLITE_HAVE_ZLIB \
@@ -432,10 +430,11 @@
432430
printf_.c \
433431
publish_.c \
434432
purge_.c \
435433
rebuild_.c \
436434
regexp_.c \
435
+ repolist_.c \
437436
report_.c \
438437
rss_.c \
439438
schema_.c \
440439
search_.c \
441440
security_audit_.c \
@@ -641,10 +640,11 @@
641640
$(OX)\printf$O \
642641
$(OX)\publish$O \
643642
$(OX)\purge$O \
644643
$(OX)\rebuild$O \
645644
$(OX)\regexp$O \
645
+ $(OX)\repolist$O \
646646
$(OX)\report$O \
647647
$(OX)\rss$O \
648648
$(OX)\schema$O \
649649
$(OX)\search$O \
650650
$(OX)\security_audit$O \
@@ -718,11 +718,15 @@
718718
@echo Building OpenSSL from "$(SSLDIR)"...
719719
!if "$(PERLDIR)" != ""
720720
@set PATH=$(PERLDIR);$(PATH)
721721
!endif
722722
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
723
+!if $(FOSSIL_ENABLE_WINXP)!=0
724
+ @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
725
+!else
723726
@pushd "$(SSLDIR)" && $(MAKE) && popd
727
+!endif
724728
!endif
725729
726730
!if $(FOSSIL_ENABLE_MINIZ)==0
727731
!if $(FOSSIL_BUILD_ZLIB)!=0
728732
APPTARGETS = $(APPTARGETS) zlib
@@ -832,10 +836,11 @@
832836
echo $(OX)\printf.obj >> $@
833837
echo $(OX)\publish.obj >> $@
834838
echo $(OX)\purge.obj >> $@
835839
echo $(OX)\rebuild.obj >> $@
836840
echo $(OX)\regexp.obj >> $@
841
+ echo $(OX)\repolist.obj >> $@
837842
echo $(OX)\report.obj >> $@
838843
echo $(OX)\rss.obj >> $@
839844
echo $(OX)\schema.obj >> $@
840845
echo $(OX)\search.obj >> $@
841846
echo $(OX)\security_audit.obj >> $@
@@ -1539,10 +1544,16 @@
15391544
$(OX)\regexp$O : regexp_.c regexp.h
15401545
$(TCC) /Fo$@ -c regexp_.c
15411546
15421547
regexp_.c : $(SRCDIR)\regexp.c
15431548
translate$E $** > $@
1549
+
1550
+$(OX)\repolist$O : repolist_.c repolist.h
1551
+ $(TCC) /Fo$@ -c repolist_.c
1552
+
1553
+repolist_.c : $(SRCDIR)\repolist.c
1554
+ translate$E $** > $@
15441555
15451556
$(OX)\report$O : report_.c report.h
15461557
$(TCC) /Fo$@ -c report_.c
15471558
15481559
report_.c : $(SRCDIR)\report.c
@@ -1904,10 +1915,11 @@
19041915
printf_.c:printf.h \
19051916
publish_.c:publish.h \
19061917
purge_.c:purge.h \
19071918
rebuild_.c:rebuild.h \
19081919
regexp_.c:regexp.h \
1920
+ repolist_.c:repolist.h \
19091921
report_.c:report.h \
19101922
rss_.c:rss.h \
19111923
schema_.c:schema.h \
19121924
search_.c:search.h \
19131925
security_audit_.c:security_audit.h \
19141926
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,11 +98,11 @@
98 !ifndef USE_SEE
99 USE_SEE = 0
100 !endif
101
102 !if $(FOSSIL_ENABLE_SSL)!=0
103 SSLDIR = $(B)\compat\openssl-1.1.1
104 SSLINCDIR = $(SSLDIR)\include
105 !if $(FOSSIL_DYNAMIC_BUILD)!=0
106 SSLLIBDIR = $(SSLDIR)
107 !else
108 SSLLIBDIR = $(SSLDIR)
@@ -292,11 +292,10 @@
292 /DSQLITE_USE_ALLOCA \
293 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
294 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
295 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
296 /DSQLITE_ENABLE_FTS4 \
297 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
298 /DSQLITE_ENABLE_DBSTAT_VTAB \
299 /DSQLITE_ENABLE_JSON1 \
300 /DSQLITE_ENABLE_FTS5 \
301 /DSQLITE_ENABLE_STMTVTAB \
302 /DSQLITE_HAVE_ZLIB \
@@ -319,11 +318,10 @@
319 /DSQLITE_USE_ALLOCA \
320 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
321 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
322 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
323 /DSQLITE_ENABLE_FTS4 \
324 /DSQLITE_ENABLE_FTS3_PARENTHESIS \
325 /DSQLITE_ENABLE_DBSTAT_VTAB \
326 /DSQLITE_ENABLE_JSON1 \
327 /DSQLITE_ENABLE_FTS5 \
328 /DSQLITE_ENABLE_STMTVTAB \
329 /DSQLITE_HAVE_ZLIB \
@@ -432,10 +430,11 @@
432 printf_.c \
433 publish_.c \
434 purge_.c \
435 rebuild_.c \
436 regexp_.c \
 
437 report_.c \
438 rss_.c \
439 schema_.c \
440 search_.c \
441 security_audit_.c \
@@ -641,10 +640,11 @@
641 $(OX)\printf$O \
642 $(OX)\publish$O \
643 $(OX)\purge$O \
644 $(OX)\rebuild$O \
645 $(OX)\regexp$O \
 
646 $(OX)\report$O \
647 $(OX)\rss$O \
648 $(OX)\schema$O \
649 $(OX)\search$O \
650 $(OX)\security_audit$O \
@@ -718,11 +718,15 @@
718 @echo Building OpenSSL from "$(SSLDIR)"...
719 !if "$(PERLDIR)" != ""
720 @set PATH=$(PERLDIR);$(PATH)
721 !endif
722 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
 
 
 
723 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
724 !endif
725
726 !if $(FOSSIL_ENABLE_MINIZ)==0
727 !if $(FOSSIL_BUILD_ZLIB)!=0
728 APPTARGETS = $(APPTARGETS) zlib
@@ -832,10 +836,11 @@
832 echo $(OX)\printf.obj >> $@
833 echo $(OX)\publish.obj >> $@
834 echo $(OX)\purge.obj >> $@
835 echo $(OX)\rebuild.obj >> $@
836 echo $(OX)\regexp.obj >> $@
 
837 echo $(OX)\report.obj >> $@
838 echo $(OX)\rss.obj >> $@
839 echo $(OX)\schema.obj >> $@
840 echo $(OX)\search.obj >> $@
841 echo $(OX)\security_audit.obj >> $@
@@ -1539,10 +1544,16 @@
1539 $(OX)\regexp$O : regexp_.c regexp.h
1540 $(TCC) /Fo$@ -c regexp_.c
1541
1542 regexp_.c : $(SRCDIR)\regexp.c
1543 translate$E $** > $@
 
 
 
 
 
 
1544
1545 $(OX)\report$O : report_.c report.h
1546 $(TCC) /Fo$@ -c report_.c
1547
1548 report_.c : $(SRCDIR)\report.c
@@ -1904,10 +1915,11 @@
1904 printf_.c:printf.h \
1905 publish_.c:publish.h \
1906 purge_.c:purge.h \
1907 rebuild_.c:rebuild.h \
1908 regexp_.c:regexp.h \
 
1909 report_.c:report.h \
1910 rss_.c:rss.h \
1911 schema_.c:schema.h \
1912 search_.c:search.h \
1913 security_audit_.c:security_audit.h \
1914
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,11 +98,11 @@
98 !ifndef USE_SEE
99 USE_SEE = 0
100 !endif
101
102 !if $(FOSSIL_ENABLE_SSL)!=0
103 SSLDIR = $(B)\compat\openssl-1.1.1a
104 SSLINCDIR = $(SSLDIR)\include
105 !if $(FOSSIL_DYNAMIC_BUILD)!=0
106 SSLLIBDIR = $(SSLDIR)
107 !else
108 SSLLIBDIR = $(SSLDIR)
@@ -292,11 +292,10 @@
292 /DSQLITE_USE_ALLOCA \
293 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
294 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
295 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
296 /DSQLITE_ENABLE_FTS4 \
 
297 /DSQLITE_ENABLE_DBSTAT_VTAB \
298 /DSQLITE_ENABLE_JSON1 \
299 /DSQLITE_ENABLE_FTS5 \
300 /DSQLITE_ENABLE_STMTVTAB \
301 /DSQLITE_HAVE_ZLIB \
@@ -319,11 +318,10 @@
318 /DSQLITE_USE_ALLOCA \
319 /DSQLITE_ENABLE_LOCKING_STYLE=0 \
320 /DSQLITE_DEFAULT_FILE_FORMAT=4 \
321 /DSQLITE_ENABLE_EXPLAIN_COMMENTS \
322 /DSQLITE_ENABLE_FTS4 \
 
323 /DSQLITE_ENABLE_DBSTAT_VTAB \
324 /DSQLITE_ENABLE_JSON1 \
325 /DSQLITE_ENABLE_FTS5 \
326 /DSQLITE_ENABLE_STMTVTAB \
327 /DSQLITE_HAVE_ZLIB \
@@ -432,10 +430,11 @@
430 printf_.c \
431 publish_.c \
432 purge_.c \
433 rebuild_.c \
434 regexp_.c \
435 repolist_.c \
436 report_.c \
437 rss_.c \
438 schema_.c \
439 search_.c \
440 security_audit_.c \
@@ -641,10 +640,11 @@
640 $(OX)\printf$O \
641 $(OX)\publish$O \
642 $(OX)\purge$O \
643 $(OX)\rebuild$O \
644 $(OX)\regexp$O \
645 $(OX)\repolist$O \
646 $(OX)\report$O \
647 $(OX)\rss$O \
648 $(OX)\schema$O \
649 $(OX)\search$O \
650 $(OX)\security_audit$O \
@@ -718,11 +718,15 @@
718 @echo Building OpenSSL from "$(SSLDIR)"...
719 !if "$(PERLDIR)" != ""
720 @set PATH=$(PERLDIR);$(PATH)
721 !endif
722 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
723 !if $(FOSSIL_ENABLE_WINXP)!=0
724 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
725 !else
726 @pushd "$(SSLDIR)" && $(MAKE) && popd
727 !endif
728 !endif
729
730 !if $(FOSSIL_ENABLE_MINIZ)==0
731 !if $(FOSSIL_BUILD_ZLIB)!=0
732 APPTARGETS = $(APPTARGETS) zlib
@@ -832,10 +836,11 @@
836 echo $(OX)\printf.obj >> $@
837 echo $(OX)\publish.obj >> $@
838 echo $(OX)\purge.obj >> $@
839 echo $(OX)\rebuild.obj >> $@
840 echo $(OX)\regexp.obj >> $@
841 echo $(OX)\repolist.obj >> $@
842 echo $(OX)\report.obj >> $@
843 echo $(OX)\rss.obj >> $@
844 echo $(OX)\schema.obj >> $@
845 echo $(OX)\search.obj >> $@
846 echo $(OX)\security_audit.obj >> $@
@@ -1539,10 +1544,16 @@
1544 $(OX)\regexp$O : regexp_.c regexp.h
1545 $(TCC) /Fo$@ -c regexp_.c
1546
1547 regexp_.c : $(SRCDIR)\regexp.c
1548 translate$E $** > $@
1549
1550 $(OX)\repolist$O : repolist_.c repolist.h
1551 $(TCC) /Fo$@ -c repolist_.c
1552
1553 repolist_.c : $(SRCDIR)\repolist.c
1554 translate$E $** > $@
1555
1556 $(OX)\report$O : report_.c report.h
1557 $(TCC) /Fo$@ -c report_.c
1558
1559 report_.c : $(SRCDIR)\report.c
@@ -1904,10 +1915,11 @@
1915 printf_.c:printf.h \
1916 publish_.c:publish.h \
1917 purge_.c:purge.h \
1918 rebuild_.c:rebuild.h \
1919 regexp_.c:regexp.h \
1920 repolist_.c:repolist.h \
1921 report_.c:report.h \
1922 rss_.c:rss.h \
1923 schema_.c:schema.h \
1924 search_.c:search.h \
1925 security_audit_.c:security_audit.h \
1926
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -1,43 +1,10 @@
1
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
3
- xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
4
- <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="fossil"
5
- type="win32" />
6
- <description>
7
- Simple, high-reliability, distributed software configuration management system.
8
- </description>
9
- <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
10
- <security>
11
- <requestedPrivileges>
12
- <requestedExecutionLevel level="asInvoker" uiAccess="false" />
13
- </requestedPrivileges>
14
- </security>
15
- </trustInfo>
16
- <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
17
- <application>
18
- <!-- Windows 10 -->
19
- <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
20
- <!-- Windows 8.1 -->
21
- <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
22
- <!-- Windows 8 -->
23
- <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
24
- <!-- Windows 7 -->
25
- <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
26
- <!-- Windows Vista -->
27
- <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
28
- </application>
29
- </compatibility>
30
- <asmv3:application>
31
- <asmv3:windowsSettings
32
- xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
33
- <dpiAware>true</dpiAware>
34
- </asmv3:windowsSettings>
35
- </asmv3:application>
36
- <dependency>
37
- <dependentAssembly>
38
- <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls"
39
- version="6.0.0.0" processorArchitecture="X86"
40
- publicKeyToken="6595b64144ccf1df" language="*" />
41
- </dependentAssembly>
42
- </dependency>
43
-</assembly>
1
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
2
+<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
3
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
4
+ <security>
5
+ <requestedPrivileges>
6
+ <requestedExecutionLevel level='asInvoker' uiAccess='false' />
7
+ </requestedPrivileges>
8
+ </security>
9
+ </trustInfo>
10
+</assembly>
4411
4512
ADDED www/admin-v-setup.md
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -1,43 +1,10 @@
1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
3 xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
4 <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="fossil"
5 type="win32" />
6 <description>
7 Simple, high-reliability, distributed software configuration management system.
8 </description>
9 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
10 <security>
11 <requestedPrivileges>
12 <requestedExecutionLevel level="asInvoker" uiAccess="false" />
13 </requestedPrivileges>
14 </security>
15 </trustInfo>
16 <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
17 <application>
18 <!-- Windows 10 -->
19 <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
20 <!-- Windows 8.1 -->
21 <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
22 <!-- Windows 8 -->
23 <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
24 <!-- Windows 7 -->
25 <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
26 <!-- Windows Vista -->
27 <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
28 </application>
29 </compatibility>
30 <asmv3:application>
31 <asmv3:windowsSettings
32 xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
33 <dpiAware>true</dpiAware>
34 </asmv3:windowsSettings>
35 </asmv3:application>
36 <dependency>
37 <dependentAssembly>
38 <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls"
39 version="6.0.0.0" processorArchitecture="X86"
40 publicKeyToken="6595b64144ccf1df" language="*" />
41 </dependentAssembly>
42 </dependency>
43 </assembly>
44
45 DDED www/admin-v-setup.md
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -1,43 +1,10 @@
1 <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
2 <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
3 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
4 <security>
5 <requestedPrivileges>
6 <requestedExecutionLevel level='asInvoker' uiAccess='false' />
7 </requestedPrivileges>
8 </security>
9 </trustInfo>
10 </assembly>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
12 DDED www/admin-v-setup.md
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -1,43 +1,10 @@
1
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
3
- xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
4
- <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="fossil"
5
- type="win32" />
6
- <description>
7
- Simple, high-reliability, distributed software configuration management system.
8
- </description>
9
- <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
10
- <security>
11
- <requestedPrivileges>
12
- <requestedExecutionLevel level="asInvoker" uiAccess="false" />
13
- </requestedPrivileges>
14
- </security>
15
- </trustInfo>
16
- <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
17
- <application>
18
- <!-- Windows 10 -->
19
- <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
20
- <!-- Windows 8.1 -->
21
- <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
22
- <!-- Windows 8 -->
23
- <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
24
- <!-- Windows 7 -->
25
- <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
26
- <!-- Windows Vista -->
27
- <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
28
- </application>
29
- </compatibility>
30
- <asmv3:application>
31
- <asmv3:windowsSettings
32
- xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
33
- <dpiAware>true</dpiAware>
34
- </asmv3:windowsSettings>
35
- </asmv3:application>
36
- <dependency>
37
- <dependentAssembly>
38
- <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls"
39
- version="6.0.0.0" processorArchitecture="X86"
40
- publicKeyToken="6595b64144ccf1df" language="*" />
41
- </dependentAssembly>
42
- </dependency>
43
-</assembly>
1
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
2
+<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
3
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
4
+ <security>
5
+ <requestedPrivileges>
6
+ <requestedExecutionLevel level='asInvoker' uiAccess='false' />
7
+ </requestedPrivileges>
8
+ </security>
9
+ </trustInfo>
10
+</assembly>
4411
4512
ADDED www/admin-v-setup.md
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -1,43 +1,10 @@
1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
3 xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
4 <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="fossil"
5 type="win32" />
6 <description>
7 Simple, high-reliability, distributed software configuration management system.
8 </description>
9 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
10 <security>
11 <requestedPrivileges>
12 <requestedExecutionLevel level="asInvoker" uiAccess="false" />
13 </requestedPrivileges>
14 </security>
15 </trustInfo>
16 <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
17 <application>
18 <!-- Windows 10 -->
19 <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
20 <!-- Windows 8.1 -->
21 <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
22 <!-- Windows 8 -->
23 <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
24 <!-- Windows 7 -->
25 <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
26 <!-- Windows Vista -->
27 <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
28 </application>
29 </compatibility>
30 <asmv3:application>
31 <asmv3:windowsSettings
32 xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
33 <dpiAware>true</dpiAware>
34 </asmv3:windowsSettings>
35 </asmv3:application>
36 <dependency>
37 <dependentAssembly>
38 <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls"
39 version="6.0.0.0" processorArchitecture="X86"
40 publicKeyToken="6595b64144ccf1df" language="*" />
41 </dependentAssembly>
42 </dependency>
43 </assembly>
44
45 DDED www/admin-v-setup.md
--- win/fossil.exe.manifest
+++ win/fossil.exe.manifest
@@ -1,43 +1,10 @@
1 <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
2 <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
3 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
4 <security>
5 <requestedPrivileges>
6 <requestedExecutionLevel level='asInvoker' uiAccess='false' />
7 </requestedPrivileges>
8 </security>
9 </trustInfo>
10 </assembly>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
12 DDED www/admin-v-setup.md
--- a/www/admin-v-setup.md
+++ b/www/admin-v-setup.md
@@ -0,0 +1,4 @@
1
+# The Differences Between theilitiestween Sthe power hierarcKeep Several of the Fossil user capabilities form a clear power hierarchy.
2
+Mathematically speaking:
3
+
4
+> *Setup > Admin > Moderator > User > Subsc# The Differe
--- a/www/admin-v-setup.md
+++ b/www/admin-v-setup.md
@@ -0,0 +1,4 @@
 
 
 
 
--- a/www/admin-v-setup.md
+++ b/www/admin-v-setup.md
@@ -0,0 +1,4 @@
1 # The Differences Between theilitiestween Sthe power hierarcKeep Several of the Fossil user capabilities form a clear power hierarchy.
2 Mathematically speaking:
3
4 > *Setup > Admin > Moderator > User > Subsc# The Differe
+1 -1
--- www/alerts.md
+++ www/alerts.md
@@ -474,11 +474,11 @@
474474
<a id="uvs"></a>
475475
## Users vs Subscribers
476476
477477
Fossil makes a distinction between "users" and "subscribers". A user is
478478
someone with a username and password: that is, someone who can log into
479
-the Fossi repository. A subscriber is someone who receives email
479
+the Fossil repository. A subscriber is someone who receives email
480480
alerts. Users can also be subscribers and subscribers can be users, but
481481
that does not have to be the case. It is possible to be a user without
482482
being a subscriber and to be a subscriber without being a user.
483483
484484
In the repository database file, users are tracked with the `user` table
485485
--- www/alerts.md
+++ www/alerts.md
@@ -474,11 +474,11 @@
474 <a id="uvs"></a>
475 ## Users vs Subscribers
476
477 Fossil makes a distinction between "users" and "subscribers". A user is
478 someone with a username and password: that is, someone who can log into
479 the Fossi repository. A subscriber is someone who receives email
480 alerts. Users can also be subscribers and subscribers can be users, but
481 that does not have to be the case. It is possible to be a user without
482 being a subscriber and to be a subscriber without being a user.
483
484 In the repository database file, users are tracked with the `user` table
485
--- www/alerts.md
+++ www/alerts.md
@@ -474,11 +474,11 @@
474 <a id="uvs"></a>
475 ## Users vs Subscribers
476
477 Fossil makes a distinction between "users" and "subscribers". A user is
478 someone with a username and password: that is, someone who can log into
479 the Fossil repository. A subscriber is someone who receives email
480 alerts. Users can also be subscribers and subscribers can be users, but
481 that does not have to be the case. It is possible to be a user without
482 being a subscriber and to be a subscriber without being a user.
483
484 In the repository database file, users are tracked with the `user` table
485
--- www/backoffice.md
+++ www/backoffice.md
@@ -166,11 +166,11 @@
166166
> fossil test-backoffice-lease -R _REPOSITORY_
167167
168168
Running that command every few seconds should show what is going on with
169169
backoffice processing in a particular repository.
170170
171
-There are also two settings that control backoffice behavior. The
171
+There are also settings that control backoffice behavior. The
172172
"backoffice-nodelay" setting prevents the "next" process from taking a
173173
lease and sleeping. If "backoffice-nodelay" is set, that causes all
174174
backoffice processes to exit either immediately or after doing whatever
175175
backoffice works needs to be done. If something is going wrong and
176176
backoffice leases are causing delays in webpage processing, then setting
@@ -177,7 +177,13 @@
177177
"backoffice-nodelay" to true can work around the problem until the bug
178178
can be fixed. The "backoffice-logfile" setting is the name of a log
179179
file onto which is appended a short message everything a backoffice
180180
process actually starts to do the backoffice work. This log file can
181181
be used to verify that backoffice really is running, if there is any
182
-doubt. Most installations should leave "backoffice-nodelay" off and
182
+doubt. The "backoffice-disable" setting prevents automatic backoffice
183
+processing, if true. Use this to completely disable backoffice processing
184
+that occurs automatically after each HTTP request. The "backoffice-disable"
185
+setting does not affect the operation of the manual
186
+"fossil backoffice" command.
187
+Most installations should leave "backoffice-nodelay" and "backoffice-disable"
188
+set to their default values of off and
183189
leave "backoffice-logfile" unset or set to an empty string.
184190
185191
ADDED www/blockchain.md
--- www/backoffice.md
+++ www/backoffice.md
@@ -166,11 +166,11 @@
166 > fossil test-backoffice-lease -R _REPOSITORY_
167
168 Running that command every few seconds should show what is going on with
169 backoffice processing in a particular repository.
170
171 There are also two settings that control backoffice behavior. The
172 "backoffice-nodelay" setting prevents the "next" process from taking a
173 lease and sleeping. If "backoffice-nodelay" is set, that causes all
174 backoffice processes to exit either immediately or after doing whatever
175 backoffice works needs to be done. If something is going wrong and
176 backoffice leases are causing delays in webpage processing, then setting
@@ -177,7 +177,13 @@
177 "backoffice-nodelay" to true can work around the problem until the bug
178 can be fixed. The "backoffice-logfile" setting is the name of a log
179 file onto which is appended a short message everything a backoffice
180 process actually starts to do the backoffice work. This log file can
181 be used to verify that backoffice really is running, if there is any
182 doubt. Most installations should leave "backoffice-nodelay" off and
 
 
 
 
 
 
183 leave "backoffice-logfile" unset or set to an empty string.
184
185 DDED www/blockchain.md
--- www/backoffice.md
+++ www/backoffice.md
@@ -166,11 +166,11 @@
166 > fossil test-backoffice-lease -R _REPOSITORY_
167
168 Running that command every few seconds should show what is going on with
169 backoffice processing in a particular repository.
170
171 There are also settings that control backoffice behavior. The
172 "backoffice-nodelay" setting prevents the "next" process from taking a
173 lease and sleeping. If "backoffice-nodelay" is set, that causes all
174 backoffice processes to exit either immediately or after doing whatever
175 backoffice works needs to be done. If something is going wrong and
176 backoffice leases are causing delays in webpage processing, then setting
@@ -177,7 +177,13 @@
177 "backoffice-nodelay" to true can work around the problem until the bug
178 can be fixed. The "backoffice-logfile" setting is the name of a log
179 file onto which is appended a short message everything a backoffice
180 process actually starts to do the backoffice work. This log file can
181 be used to verify that backoffice really is running, if there is any
182 doubt. The "backoffice-disable" setting prevents automatic backoffice
183 processing, if true. Use this to completely disable backoffice processing
184 that occurs automatically after each HTTP request. The "backoffice-disable"
185 setting does not affect the operation of the manual
186 "fossil backoffice" command.
187 Most installations should leave "backoffice-nodelay" and "backoffice-disable"
188 set to their default values of off and
189 leave "backoffice-logfile" unset or set to an empty string.
190
191 DDED www/blockchain.md
--- a/www/blockchain.md
+++ b/www/blockchain.md
@@ -0,0 +1,31 @@
1
+# Fossil As Blockchain
2
+
3
+Fossil is a version control system built around blockchain.
4
+
5
+hains in [PHB] Weekly — asks as
6
+
7
+>
8
+ "anization “has a blockchain.” With Fossil and a
9
+ suitably narrow definition of the termI@2j~,2s:in mind, you
10
+ could answer “Yes,” except that..." [(1)][]
11
+
12
+
13
+By that definition, Fossil is clearly an implementation of “Our development organization
14
+ has been usingN@OF,Fs:for years!” You may decide that
15
+ this makes you responsible for a public deception, putting the
16
+ organizaion at risk of an SEC investigation for making falSome people have c rganization has no actual need for a proper blockchain tech base,
17
+ isn’t it better to just say “Yes” and point at Fossil so you can get
18
+ back to useful work?
19
+
20
+* **Middle Managemed around blockchainManagement:** Your project leader asks the same question,
21
+ so you point them at this document, which tells them the truth:
22
+ kinda yes, but mostly no.
23
+
24
+* **Developer Lunch:** A peer asks if you’re doing anything with
25
+ blockchains. Knowing the coednts of this document, you decide you
26
+ can’t justify using that term to refer to Fossil at a deep technical
27
+ level, so you admit that you are not.
28
+
29
+[PHBZ@LU,I:Pointy-haired_BossI@2cV,1F@25G,8:s
30
+FossilO@2Ek,2Z@292,1m@2DM,B:What if youB5@2LA,1D: If you restrict your definition’s
31
+scope to cover only the most common
--- a/www/blockchain.md
+++ b/www/blockchain.md
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/www/blockchain.md
+++ b/www/blockchain.md
@@ -0,0 +1,31 @@
1 # Fossil As Blockchain
2
3 Fossil is a version control system built around blockchain.
4
5 hains in [PHB] Weekly — asks as
6
7 >
8 "anization “has a blockchain.” With Fossil and a
9 suitably narrow definition of the termI@2j~,2s:in mind, you
10 could answer “Yes,” except that..." [(1)][]
11
12
13 By that definition, Fossil is clearly an implementation of “Our development organization
14 has been usingN@OF,Fs:for years!” You may decide that
15 this makes you responsible for a public deception, putting the
16 organizaion at risk of an SEC investigation for making falSome people have c rganization has no actual need for a proper blockchain tech base,
17 isn’t it better to just say “Yes” and point at Fossil so you can get
18 back to useful work?
19
20 * **Middle Managemed around blockchainManagement:** Your project leader asks the same question,
21 so you point them at this document, which tells them the truth:
22 kinda yes, but mostly no.
23
24 * **Developer Lunch:** A peer asks if you’re doing anything with
25 blockchains. Knowing the coednts of this document, you decide you
26 can’t justify using that term to refer to Fossil at a deep technical
27 level, so you admit that you are not.
28
29 [PHBZ@LU,I:Pointy-haired_BossI@2cV,1F@25G,8:s
30 FossilO@2Ek,2Z@292,1m@2DM,B:What if youB5@2LA,1D: If you restrict your definition’s
31 scope to cover only the most common
+1 -1
--- www/build.wiki
+++ www/build.wiki
@@ -136,11 +136,11 @@
136136
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
137137
first <a href="https://www.openssl.org/source/">download the official
138138
source code for OpenSSL</a> and extract it to an appropriately named
139139
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
140140
[/tree?ci=trunk&name=compat | compat] directory (e.g.
141
-"<b>compat/openssl-1.1.1</b>"), then make sure that some recent
141
+"<b>compat/openssl-1.1.1a</b>"), then make sure that some recent
142142
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
143143
and finally run one of the following commands:
144144
<blockquote><pre>
145145
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
146146
</pre></blockquote>
147147
--- www/build.wiki
+++ www/build.wiki
@@ -136,11 +136,11 @@
136 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
137 first <a href="https://www.openssl.org/source/">download the official
138 source code for OpenSSL</a> and extract it to an appropriately named
139 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
140 [/tree?ci=trunk&name=compat | compat] directory (e.g.
141 "<b>compat/openssl-1.1.1</b>"), then make sure that some recent
142 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
143 and finally run one of the following commands:
144 <blockquote><pre>
145 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
146 </pre></blockquote>
147
--- www/build.wiki
+++ www/build.wiki
@@ -136,11 +136,11 @@
136 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
137 first <a href="https://www.openssl.org/source/">download the official
138 source code for OpenSSL</a> and extract it to an appropriately named
139 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
140 [/tree?ci=trunk&name=compat | compat] directory (e.g.
141 "<b>compat/openssl-1.1.1a</b>"), then make sure that some recent
142 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
143 and finally run one of the following commands:
144 <blockquote><pre>
145 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
146 </pre></blockquote>
147
+1 -1
--- www/build.wiki
+++ www/build.wiki
@@ -136,11 +136,11 @@
136136
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
137137
first <a href="https://www.openssl.org/source/">download the official
138138
source code for OpenSSL</a> and extract it to an appropriately named
139139
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
140140
[/tree?ci=trunk&name=compat | compat] directory (e.g.
141
-"<b>compat/openssl-1.1.1</b>"), then make sure that some recent
141
+"<b>compat/openssl-1.1.1a</b>"), then make sure that some recent
142142
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
143143
and finally run one of the following commands:
144144
<blockquote><pre>
145145
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
146146
</pre></blockquote>
147147
--- www/build.wiki
+++ www/build.wiki
@@ -136,11 +136,11 @@
136 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
137 first <a href="https://www.openssl.org/source/">download the official
138 source code for OpenSSL</a> and extract it to an appropriately named
139 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
140 [/tree?ci=trunk&name=compat | compat] directory (e.g.
141 "<b>compat/openssl-1.1.1</b>"), then make sure that some recent
142 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
143 and finally run one of the following commands:
144 <blockquote><pre>
145 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
146 </pre></blockquote>
147
--- www/build.wiki
+++ www/build.wiki
@@ -136,11 +136,11 @@
136 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
137 first <a href="https://www.openssl.org/source/">download the official
138 source code for OpenSSL</a> and extract it to an appropriately named
139 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
140 [/tree?ci=trunk&name=compat | compat] directory (e.g.
141 "<b>compat/openssl-1.1.1a</b>"), then make sure that some recent
142 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
143 and finally run one of the following commands:
144 <blockquote><pre>
145 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
146 </pre></blockquote>
147
--- www/changes.wiki
+++ www/changes.wiki
@@ -28,15 +28,22 @@
2828
included in the header or footer.
2929
* Add the [./backoffice.md|backoffice].
3030
* Update internal Unicode character tables, used in regular expression
3131
handling, from version 10.0 to 11.0.
3232
* Improvements to the "Security Audit" administration page
33
- * Added the [/help?cmd=branch|fossil branch current] command.
33
+ * Add the [/help?cmd=branch|fossil branch current] command.
34
+ * Add the [./grep.md|grep] command.
3435
* Update the built-in SQLite to version 3.25.1.
3536
* Some code and interfaces are in place to support sending and
3637
receiving email directly via SMTP, but this feature is not yet
3738
complete or ready for production use.
39
+ * The `mv-rm-files` setting is now compiled into Fossil in the
40
+ default Fossil configuration; no longer must you say
41
+ <tt>./configure --with-legacy-mv-rm</tt> to make it available. The
42
+ setting remains disabled by default, however, so you must still say
43
+ <tt>fossil set mv-rm-files 1</tt> to enable it on each repository
44
+ where you want hard <tt>mv/rm</tt> behavior.
3845
3946
<a name='v2_6'></a>
4047
<h2>Changes for Version 2.6 (2018-05-04)</h2>
4148
4249
* Fix a bug that was causing crashes while trying to clone the TCL
4350
--- www/changes.wiki
+++ www/changes.wiki
@@ -28,15 +28,22 @@
28 included in the header or footer.
29 * Add the [./backoffice.md|backoffice].
30 * Update internal Unicode character tables, used in regular expression
31 handling, from version 10.0 to 11.0.
32 * Improvements to the "Security Audit" administration page
33 * Added the [/help?cmd=branch|fossil branch current] command.
 
34 * Update the built-in SQLite to version 3.25.1.
35 * Some code and interfaces are in place to support sending and
36 receiving email directly via SMTP, but this feature is not yet
37 complete or ready for production use.
 
 
 
 
 
 
38
39 <a name='v2_6'></a>
40 <h2>Changes for Version 2.6 (2018-05-04)</h2>
41
42 * Fix a bug that was causing crashes while trying to clone the TCL
43
--- www/changes.wiki
+++ www/changes.wiki
@@ -28,15 +28,22 @@
28 included in the header or footer.
29 * Add the [./backoffice.md|backoffice].
30 * Update internal Unicode character tables, used in regular expression
31 handling, from version 10.0 to 11.0.
32 * Improvements to the "Security Audit" administration page
33 * Add the [/help?cmd=branch|fossil branch current] command.
34 * Add the [./grep.md|grep] command.
35 * Update the built-in SQLite to version 3.25.1.
36 * Some code and interfaces are in place to support sending and
37 receiving email directly via SMTP, but this feature is not yet
38 complete or ready for production use.
39 * The `mv-rm-files` setting is now compiled into Fossil in the
40 default Fossil configuration; no longer must you say
41 <tt>./configure --with-legacy-mv-rm</tt> to make it available. The
42 setting remains disabled by default, however, so you must still say
43 <tt>fossil set mv-rm-files 1</tt> to enable it on each repository
44 where you want hard <tt>mv/rm</tt> behavior.
45
46 <a name='v2_6'></a>
47 <h2>Changes for Version 2.6 (2018-05-04)</h2>
48
49 * Fix a bug that was causing crashes while trying to clone the TCL
50
+1 -1
--- www/event.wiki
+++ www/event.wiki
@@ -23,11 +23,11 @@
2323
can be something simple like "Version 1.2.3" perhaps with a bright
2424
color background to draw attention to the entry and the wiki content
2525
can contain release notes, for example.
2626
2727
* <b>Blog Entries</b>. Blog entries from developers describing the current
28
- state of a project, or rational for various design decisions, or
28
+ state of a project, or rationale for various design decisions, or
2929
roadmaps for future development, can be entered as technotes.
3030
3131
* <b>Process Checkpoints</b>. For projects that have a formal process,
3232
technotes can be used to record the completion or the initiation of
3333
various process steps. For example, a technote can be used to record
3434
--- www/event.wiki
+++ www/event.wiki
@@ -23,11 +23,11 @@
23 can be something simple like "Version 1.2.3" perhaps with a bright
24 color background to draw attention to the entry and the wiki content
25 can contain release notes, for example.
26
27 * <b>Blog Entries</b>. Blog entries from developers describing the current
28 state of a project, or rational for various design decisions, or
29 roadmaps for future development, can be entered as technotes.
30
31 * <b>Process Checkpoints</b>. For projects that have a formal process,
32 technotes can be used to record the completion or the initiation of
33 various process steps. For example, a technote can be used to record
34
--- www/event.wiki
+++ www/event.wiki
@@ -23,11 +23,11 @@
23 can be something simple like "Version 1.2.3" perhaps with a bright
24 color background to draw attention to the entry and the wiki content
25 can contain release notes, for example.
26
27 * <b>Blog Entries</b>. Blog entries from developers describing the current
28 state of a project, or rationale for various design decisions, or
29 roadmaps for future development, can be entered as technotes.
30
31 * <b>Process Checkpoints</b>. For projects that have a formal process,
32 technotes can be used to record the completion or the initiation of
33 various process steps. For example, a technote can be used to record
34
+131 -131
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -125,99 +125,99 @@
125125
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br>
126126
<b>U</b> <i>user-login</i><br>
127127
<b>Z</b> <i>manifest-checksum</i>
128128
</blockquote>
129129
130
-A manifest may optionally have a single B-card. The B-card specifies
130
+A manifest may optionally have a single <b>B</b> card. The <b>B</b> card specifies
131131
another manifest that serves as the "baseline" for this manifest. A
132
-manifest that has a B-card is called a delta-manifest and a manifest
133
-that omits the B-card is a baseline-manifest. The other manifest
134
-identified by the argument of the B-card must be a baseline-manifest.
132
+manifest that has a <b>B</b> card is called a delta-manifest and a manifest
133
+that omits the <b>B</b> card is a baseline-manifest. The other manifest
134
+identified by the argument of the <b>B</b> card must be a baseline-manifest.
135135
A baseline-manifest records the complete contents of a check-in.
136136
A delta-manifest records only changes from its baseline.
137137
138
-A manifest must have exactly one C-card. The sole argument to
139
-the C-card is a check-in comment that describes the check-in that
138
+A manifest must have exactly one <b>C</b> card. The sole argument to
139
+the <b>C</b> card is a check-in comment that describes the check-in that
140140
the manifest defines. The check-in comment is text. The following
141141
escape sequences are applied to the text:
142142
A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
143143
newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E). A backslash
144144
(ASCII 0x5C) is represented as two backslashes "\\". Apart from
145145
space and newline, no other whitespace characters are allowed in
146146
the check-in comment. Nor are any unprintable characters allowed
147147
in the comment.
148148
149
-A manifest must have exactly one D-card. The sole argument to
150
-the D-card is a date-time stamp in the ISO8601 format. The
149
+A manifest must have exactly one <b>D</b> card. The sole argument to
150
+the <b>D</b> card is a date-time stamp in the ISO8601 format. The
151151
date and time should be in coordinated universal time (UTC).
152152
The format one of:
153153
154154
<blockquote>
155155
<i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i><br>
156156
<i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i><b>.</b><i>SSS</i>
157157
</blockquote>
158158
159
-A manifest has zero or more F-cards. Each F-card identifies a file
159
+A manifest has zero or more <b>F</b> cards. Each <b>F</b> card identifies a file
160160
that is part of the check-in. There are one, two, three, or four
161161
arguments. The first argument is the pathname of the file in the
162162
check-in relative to the root of the project file hierarchy. No ".."
163163
or "." directories are allowed within the filename. Space characters
164
-are escaped as in C-card comment text. Backslash characters and
164
+are escaped as in <b>C</b> card comment text. Backslash characters and
165165
newlines are not allowed within filenames. The directory separator
166166
character is a forward slash (ASCII 0x2F). The second argument to the
167
-F-card is the lower-case hexadecimal artifact hash of
167
+<b>F</b> card is the lower-case hexadecimal artifact hash of
168168
the content artifact. The second argument is required for baseline
169169
manifests but is optional for delta manifests. When the second
170
-argument to the F-card is omitted, it means that the file has been
170
+argument to the <b>F</b> card is omitted, it means that the file has been
171171
deleted relative to the baseline (files removed in baseline manifests
172
-versions are <em>not</em> added as F-cards). The optional 3rd argument
172
+versions are <em>not</em> added as <b>F</b> cards). The optional 3rd argument
173173
defines any special access permissions associated with the file. This
174174
can be defined as "x" to mean that the file is executable or "l"
175175
(small letter ell) to mean a symlink. All files are always readable
176176
and writable. This can be expressed by "w" permission if desired but
177177
is optional. The file format might be extended with new permission
178178
letters in the future. The optional 4th argument is the name of the
179179
same file as it existed in the parent check-in. If the name of the
180180
file is unchanged from its parent, then the 4th argument is omitted.
181181
182
-A manifest has zero or one N-cards. The N-card specifies the mimetype for the
183
-text in the comment of the C-card. If the N-card is omitted, a default mimetype
182
+A manifest has zero or one <b>N</b> cards. The <b>N</b> card specifies the mimetype for the
183
+text in the comment of the <b>C</b> card. If the <b>N</b> card is omitted, a default mimetype
184184
is used.
185185
186
-A manifest has zero or one P-cards. Most manifests have one P-card.
187
-The P-card has a varying number of arguments that
186
+A manifest has zero or one <b>P</b> cards. Most manifests have one <b>P</b> card.
187
+The <b>P</b> card has a varying number of arguments that
188188
define other manifests from which the current manifest
189189
is derived. Each argument is a lowercase
190190
hexadecimal artifact hash of a predecessor manifest. All arguments
191
-to the P-card must be unique within that card.
191
+to the <b>P</b> card must be unique within that card.
192192
The first argument is the artifact hash of the direct ancestor of the manifest.
193193
Other arguments define manifests with which the first was
194194
merged to yield the current manifest. Most manifests have
195
-a P-card with a single argument. The first manifest in the
196
-project has no ancestors and thus has no P-card or (depending
197
-on the Fossil version) an empty P-card (no arguments).
195
+a <b>P</b> card with a single argument. The first manifest in the
196
+project has no ancestors and thus has no <b>P</b> card or (depending
197
+on the Fossil version) an empty <b>P</b> card (no arguments).
198198
199
-A manifest has zero or more Q-cards. A Q-card is similar to a P-card
199
+A manifest has zero or more <b>Q</b> cards. A <b>Q</b> card is similar to a <b>P</b> card
200200
in that it defines a predecessor to the current check-in. But
201
-whereas a P-card defines the immediate ancestor or a merge
202
-ancestor, the Q-card is used to identify a single check-in or a small
201
+whereas a <b>P</b> card defines the immediate ancestor or a merge
202
+ancestor, the <b>Q</b> card is used to identify a single check-in or a small
203203
range of check-ins which were cherry-picked for inclusion in or
204204
exclusion from the current manifest. The first argument of
205
-the Q-card is the artifact ID of another manifest (the "target")
205
+the <b>Q</b> card is the artifact ID of another manifest (the "target")
206206
which has had its changes included or excluded in the current manifest.
207207
The target is preceded by "+" or "-" to show inclusion or
208208
exclusion, respectively. The optional second argument to the
209
-Q-card is another manifest artifact ID which is the "baseline"
209
+<b>Q</b> card is another manifest artifact ID which is the "baseline"
210210
for the cherry-pick. If omitted, the baseline is the primary
211211
parent of the target. The
212212
changes included or excluded consist of all changes moving from
213213
the baseline to the target.
214214
215
-The Q-card was added to the interface specification on 2011-02-26.
216
-Older versions of Fossil will reject manifests that contain Q-cards.
215
+The <b>Q</b> card was added to the interface specification on 2011-02-26.
216
+Older versions of Fossil will reject manifests that contain <b>Q</b> cards.
217217
218
-A manifest may optionally have a single R-card. The R-card has
218
+A manifest may optionally have a single <b>R</b> card. The <b>R</b> card has
219219
a single argument which is the MD5 checksum of all files in
220220
the check-in except the manifest itself. The checksum is expressed
221221
as 32 characters of lowercase hexadecimal. The checksum is
222222
computed as follows: For each file in the check-in (except for
223223
the manifest itself) in strict sorted lexicographical order,
@@ -225,33 +225,33 @@
225225
repository, append a single space (ASCII 0x20), the
226226
size of the file in ASCII decimal, a single newline
227227
character (ASCII 0x0A), and the complete text of the file.
228228
Compute the MD5 checksum of the result.
229229
230
-A manifest might contain one or more T-cards used to set
230
+A manifest might contain one or more <b>T</b> cards used to set
231231
[./branching.wiki#tags | tags or properties]
232
-on the check-in. The format of the T-card is the same as
232
+on the check-in. The format of the <b>T</b> card is the same as
233233
described in <i>Control Artifacts</i> section below, except that the
234234
second argument is the single character "<b>*</b>" instead of an
235235
artifact ID. The <b>*</b> in place of the artifact ID indicates that
236236
the tag or property applies to the current artifact. It is not
237237
possible to encode the current artifact ID as part of an artifact,
238238
since the act of inserting the artifact ID would change the artifact ID,
239
-hence a <b>*</b> is used to represent "self". T-cards are typically
239
+hence a <b>*</b> is used to represent "self". <b>T</b> cards are typically
240240
added to manifests in order to set the <b>branch</b> property and a
241241
symbolic name when the check-in is intended to start a new branch.
242242
243
-Each manifest has a single U-card. The argument to the U-card is
243
+Each manifest has a single <b>U</b> card. The argument to the <b>U</b> card is
244244
the login of the user who created the manifest. The login name
245245
is encoded using the same character escapes as is used for the
246
-check-in comment argument to the C-card.
246
+check-in comment argument to the <b>C</b> card.
247247
248
-A manifest must have a single Z-card as its last line. The argument
249
-to the Z-card is a 32-character lowercase hexadecimal MD5 hash
248
+A manifest must have a single <b>Z</b> card as its last line. The argument
249
+to the <b>Z</b> card is a 32-character lowercase hexadecimal MD5 hash
250250
of all prior lines of the manifest up to and including the newline
251251
character that immediately precedes the "Z", excluding any PGP
252
-clear-signing prefix. The Z-card is
252
+clear-signing prefix. The <b>Z</b> card is
253253
a sanity check to prove that the manifest is well-formed and
254254
consistent.
255255
256256
A sample manifest from Fossil itself can be seen
257257
[/artifact/28987096ac | here].
@@ -270,16 +270,16 @@
270270
<blockquote>
271271
<b>M</b> <i>artifact-id</i><br />
272272
<b>Z</b> <i>checksum</i>
273273
</blockquote>
274274
275
-A cluster contains one or more "M" cards followed by a single "Z"
276
-card. Each M card has a single argument which is the artifact ID of
277
-another artifact in the repository. The Z card works exactly like
278
-the Z card of a manifest. The argument to the Z card is the
275
+A cluster contains one or more <b>M</b> cards followed by a single <b>Z</b> card.
276
+Each <b>M</b> card has a single argument which is the artifact ID of
277
+another artifact in the repository. The <b>Z</b> card works exactly like
278
+the <b>Z</b> card of a manifest. The argument to the <b>Z</b> card is the
279279
lower-case hexadecimal representation of the MD5 checksum of all
280
-prior cards in the cluster. The Z-card is required.
280
+prior cards in the cluster. The <b>Z</b> card is required.
281281
282282
An example cluster from Fossil can be seen
283283
[/artifact/d03dbdd73a2a8 | here].
284284
285285
<a name="ctrl"></a>
@@ -294,21 +294,21 @@
294294
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <i>artifact-id</i> ?<i>value</i>?<br />
295295
<b>U</b> <i>user-name</i><br />
296296
<b>Z</b> <i>checksum</i><br />
297297
</blockquote>
298298
299
-A control artifact must have one D card, one U card, one Z card and
300
-one or more T cards. No other cards or other text is
299
+A control artifact must have one <b>D</b> card, one <b>U</b> card, one <b>Z</b> card and
300
+one or more <b>T</b> cards. No other cards or other text is
301301
allowed in a control artifact. Control artifacts might be PGP
302302
clearsigned.
303303
304
-The D card and the Z card of a control artifact are the same
304
+The <b>D</b> card and the <b>Z</b> card of a control artifact are the same
305305
as in a manifest.
306306
307
-The T card represents a [./branching.wiki#tags | tag or property]
307
+The <b>T</b> card represents a [./branching.wiki#tags | tag or property]
308308
that is applied to
309
-some other artifact. The T card has two or three values. The
309
+some other artifact. The <b>T</b> card has two or three values. The
310310
second argument is the 40 character lowercase artifact ID of the artifact
311311
to which the tag is to be applied. The
312312
first value is the tag name. The first character of the tag
313313
is either "+", "-", or "*". The "+" means the tag should be added
314314
to the artifact. The "-" means the tag should be removed.
@@ -328,12 +328,12 @@
328328
for display purposes. The "user" tag overrides the name of the
329329
check-in user. The "date" tag overrides the check-in date.
330330
The "branch" tag sets the name of the branch that at check-in
331331
belongs to. Symbolic tags begin with the "sym-" prefix.
332332
333
-The U card is the name of the user that created the control
334
-artifact. The Z card is the usual required artifact checksum.
333
+The <b>U</b> card is the name of the user that created the control
334
+artifact. The <b>Z</b> card is the usual required artifact checksum.
335335
336336
An example control artifacts can be seen [/info/9d302ccda8 | here].
337337
338338
339339
<a name="wikichng"></a>
@@ -352,23 +352,23 @@
352352
<b>U</b> <i>user-name</i><br />
353353
<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
354354
<b>Z</b> <i>checksum</i>
355355
</blockquote>
356356
357
-The D card is the date and time when the wiki page was edited.
358
-The P card specifies the parent wiki pages, if any. The L card
359
-gives the name of the wiki page. The optional N card specifies
360
-the mimetype of the wiki text. If the N card is omitted, the
357
+The <b>D</b> card is the date and time when the wiki page was edited.
358
+The <b>P</b> card specifies the parent wiki pages, if any. The <b>L</b> card
359
+gives the name of the wiki page. The optional <b>N</b> card specifies
360
+the mimetype of the wiki text. If the <b>N</b> card is omitted, the
361361
mimetype is assumed to be text/x-fossil-wiki.
362
-The U card specifies the login
363
-of the user who made this edit to the wiki page. The Z card is
362
+The <b>U</b> card specifies the login
363
+of the user who made this edit to the wiki page. The <b>Z</b> card is
364364
the usual checksum over the entire artifact and is required.
365365
366
-The W card is used to specify the text of the wiki page. The
367
-argument to the W card is an integer which is the number of bytes
366
+The <b>W</b> card is used to specify the text of the wiki page. The
367
+argument to the <b>W</b> card is an integer which is the number of bytes
368368
of text in the wiki page. That text follows the newline character
369
-that terminates the W card. The wiki text is always followed by one
369
+that terminates the <b>W</b> card. The wiki text is always followed by one
370370
extra newline.
371371
372372
An example wiki artifact can be seen
373373
[/artifact?name=7b2f5fd0e0&txt=1 | here].
374374
@@ -384,38 +384,38 @@
384384
<b>K</b> <i>ticket-id</i><br />
385385
<b>U</b> <i>user-name</i><br />
386386
<b>Z</b> <i>checksum</i>
387387
</blockquote>
388388
389
-The D card is the usual date and time stamp and represents the point
390
-in time when the change was entered. The U card is the login of the
391
-programmer who entered this change. The Z card is the required checksum over
389
+The <b>D</b> card is the usual date and time stamp and represents the point
390
+in time when the change was entered. The <b>U</b> card is the login of the
391
+programmer who entered this change. The <b>Z</b> card is the required checksum over
392392
the entire artifact.
393393
394394
Every ticket has a distinct ticket-id:
395395
40-character lower-case hexadecimal number.
396
-The ticket-id is given in the K-card. A ticket exists if it contains one or
396
+The ticket-id is given in the <b>K</b> card. A ticket exists if it contains one or
397397
more changes. The first "change" to a ticket is what brings the
398398
ticket into existence.
399399
400
-J cards specify changes to the "value" of "fields" in the ticket.
401
-If the <i>value</i> parameter of the J card is omitted, then the
400
+<b>J</b> cards specify changes to the "value" of "fields" in the ticket.
401
+If the <i>value</i> parameter of the <b>J</b> card is omitted, then the
402402
field is set to an empty string.
403403
Each fossil server has a ticket configuration which specifies the fields its
404404
understands. The ticket configuration is part of the local state for
405405
the repository and thus can vary from one repository to another.
406
-Hence a J card might specify a <i>field</i> that do not exist in the
407
-local ticket configuration. If a J card specifies a <i>field</i> that
408
-is not in the local configuration, then that J card
406
+Hence a <b>J</b> card might specify a <i>field</i> that do not exist in the
407
+local ticket configuration. If a <b>J</b> card specifies a <i>field</i> that
408
+is not in the local configuration, then that <b>J</b> card
409409
is simply ignored.
410410
411
-The first argument of the J card is the field name. The second
411
+The first argument of the <b>J</b> card is the field name. The second
412412
value is the field value. If the field name begins with "+" then
413413
the value is appended to the prior value. Otherwise, the value
414
-on the J card replaces any previous value of the field.
414
+on the <b>J</b> card replaces any previous value of the field.
415415
The field name and value are both encoded using the character
416
-escapes defined for the C card of a manifest.
416
+escapes defined for the <b>C</b> card of a manifest.
417417
418418
An example ticket-change artifact can be seen
419419
[/artifact/91f1ec6af053 | here].
420420
421421
<a name="attachment"></a>
@@ -434,32 +434,32 @@
434434
<b>N</b> <i>mimetype</i><br />
435435
<b>U</b> <i>user-name</i><br />
436436
<b>Z</b> <i>checksum</i>
437437
</blockquote>
438438
439
-The A card specifies a filename for the attachment in its first argument.
440
-The second argument to the A card is the name of the wiki page or
439
+The <b>A</b> card specifies a filename for the attachment in its first argument.
440
+The second argument to the <b>A</b> card is the name of the wiki page or
441441
ticket or technical note to which the attachment is connected. The
442442
third argument is either missing or else it is the 40-character artifact
443443
ID of the attachment itself. A missing third argument means that the
444444
attachment should be deleted.
445445
446
-The C card is an optional comment describing what the attachment is about.
447
-The C card is optional, but there can only be one.
446
+The <b>C</b> card is an optional comment describing what the attachment is about.
447
+The <b>C</b> card is optional, but there can only be one.
448448
449
-A single D card is required to give the date and time when the attachment
449
+A single <b>D</b> card is required to give the date and time when the attachment
450450
was applied.
451451
452
-There may be zero or one N cards. The N card specifies the mimetype of the
453
-comment text provided in the C card. If the N card is omitted, the C card
452
+There may be zero or one <b>N</b> cards. The <b>N</b> card specifies the mimetype of the
453
+comment text provided in the <b>C</b> card. If the <b>N</b> card is omitted, the <b>C</b> card
454454
mimetype is taken to be text/plain.
455455
456
-A single U card gives the name of the user who added the attachment.
457
-If an attachment is added anonymously, then the U card may be omitted.
456
+A single <b>U</b> card gives the name of the user who added the attachment.
457
+If an attachment is added anonymously, then the <b>U</b> card may be omitted.
458458
459
-The Z card is the usual checksum over the rest of the attachment artifact.
460
-The Z card is required.
459
+The <b>Z</b> card is the usual checksum over the rest of the attachment artifact.
460
+The <b>Z</b> card is required.
461461
462462
463463
<a name="event"></a>
464464
<h3>2.7 Technical Notes</h3>
465465
@@ -480,55 +480,55 @@
480480
<b>U</b> <i>user-name</i><br />
481481
<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
482482
<b>Z</b> <i>checksum</i>
483483
</blockquote>
484484
485
-The C card contains text that is displayed on the timeline for the
486
-technote. The C card is optional, but there can only be one.
485
+The <b>C</b> card contains text that is displayed on the timeline for the
486
+technote. The <b>C</b> card is optional, but there can only be one.
487487
488
-A single D card is required to give the date and time when the
488
+A single <b>D</b> card is required to give the date and time when the
489489
technote artifact was created. This is different from the time at which
490490
the technote appears on the timeline.
491491
492
-A single E card gives the time of the technote (the point on the timeline
492
+A single <b>E</b> card gives the time of the technote (the point on the timeline
493493
where the technote is displayed) and a unique identifier for the technote.
494494
When there are multiple artifacts with the same technote-id, the one with
495
-the most recent D card is the only one used. The technote-id must be a
495
+the most recent <b>D</b> card is the only one used. The technote-id must be a
496496
40-character lower-case hexadecimal string.
497497
498
-The optional N card specifies the mimetype of the text of the technote
499
-that is contained in the W card. If the N card is omitted, then the
500
-W card text mimetype is assumed to be text/x-fossil-wiki, which is the
498
+The optional <b>N</b> card specifies the mimetype of the text of the technote
499
+that is contained in the <b>W</b> card. If the <b>N</b> card is omitted, then the
500
+<b>W</b> card text mimetype is assumed to be text/x-fossil-wiki, which is the
501501
Fossil wiki format.
502502
503
-The optional P card specifies a prior technote with the same technote-id
504
-from which the current technote is an edit. The P card is a hint to the
503
+The optional <b>P</b> card specifies a prior technote with the same technote-id
504
+from which the current technote is an edit. The <b>P</b> card is a hint to the
505505
system that it might be space efficient to store one technote as a delta of
506506
the other.
507507
508
-A technote might contain one or more T-cards used to set
508
+A technote might contain one or more <b>T</b> cards used to set
509509
[./branching.wiki#tags | tags or properties]
510
-on the technote. The format of the T-card is the same as
510
+on the technote. The format of the <b>T</b> card is the same as
511511
described in [#ctrl | Control Artifacts] section above, except that the
512512
second argument is the single character "<b>*</b>" instead of an
513513
artifact ID and the name is always prefaced by "<b>+</b>".
514514
The <b>*</b> in place of the artifact ID indicates that
515515
the tag or property applies to the current artifact. It is not
516516
possible to encode the current artifact ID as part of an artifact,
517517
since the act of inserting the artifact ID would change the artifact ID,
518518
hence a <b>*</b> is used to represent "self". The "<b>+</b>" on the
519519
name means that tags can only be add and they can only be non-propagating
520
-tags. In a technote, T cards are normally used to set the background
520
+tags. In a technote, <b>T</b> cards are normally used to set the background
521521
display color for timelines.
522522
523
-The optional U card gives name of the user who entered the technote.
523
+The optional <b>U</b> card gives name of the user who entered the technote.
524524
525
-A single W card provides wiki text for the document associated with the
526
-technote. The format of the W card is exactly the same as for a
525
+A single <b>W</b> card provides wiki text for the document associated with the
526
+technote. The format of the <b>W</b> card is exactly the same as for a
527527
[#wikichng | wiki artifact].
528528
529
-The Z card is the required checksum over the rest of the artifact.
529
+The <b>Z</b> card is the required checksum over the rest of the artifact.
530530
531531
<a name="forum"></a>
532532
<h3>2.8 Forum Posts</h3>
533533
534534
Forum posts are intended as a mechanism for users and developers to
@@ -546,63 +546,63 @@
546546
<b>U</b> <i>user-name</i><br />
547547
<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
548548
<b>Z</b> <i>checksum</i>
549549
</blockquote>
550550
551
-Every forum post must have either one I card and one G card
552
-or one H card.
551
+Every forum post must have either one <b>I</b> card and one <b>G</b> card
552
+or one <b>H</b> card.
553553
Forum posts are organized into topic threads. The initial
554
-post for a thread (the root post) has an H card giving the title or
555
-subject for that thread. The argument to the H card is a string
556
-in the same format as a comment string in a C card.
557
-All follow-up posts have an I card that
554
+post for a thread (the root post) has an <b>H</b> card giving the title or
555
+subject for that thread. The argument to the <b>H</b> card is a string
556
+in the same format as a comment string in a <b>C</b> card.
557
+All follow-up posts have an <b>I</b> card that
558558
indicates which prior post in the same thread the current forum
559
-post is replying to, and a G card specifying the root post for
560
-the entire thread. The argument to G and I cards is the
559
+post is replying to, and a <b>G</b> card specifying the root post for
560
+the entire thread. The argument to G and <b>I</b> cards is the
561561
artifact hash for the prior forum post to which the card refers.
562562
563563
In theory, it is sufficient for follow-up posts to have only an
564
-I card, since the G card value could be computed by following a
565
-chain of I cards. However, the G card is required in order to
564
+<b>I</b> card, since the <b>G</b> card value could be computed by following a
565
+chain of <b>I</b> cards. However, the <b>G</b> card is required in order to
566566
associate the artifact with a forum thread in the case where an
567
-intermediate artifact in the I card chain is shunned or otherwise
567
+intermediate artifact in the <b>I</b> card chain is shunned or otherwise
568568
becomes unreadable.
569569
570
-A single D card is required to give the date and time when the
570
+A single <b>D</b> card is required to give the date and time when the
571571
forum post was created.
572572
573
-The optional N card specifies the mimetype of the text of the technote
574
-that is contained in the W card. If the N card is omitted, then the
575
-W card text mimetype is assumed to be text/x-fossil-wiki, which is the
573
+The optional <b>N</b> card specifies the mimetype of the text of the technote
574
+that is contained in the <b>W</b> card. If the <b>N</b> card is omitted, then the
575
+<b>W</b> card text mimetype is assumed to be text/x-fossil-wiki, which is the
576576
Fossil wiki format.
577577
578
-The optional P card specifies a prior forum post for which this
578
+The optional <b>P</b> card specifies a prior forum post for which this
579579
forum post is an edit. For display purposes, only the child post
580580
is shown, though the historical post is retained as a record.
581
-If P cards are used and there exist multiple versions of the same
582
-forum post, then I cards for other artifacts refer to whichever
581
+If <b>P</b> cards are used and there exist multiple versions of the same
582
+forum post, then <b>I</b> cards for other artifacts refer to whichever
583583
version of the post was current at the time the reply was made,
584
-but G cards refer to the initial, unedited root post for the thread.
585
-Thus, following the chain of I cards back to the root of the thread
586
-may land on a different post than the one given in the G card.
587
-However, following the chain of I cards back to the thread root,
588
-then following P cards back to the initial version of the thread
589
-root must give the same artifact as is provided by the G card,
590
-otherwise the artifact containing the G card is considered invalid
584
+but <b>G</b> cards refer to the initial, unedited root post for the thread.
585
+Thus, following the chain of <b>I</b> cards back to the root of the thread
586
+may land on a different post than the one given in the <b>G</b> card.
587
+However, following the chain of <b>I</b> cards back to the thread root,
588
+then following <b>P</b> cards back to the initial version of the thread
589
+root must give the same artifact as is provided by the <b>G</b> card,
590
+otherwise the artifact containing the <b>G</b> card is considered invalid
591591
and should be ignored.
592592
593
-In general, P cards may contain multiple arguments, indicating a
593
+In general, <b>P</b> cards may contain multiple arguments, indicating a
594594
merge. But since forum posts cannot be merged, the
595
-P card of a forum post may only contain a single argument.
595
+<b>P</b> card of a forum post may only contain a single argument.
596596
597
-The U card gives name of the user who entered the forum post.
597
+The <b>U</b> card gives name of the user who entered the forum post.
598598
599
-A single W card provides wiki text for the forum post.
600
-The format of the W card is exactly the same as for a
599
+A single <b>W</b> card provides wiki text for the forum post.
600
+The format of the <b>W</b> card is exactly the same as for a
601601
[#wikichng | wiki artifact].
602602
603
-The Z card is the required checksum over the rest of the artifact.
603
+The <b>Z</b> card is the required checksum over the rest of the artifact.
604604
605605
606606
<a name="summary"></a>
607607
<h2>3.0 Card Summary</h2>
608608
@@ -868,11 +868,11 @@
868868
implementing algorithms described above.
869869
870870
<h3>4.1 R-Card Hash Calculation</h3>
871871
872872
Given a manifest file named <tt>MF</tt>, the following Bash shell code
873
-demonstrates how to compute the value of the R card in that manifest.
873
+demonstrates how to compute the value of the <b>R</b> card in that manifest.
874874
This example uses manifest [28987096ac]. Lines starting with <tt>#</tt> are
875875
shell input and other lines are output. This demonstration assumes that the
876876
file versions represented by the input manifest are checked out
877877
under the current directory.
878878
@@ -900,8 +900,8 @@
900900
Minor caveats: the above demonstration will work only when none of the
901901
filenames in the manifest are "fossilized" (encoded) because they contain
902902
spaces. In that case the shell-generated hash would differ because the
903903
<tt>stat</tt> calls will fail to find such files (which are output in encoded
904904
form here). That approach also won't work for delta manifests. Calculating
905
-the R-card for delta manifests requires traversing both the delta and its baseline in
905
+the <b>R</b> card for delta manifests requires traversing both the delta and its baseline in
906906
lexical order of the files, preferring the delta's copy if both contain
907907
a given file.
908908
909909
ADDED www/grep.md
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -125,99 +125,99 @@
125 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br>
126 <b>U</b> <i>user-login</i><br>
127 <b>Z</b> <i>manifest-checksum</i>
128 </blockquote>
129
130 A manifest may optionally have a single B-card. The B-card specifies
131 another manifest that serves as the "baseline" for this manifest. A
132 manifest that has a B-card is called a delta-manifest and a manifest
133 that omits the B-card is a baseline-manifest. The other manifest
134 identified by the argument of the B-card must be a baseline-manifest.
135 A baseline-manifest records the complete contents of a check-in.
136 A delta-manifest records only changes from its baseline.
137
138 A manifest must have exactly one C-card. The sole argument to
139 the C-card is a check-in comment that describes the check-in that
140 the manifest defines. The check-in comment is text. The following
141 escape sequences are applied to the text:
142 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
143 newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E). A backslash
144 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
145 space and newline, no other whitespace characters are allowed in
146 the check-in comment. Nor are any unprintable characters allowed
147 in the comment.
148
149 A manifest must have exactly one D-card. The sole argument to
150 the D-card is a date-time stamp in the ISO8601 format. The
151 date and time should be in coordinated universal time (UTC).
152 The format one of:
153
154 <blockquote>
155 <i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i><br>
156 <i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i><b>.</b><i>SSS</i>
157 </blockquote>
158
159 A manifest has zero or more F-cards. Each F-card identifies a file
160 that is part of the check-in. There are one, two, three, or four
161 arguments. The first argument is the pathname of the file in the
162 check-in relative to the root of the project file hierarchy. No ".."
163 or "." directories are allowed within the filename. Space characters
164 are escaped as in C-card comment text. Backslash characters and
165 newlines are not allowed within filenames. The directory separator
166 character is a forward slash (ASCII 0x2F). The second argument to the
167 F-card is the lower-case hexadecimal artifact hash of
168 the content artifact. The second argument is required for baseline
169 manifests but is optional for delta manifests. When the second
170 argument to the F-card is omitted, it means that the file has been
171 deleted relative to the baseline (files removed in baseline manifests
172 versions are <em>not</em> added as F-cards). The optional 3rd argument
173 defines any special access permissions associated with the file. This
174 can be defined as "x" to mean that the file is executable or "l"
175 (small letter ell) to mean a symlink. All files are always readable
176 and writable. This can be expressed by "w" permission if desired but
177 is optional. The file format might be extended with new permission
178 letters in the future. The optional 4th argument is the name of the
179 same file as it existed in the parent check-in. If the name of the
180 file is unchanged from its parent, then the 4th argument is omitted.
181
182 A manifest has zero or one N-cards. The N-card specifies the mimetype for the
183 text in the comment of the C-card. If the N-card is omitted, a default mimetype
184 is used.
185
186 A manifest has zero or one P-cards. Most manifests have one P-card.
187 The P-card has a varying number of arguments that
188 define other manifests from which the current manifest
189 is derived. Each argument is a lowercase
190 hexadecimal artifact hash of a predecessor manifest. All arguments
191 to the P-card must be unique within that card.
192 The first argument is the artifact hash of the direct ancestor of the manifest.
193 Other arguments define manifests with which the first was
194 merged to yield the current manifest. Most manifests have
195 a P-card with a single argument. The first manifest in the
196 project has no ancestors and thus has no P-card or (depending
197 on the Fossil version) an empty P-card (no arguments).
198
199 A manifest has zero or more Q-cards. A Q-card is similar to a P-card
200 in that it defines a predecessor to the current check-in. But
201 whereas a P-card defines the immediate ancestor or a merge
202 ancestor, the Q-card is used to identify a single check-in or a small
203 range of check-ins which were cherry-picked for inclusion in or
204 exclusion from the current manifest. The first argument of
205 the Q-card is the artifact ID of another manifest (the "target")
206 which has had its changes included or excluded in the current manifest.
207 The target is preceded by "+" or "-" to show inclusion or
208 exclusion, respectively. The optional second argument to the
209 Q-card is another manifest artifact ID which is the "baseline"
210 for the cherry-pick. If omitted, the baseline is the primary
211 parent of the target. The
212 changes included or excluded consist of all changes moving from
213 the baseline to the target.
214
215 The Q-card was added to the interface specification on 2011-02-26.
216 Older versions of Fossil will reject manifests that contain Q-cards.
217
218 A manifest may optionally have a single R-card. The R-card has
219 a single argument which is the MD5 checksum of all files in
220 the check-in except the manifest itself. The checksum is expressed
221 as 32 characters of lowercase hexadecimal. The checksum is
222 computed as follows: For each file in the check-in (except for
223 the manifest itself) in strict sorted lexicographical order,
@@ -225,33 +225,33 @@
225 repository, append a single space (ASCII 0x20), the
226 size of the file in ASCII decimal, a single newline
227 character (ASCII 0x0A), and the complete text of the file.
228 Compute the MD5 checksum of the result.
229
230 A manifest might contain one or more T-cards used to set
231 [./branching.wiki#tags | tags or properties]
232 on the check-in. The format of the T-card is the same as
233 described in <i>Control Artifacts</i> section below, except that the
234 second argument is the single character "<b>*</b>" instead of an
235 artifact ID. The <b>*</b> in place of the artifact ID indicates that
236 the tag or property applies to the current artifact. It is not
237 possible to encode the current artifact ID as part of an artifact,
238 since the act of inserting the artifact ID would change the artifact ID,
239 hence a <b>*</b> is used to represent "self". T-cards are typically
240 added to manifests in order to set the <b>branch</b> property and a
241 symbolic name when the check-in is intended to start a new branch.
242
243 Each manifest has a single U-card. The argument to the U-card is
244 the login of the user who created the manifest. The login name
245 is encoded using the same character escapes as is used for the
246 check-in comment argument to the C-card.
247
248 A manifest must have a single Z-card as its last line. The argument
249 to the Z-card is a 32-character lowercase hexadecimal MD5 hash
250 of all prior lines of the manifest up to and including the newline
251 character that immediately precedes the "Z", excluding any PGP
252 clear-signing prefix. The Z-card is
253 a sanity check to prove that the manifest is well-formed and
254 consistent.
255
256 A sample manifest from Fossil itself can be seen
257 [/artifact/28987096ac | here].
@@ -270,16 +270,16 @@
270 <blockquote>
271 <b>M</b> <i>artifact-id</i><br />
272 <b>Z</b> <i>checksum</i>
273 </blockquote>
274
275 A cluster contains one or more "M" cards followed by a single "Z"
276 card. Each M card has a single argument which is the artifact ID of
277 another artifact in the repository. The Z card works exactly like
278 the Z card of a manifest. The argument to the Z card is the
279 lower-case hexadecimal representation of the MD5 checksum of all
280 prior cards in the cluster. The Z-card is required.
281
282 An example cluster from Fossil can be seen
283 [/artifact/d03dbdd73a2a8 | here].
284
285 <a name="ctrl"></a>
@@ -294,21 +294,21 @@
294 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <i>artifact-id</i> ?<i>value</i>?<br />
295 <b>U</b> <i>user-name</i><br />
296 <b>Z</b> <i>checksum</i><br />
297 </blockquote>
298
299 A control artifact must have one D card, one U card, one Z card and
300 one or more T cards. No other cards or other text is
301 allowed in a control artifact. Control artifacts might be PGP
302 clearsigned.
303
304 The D card and the Z card of a control artifact are the same
305 as in a manifest.
306
307 The T card represents a [./branching.wiki#tags | tag or property]
308 that is applied to
309 some other artifact. The T card has two or three values. The
310 second argument is the 40 character lowercase artifact ID of the artifact
311 to which the tag is to be applied. The
312 first value is the tag name. The first character of the tag
313 is either "+", "-", or "*". The "+" means the tag should be added
314 to the artifact. The "-" means the tag should be removed.
@@ -328,12 +328,12 @@
328 for display purposes. The "user" tag overrides the name of the
329 check-in user. The "date" tag overrides the check-in date.
330 The "branch" tag sets the name of the branch that at check-in
331 belongs to. Symbolic tags begin with the "sym-" prefix.
332
333 The U card is the name of the user that created the control
334 artifact. The Z card is the usual required artifact checksum.
335
336 An example control artifacts can be seen [/info/9d302ccda8 | here].
337
338
339 <a name="wikichng"></a>
@@ -352,23 +352,23 @@
352 <b>U</b> <i>user-name</i><br />
353 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
354 <b>Z</b> <i>checksum</i>
355 </blockquote>
356
357 The D card is the date and time when the wiki page was edited.
358 The P card specifies the parent wiki pages, if any. The L card
359 gives the name of the wiki page. The optional N card specifies
360 the mimetype of the wiki text. If the N card is omitted, the
361 mimetype is assumed to be text/x-fossil-wiki.
362 The U card specifies the login
363 of the user who made this edit to the wiki page. The Z card is
364 the usual checksum over the entire artifact and is required.
365
366 The W card is used to specify the text of the wiki page. The
367 argument to the W card is an integer which is the number of bytes
368 of text in the wiki page. That text follows the newline character
369 that terminates the W card. The wiki text is always followed by one
370 extra newline.
371
372 An example wiki artifact can be seen
373 [/artifact?name=7b2f5fd0e0&txt=1 | here].
374
@@ -384,38 +384,38 @@
384 <b>K</b> <i>ticket-id</i><br />
385 <b>U</b> <i>user-name</i><br />
386 <b>Z</b> <i>checksum</i>
387 </blockquote>
388
389 The D card is the usual date and time stamp and represents the point
390 in time when the change was entered. The U card is the login of the
391 programmer who entered this change. The Z card is the required checksum over
392 the entire artifact.
393
394 Every ticket has a distinct ticket-id:
395 40-character lower-case hexadecimal number.
396 The ticket-id is given in the K-card. A ticket exists if it contains one or
397 more changes. The first "change" to a ticket is what brings the
398 ticket into existence.
399
400 J cards specify changes to the "value" of "fields" in the ticket.
401 If the <i>value</i> parameter of the J card is omitted, then the
402 field is set to an empty string.
403 Each fossil server has a ticket configuration which specifies the fields its
404 understands. The ticket configuration is part of the local state for
405 the repository and thus can vary from one repository to another.
406 Hence a J card might specify a <i>field</i> that do not exist in the
407 local ticket configuration. If a J card specifies a <i>field</i> that
408 is not in the local configuration, then that J card
409 is simply ignored.
410
411 The first argument of the J card is the field name. The second
412 value is the field value. If the field name begins with "+" then
413 the value is appended to the prior value. Otherwise, the value
414 on the J card replaces any previous value of the field.
415 The field name and value are both encoded using the character
416 escapes defined for the C card of a manifest.
417
418 An example ticket-change artifact can be seen
419 [/artifact/91f1ec6af053 | here].
420
421 <a name="attachment"></a>
@@ -434,32 +434,32 @@
434 <b>N</b> <i>mimetype</i><br />
435 <b>U</b> <i>user-name</i><br />
436 <b>Z</b> <i>checksum</i>
437 </blockquote>
438
439 The A card specifies a filename for the attachment in its first argument.
440 The second argument to the A card is the name of the wiki page or
441 ticket or technical note to which the attachment is connected. The
442 third argument is either missing or else it is the 40-character artifact
443 ID of the attachment itself. A missing third argument means that the
444 attachment should be deleted.
445
446 The C card is an optional comment describing what the attachment is about.
447 The C card is optional, but there can only be one.
448
449 A single D card is required to give the date and time when the attachment
450 was applied.
451
452 There may be zero or one N cards. The N card specifies the mimetype of the
453 comment text provided in the C card. If the N card is omitted, the C card
454 mimetype is taken to be text/plain.
455
456 A single U card gives the name of the user who added the attachment.
457 If an attachment is added anonymously, then the U card may be omitted.
458
459 The Z card is the usual checksum over the rest of the attachment artifact.
460 The Z card is required.
461
462
463 <a name="event"></a>
464 <h3>2.7 Technical Notes</h3>
465
@@ -480,55 +480,55 @@
480 <b>U</b> <i>user-name</i><br />
481 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
482 <b>Z</b> <i>checksum</i>
483 </blockquote>
484
485 The C card contains text that is displayed on the timeline for the
486 technote. The C card is optional, but there can only be one.
487
488 A single D card is required to give the date and time when the
489 technote artifact was created. This is different from the time at which
490 the technote appears on the timeline.
491
492 A single E card gives the time of the technote (the point on the timeline
493 where the technote is displayed) and a unique identifier for the technote.
494 When there are multiple artifacts with the same technote-id, the one with
495 the most recent D card is the only one used. The technote-id must be a
496 40-character lower-case hexadecimal string.
497
498 The optional N card specifies the mimetype of the text of the technote
499 that is contained in the W card. If the N card is omitted, then the
500 W card text mimetype is assumed to be text/x-fossil-wiki, which is the
501 Fossil wiki format.
502
503 The optional P card specifies a prior technote with the same technote-id
504 from which the current technote is an edit. The P card is a hint to the
505 system that it might be space efficient to store one technote as a delta of
506 the other.
507
508 A technote might contain one or more T-cards used to set
509 [./branching.wiki#tags | tags or properties]
510 on the technote. The format of the T-card is the same as
511 described in [#ctrl | Control Artifacts] section above, except that the
512 second argument is the single character "<b>*</b>" instead of an
513 artifact ID and the name is always prefaced by "<b>+</b>".
514 The <b>*</b> in place of the artifact ID indicates that
515 the tag or property applies to the current artifact. It is not
516 possible to encode the current artifact ID as part of an artifact,
517 since the act of inserting the artifact ID would change the artifact ID,
518 hence a <b>*</b> is used to represent "self". The "<b>+</b>" on the
519 name means that tags can only be add and they can only be non-propagating
520 tags. In a technote, T cards are normally used to set the background
521 display color for timelines.
522
523 The optional U card gives name of the user who entered the technote.
524
525 A single W card provides wiki text for the document associated with the
526 technote. The format of the W card is exactly the same as for a
527 [#wikichng | wiki artifact].
528
529 The Z card is the required checksum over the rest of the artifact.
530
531 <a name="forum"></a>
532 <h3>2.8 Forum Posts</h3>
533
534 Forum posts are intended as a mechanism for users and developers to
@@ -546,63 +546,63 @@
546 <b>U</b> <i>user-name</i><br />
547 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
548 <b>Z</b> <i>checksum</i>
549 </blockquote>
550
551 Every forum post must have either one I card and one G card
552 or one H card.
553 Forum posts are organized into topic threads. The initial
554 post for a thread (the root post) has an H card giving the title or
555 subject for that thread. The argument to the H card is a string
556 in the same format as a comment string in a C card.
557 All follow-up posts have an I card that
558 indicates which prior post in the same thread the current forum
559 post is replying to, and a G card specifying the root post for
560 the entire thread. The argument to G and I cards is the
561 artifact hash for the prior forum post to which the card refers.
562
563 In theory, it is sufficient for follow-up posts to have only an
564 I card, since the G card value could be computed by following a
565 chain of I cards. However, the G card is required in order to
566 associate the artifact with a forum thread in the case where an
567 intermediate artifact in the I card chain is shunned or otherwise
568 becomes unreadable.
569
570 A single D card is required to give the date and time when the
571 forum post was created.
572
573 The optional N card specifies the mimetype of the text of the technote
574 that is contained in the W card. If the N card is omitted, then the
575 W card text mimetype is assumed to be text/x-fossil-wiki, which is the
576 Fossil wiki format.
577
578 The optional P card specifies a prior forum post for which this
579 forum post is an edit. For display purposes, only the child post
580 is shown, though the historical post is retained as a record.
581 If P cards are used and there exist multiple versions of the same
582 forum post, then I cards for other artifacts refer to whichever
583 version of the post was current at the time the reply was made,
584 but G cards refer to the initial, unedited root post for the thread.
585 Thus, following the chain of I cards back to the root of the thread
586 may land on a different post than the one given in the G card.
587 However, following the chain of I cards back to the thread root,
588 then following P cards back to the initial version of the thread
589 root must give the same artifact as is provided by the G card,
590 otherwise the artifact containing the G card is considered invalid
591 and should be ignored.
592
593 In general, P cards may contain multiple arguments, indicating a
594 merge. But since forum posts cannot be merged, the
595 P card of a forum post may only contain a single argument.
596
597 The U card gives name of the user who entered the forum post.
598
599 A single W card provides wiki text for the forum post.
600 The format of the W card is exactly the same as for a
601 [#wikichng | wiki artifact].
602
603 The Z card is the required checksum over the rest of the artifact.
604
605
606 <a name="summary"></a>
607 <h2>3.0 Card Summary</h2>
608
@@ -868,11 +868,11 @@
868 implementing algorithms described above.
869
870 <h3>4.1 R-Card Hash Calculation</h3>
871
872 Given a manifest file named <tt>MF</tt>, the following Bash shell code
873 demonstrates how to compute the value of the R card in that manifest.
874 This example uses manifest [28987096ac]. Lines starting with <tt>#</tt> are
875 shell input and other lines are output. This demonstration assumes that the
876 file versions represented by the input manifest are checked out
877 under the current directory.
878
@@ -900,8 +900,8 @@
900 Minor caveats: the above demonstration will work only when none of the
901 filenames in the manifest are "fossilized" (encoded) because they contain
902 spaces. In that case the shell-generated hash would differ because the
903 <tt>stat</tt> calls will fail to find such files (which are output in encoded
904 form here). That approach also won't work for delta manifests. Calculating
905 the R-card for delta manifests requires traversing both the delta and its baseline in
906 lexical order of the files, preferring the delta's copy if both contain
907 a given file.
908
909 DDED www/grep.md
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -125,99 +125,99 @@
125 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br>
126 <b>U</b> <i>user-login</i><br>
127 <b>Z</b> <i>manifest-checksum</i>
128 </blockquote>
129
130 A manifest may optionally have a single <b>B</b> card. The <b>B</b> card specifies
131 another manifest that serves as the "baseline" for this manifest. A
132 manifest that has a <b>B</b> card is called a delta-manifest and a manifest
133 that omits the <b>B</b> card is a baseline-manifest. The other manifest
134 identified by the argument of the <b>B</b> card must be a baseline-manifest.
135 A baseline-manifest records the complete contents of a check-in.
136 A delta-manifest records only changes from its baseline.
137
138 A manifest must have exactly one <b>C</b> card. The sole argument to
139 the <b>C</b> card is a check-in comment that describes the check-in that
140 the manifest defines. The check-in comment is text. The following
141 escape sequences are applied to the text:
142 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
143 newline (ASCII 0x0a) is "\n" (ASCII 0x5C, x6E). A backslash
144 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
145 space and newline, no other whitespace characters are allowed in
146 the check-in comment. Nor are any unprintable characters allowed
147 in the comment.
148
149 A manifest must have exactly one <b>D</b> card. The sole argument to
150 the <b>D</b> card is a date-time stamp in the ISO8601 format. The
151 date and time should be in coordinated universal time (UTC).
152 The format one of:
153
154 <blockquote>
155 <i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i><br>
156 <i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i><b>.</b><i>SSS</i>
157 </blockquote>
158
159 A manifest has zero or more <b>F</b> cards. Each <b>F</b> card identifies a file
160 that is part of the check-in. There are one, two, three, or four
161 arguments. The first argument is the pathname of the file in the
162 check-in relative to the root of the project file hierarchy. No ".."
163 or "." directories are allowed within the filename. Space characters
164 are escaped as in <b>C</b> card comment text. Backslash characters and
165 newlines are not allowed within filenames. The directory separator
166 character is a forward slash (ASCII 0x2F). The second argument to the
167 <b>F</b> card is the lower-case hexadecimal artifact hash of
168 the content artifact. The second argument is required for baseline
169 manifests but is optional for delta manifests. When the second
170 argument to the <b>F</b> card is omitted, it means that the file has been
171 deleted relative to the baseline (files removed in baseline manifests
172 versions are <em>not</em> added as <b>F</b> cards). The optional 3rd argument
173 defines any special access permissions associated with the file. This
174 can be defined as "x" to mean that the file is executable or "l"
175 (small letter ell) to mean a symlink. All files are always readable
176 and writable. This can be expressed by "w" permission if desired but
177 is optional. The file format might be extended with new permission
178 letters in the future. The optional 4th argument is the name of the
179 same file as it existed in the parent check-in. If the name of the
180 file is unchanged from its parent, then the 4th argument is omitted.
181
182 A manifest has zero or one <b>N</b> cards. The <b>N</b> card specifies the mimetype for the
183 text in the comment of the <b>C</b> card. If the <b>N</b> card is omitted, a default mimetype
184 is used.
185
186 A manifest has zero or one <b>P</b> cards. Most manifests have one <b>P</b> card.
187 The <b>P</b> card has a varying number of arguments that
188 define other manifests from which the current manifest
189 is derived. Each argument is a lowercase
190 hexadecimal artifact hash of a predecessor manifest. All arguments
191 to the <b>P</b> card must be unique within that card.
192 The first argument is the artifact hash of the direct ancestor of the manifest.
193 Other arguments define manifests with which the first was
194 merged to yield the current manifest. Most manifests have
195 a <b>P</b> card with a single argument. The first manifest in the
196 project has no ancestors and thus has no <b>P</b> card or (depending
197 on the Fossil version) an empty <b>P</b> card (no arguments).
198
199 A manifest has zero or more <b>Q</b> cards. A <b>Q</b> card is similar to a <b>P</b> card
200 in that it defines a predecessor to the current check-in. But
201 whereas a <b>P</b> card defines the immediate ancestor or a merge
202 ancestor, the <b>Q</b> card is used to identify a single check-in or a small
203 range of check-ins which were cherry-picked for inclusion in or
204 exclusion from the current manifest. The first argument of
205 the <b>Q</b> card is the artifact ID of another manifest (the "target")
206 which has had its changes included or excluded in the current manifest.
207 The target is preceded by "+" or "-" to show inclusion or
208 exclusion, respectively. The optional second argument to the
209 <b>Q</b> card is another manifest artifact ID which is the "baseline"
210 for the cherry-pick. If omitted, the baseline is the primary
211 parent of the target. The
212 changes included or excluded consist of all changes moving from
213 the baseline to the target.
214
215 The <b>Q</b> card was added to the interface specification on 2011-02-26.
216 Older versions of Fossil will reject manifests that contain <b>Q</b> cards.
217
218 A manifest may optionally have a single <b>R</b> card. The <b>R</b> card has
219 a single argument which is the MD5 checksum of all files in
220 the check-in except the manifest itself. The checksum is expressed
221 as 32 characters of lowercase hexadecimal. The checksum is
222 computed as follows: For each file in the check-in (except for
223 the manifest itself) in strict sorted lexicographical order,
@@ -225,33 +225,33 @@
225 repository, append a single space (ASCII 0x20), the
226 size of the file in ASCII decimal, a single newline
227 character (ASCII 0x0A), and the complete text of the file.
228 Compute the MD5 checksum of the result.
229
230 A manifest might contain one or more <b>T</b> cards used to set
231 [./branching.wiki#tags | tags or properties]
232 on the check-in. The format of the <b>T</b> card is the same as
233 described in <i>Control Artifacts</i> section below, except that the
234 second argument is the single character "<b>*</b>" instead of an
235 artifact ID. The <b>*</b> in place of the artifact ID indicates that
236 the tag or property applies to the current artifact. It is not
237 possible to encode the current artifact ID as part of an artifact,
238 since the act of inserting the artifact ID would change the artifact ID,
239 hence a <b>*</b> is used to represent "self". <b>T</b> cards are typically
240 added to manifests in order to set the <b>branch</b> property and a
241 symbolic name when the check-in is intended to start a new branch.
242
243 Each manifest has a single <b>U</b> card. The argument to the <b>U</b> card is
244 the login of the user who created the manifest. The login name
245 is encoded using the same character escapes as is used for the
246 check-in comment argument to the <b>C</b> card.
247
248 A manifest must have a single <b>Z</b> card as its last line. The argument
249 to the <b>Z</b> card is a 32-character lowercase hexadecimal MD5 hash
250 of all prior lines of the manifest up to and including the newline
251 character that immediately precedes the "Z", excluding any PGP
252 clear-signing prefix. The <b>Z</b> card is
253 a sanity check to prove that the manifest is well-formed and
254 consistent.
255
256 A sample manifest from Fossil itself can be seen
257 [/artifact/28987096ac | here].
@@ -270,16 +270,16 @@
270 <blockquote>
271 <b>M</b> <i>artifact-id</i><br />
272 <b>Z</b> <i>checksum</i>
273 </blockquote>
274
275 A cluster contains one or more <b>M</b> cards followed by a single <b>Z</b> card.
276 Each <b>M</b> card has a single argument which is the artifact ID of
277 another artifact in the repository. The <b>Z</b> card works exactly like
278 the <b>Z</b> card of a manifest. The argument to the <b>Z</b> card is the
279 lower-case hexadecimal representation of the MD5 checksum of all
280 prior cards in the cluster. The <b>Z</b> card is required.
281
282 An example cluster from Fossil can be seen
283 [/artifact/d03dbdd73a2a8 | here].
284
285 <a name="ctrl"></a>
@@ -294,21 +294,21 @@
294 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <i>artifact-id</i> ?<i>value</i>?<br />
295 <b>U</b> <i>user-name</i><br />
296 <b>Z</b> <i>checksum</i><br />
297 </blockquote>
298
299 A control artifact must have one <b>D</b> card, one <b>U</b> card, one <b>Z</b> card and
300 one or more <b>T</b> cards. No other cards or other text is
301 allowed in a control artifact. Control artifacts might be PGP
302 clearsigned.
303
304 The <b>D</b> card and the <b>Z</b> card of a control artifact are the same
305 as in a manifest.
306
307 The <b>T</b> card represents a [./branching.wiki#tags | tag or property]
308 that is applied to
309 some other artifact. The <b>T</b> card has two or three values. The
310 second argument is the 40 character lowercase artifact ID of the artifact
311 to which the tag is to be applied. The
312 first value is the tag name. The first character of the tag
313 is either "+", "-", or "*". The "+" means the tag should be added
314 to the artifact. The "-" means the tag should be removed.
@@ -328,12 +328,12 @@
328 for display purposes. The "user" tag overrides the name of the
329 check-in user. The "date" tag overrides the check-in date.
330 The "branch" tag sets the name of the branch that at check-in
331 belongs to. Symbolic tags begin with the "sym-" prefix.
332
333 The <b>U</b> card is the name of the user that created the control
334 artifact. The <b>Z</b> card is the usual required artifact checksum.
335
336 An example control artifacts can be seen [/info/9d302ccda8 | here].
337
338
339 <a name="wikichng"></a>
@@ -352,23 +352,23 @@
352 <b>U</b> <i>user-name</i><br />
353 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
354 <b>Z</b> <i>checksum</i>
355 </blockquote>
356
357 The <b>D</b> card is the date and time when the wiki page was edited.
358 The <b>P</b> card specifies the parent wiki pages, if any. The <b>L</b> card
359 gives the name of the wiki page. The optional <b>N</b> card specifies
360 the mimetype of the wiki text. If the <b>N</b> card is omitted, the
361 mimetype is assumed to be text/x-fossil-wiki.
362 The <b>U</b> card specifies the login
363 of the user who made this edit to the wiki page. The <b>Z</b> card is
364 the usual checksum over the entire artifact and is required.
365
366 The <b>W</b> card is used to specify the text of the wiki page. The
367 argument to the <b>W</b> card is an integer which is the number of bytes
368 of text in the wiki page. That text follows the newline character
369 that terminates the <b>W</b> card. The wiki text is always followed by one
370 extra newline.
371
372 An example wiki artifact can be seen
373 [/artifact?name=7b2f5fd0e0&txt=1 | here].
374
@@ -384,38 +384,38 @@
384 <b>K</b> <i>ticket-id</i><br />
385 <b>U</b> <i>user-name</i><br />
386 <b>Z</b> <i>checksum</i>
387 </blockquote>
388
389 The <b>D</b> card is the usual date and time stamp and represents the point
390 in time when the change was entered. The <b>U</b> card is the login of the
391 programmer who entered this change. The <b>Z</b> card is the required checksum over
392 the entire artifact.
393
394 Every ticket has a distinct ticket-id:
395 40-character lower-case hexadecimal number.
396 The ticket-id is given in the <b>K</b> card. A ticket exists if it contains one or
397 more changes. The first "change" to a ticket is what brings the
398 ticket into existence.
399
400 <b>J</b> cards specify changes to the "value" of "fields" in the ticket.
401 If the <i>value</i> parameter of the <b>J</b> card is omitted, then the
402 field is set to an empty string.
403 Each fossil server has a ticket configuration which specifies the fields its
404 understands. The ticket configuration is part of the local state for
405 the repository and thus can vary from one repository to another.
406 Hence a <b>J</b> card might specify a <i>field</i> that do not exist in the
407 local ticket configuration. If a <b>J</b> card specifies a <i>field</i> that
408 is not in the local configuration, then that <b>J</b> card
409 is simply ignored.
410
411 The first argument of the <b>J</b> card is the field name. The second
412 value is the field value. If the field name begins with "+" then
413 the value is appended to the prior value. Otherwise, the value
414 on the <b>J</b> card replaces any previous value of the field.
415 The field name and value are both encoded using the character
416 escapes defined for the <b>C</b> card of a manifest.
417
418 An example ticket-change artifact can be seen
419 [/artifact/91f1ec6af053 | here].
420
421 <a name="attachment"></a>
@@ -434,32 +434,32 @@
434 <b>N</b> <i>mimetype</i><br />
435 <b>U</b> <i>user-name</i><br />
436 <b>Z</b> <i>checksum</i>
437 </blockquote>
438
439 The <b>A</b> card specifies a filename for the attachment in its first argument.
440 The second argument to the <b>A</b> card is the name of the wiki page or
441 ticket or technical note to which the attachment is connected. The
442 third argument is either missing or else it is the 40-character artifact
443 ID of the attachment itself. A missing third argument means that the
444 attachment should be deleted.
445
446 The <b>C</b> card is an optional comment describing what the attachment is about.
447 The <b>C</b> card is optional, but there can only be one.
448
449 A single <b>D</b> card is required to give the date and time when the attachment
450 was applied.
451
452 There may be zero or one <b>N</b> cards. The <b>N</b> card specifies the mimetype of the
453 comment text provided in the <b>C</b> card. If the <b>N</b> card is omitted, the <b>C</b> card
454 mimetype is taken to be text/plain.
455
456 A single <b>U</b> card gives the name of the user who added the attachment.
457 If an attachment is added anonymously, then the <b>U</b> card may be omitted.
458
459 The <b>Z</b> card is the usual checksum over the rest of the attachment artifact.
460 The <b>Z</b> card is required.
461
462
463 <a name="event"></a>
464 <h3>2.7 Technical Notes</h3>
465
@@ -480,55 +480,55 @@
480 <b>U</b> <i>user-name</i><br />
481 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
482 <b>Z</b> <i>checksum</i>
483 </blockquote>
484
485 The <b>C</b> card contains text that is displayed on the timeline for the
486 technote. The <b>C</b> card is optional, but there can only be one.
487
488 A single <b>D</b> card is required to give the date and time when the
489 technote artifact was created. This is different from the time at which
490 the technote appears on the timeline.
491
492 A single <b>E</b> card gives the time of the technote (the point on the timeline
493 where the technote is displayed) and a unique identifier for the technote.
494 When there are multiple artifacts with the same technote-id, the one with
495 the most recent <b>D</b> card is the only one used. The technote-id must be a
496 40-character lower-case hexadecimal string.
497
498 The optional <b>N</b> card specifies the mimetype of the text of the technote
499 that is contained in the <b>W</b> card. If the <b>N</b> card is omitted, then the
500 <b>W</b> card text mimetype is assumed to be text/x-fossil-wiki, which is the
501 Fossil wiki format.
502
503 The optional <b>P</b> card specifies a prior technote with the same technote-id
504 from which the current technote is an edit. The <b>P</b> card is a hint to the
505 system that it might be space efficient to store one technote as a delta of
506 the other.
507
508 A technote might contain one or more <b>T</b> cards used to set
509 [./branching.wiki#tags | tags or properties]
510 on the technote. The format of the <b>T</b> card is the same as
511 described in [#ctrl | Control Artifacts] section above, except that the
512 second argument is the single character "<b>*</b>" instead of an
513 artifact ID and the name is always prefaced by "<b>+</b>".
514 The <b>*</b> in place of the artifact ID indicates that
515 the tag or property applies to the current artifact. It is not
516 possible to encode the current artifact ID as part of an artifact,
517 since the act of inserting the artifact ID would change the artifact ID,
518 hence a <b>*</b> is used to represent "self". The "<b>+</b>" on the
519 name means that tags can only be add and they can only be non-propagating
520 tags. In a technote, <b>T</b> cards are normally used to set the background
521 display color for timelines.
522
523 The optional <b>U</b> card gives name of the user who entered the technote.
524
525 A single <b>W</b> card provides wiki text for the document associated with the
526 technote. The format of the <b>W</b> card is exactly the same as for a
527 [#wikichng | wiki artifact].
528
529 The <b>Z</b> card is the required checksum over the rest of the artifact.
530
531 <a name="forum"></a>
532 <h3>2.8 Forum Posts</h3>
533
534 Forum posts are intended as a mechanism for users and developers to
@@ -546,63 +546,63 @@
546 <b>U</b> <i>user-name</i><br />
547 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
548 <b>Z</b> <i>checksum</i>
549 </blockquote>
550
551 Every forum post must have either one <b>I</b> card and one <b>G</b> card
552 or one <b>H</b> card.
553 Forum posts are organized into topic threads. The initial
554 post for a thread (the root post) has an <b>H</b> card giving the title or
555 subject for that thread. The argument to the <b>H</b> card is a string
556 in the same format as a comment string in a <b>C</b> card.
557 All follow-up posts have an <b>I</b> card that
558 indicates which prior post in the same thread the current forum
559 post is replying to, and a <b>G</b> card specifying the root post for
560 the entire thread. The argument to G and <b>I</b> cards is the
561 artifact hash for the prior forum post to which the card refers.
562
563 In theory, it is sufficient for follow-up posts to have only an
564 <b>I</b> card, since the <b>G</b> card value could be computed by following a
565 chain of <b>I</b> cards. However, the <b>G</b> card is required in order to
566 associate the artifact with a forum thread in the case where an
567 intermediate artifact in the <b>I</b> card chain is shunned or otherwise
568 becomes unreadable.
569
570 A single <b>D</b> card is required to give the date and time when the
571 forum post was created.
572
573 The optional <b>N</b> card specifies the mimetype of the text of the technote
574 that is contained in the <b>W</b> card. If the <b>N</b> card is omitted, then the
575 <b>W</b> card text mimetype is assumed to be text/x-fossil-wiki, which is the
576 Fossil wiki format.
577
578 The optional <b>P</b> card specifies a prior forum post for which this
579 forum post is an edit. For display purposes, only the child post
580 is shown, though the historical post is retained as a record.
581 If <b>P</b> cards are used and there exist multiple versions of the same
582 forum post, then <b>I</b> cards for other artifacts refer to whichever
583 version of the post was current at the time the reply was made,
584 but <b>G</b> cards refer to the initial, unedited root post for the thread.
585 Thus, following the chain of <b>I</b> cards back to the root of the thread
586 may land on a different post than the one given in the <b>G</b> card.
587 However, following the chain of <b>I</b> cards back to the thread root,
588 then following <b>P</b> cards back to the initial version of the thread
589 root must give the same artifact as is provided by the <b>G</b> card,
590 otherwise the artifact containing the <b>G</b> card is considered invalid
591 and should be ignored.
592
593 In general, <b>P</b> cards may contain multiple arguments, indicating a
594 merge. But since forum posts cannot be merged, the
595 <b>P</b> card of a forum post may only contain a single argument.
596
597 The <b>U</b> card gives name of the user who entered the forum post.
598
599 A single <b>W</b> card provides wiki text for the forum post.
600 The format of the <b>W</b> card is exactly the same as for a
601 [#wikichng | wiki artifact].
602
603 The <b>Z</b> card is the required checksum over the rest of the artifact.
604
605
606 <a name="summary"></a>
607 <h2>3.0 Card Summary</h2>
608
@@ -868,11 +868,11 @@
868 implementing algorithms described above.
869
870 <h3>4.1 R-Card Hash Calculation</h3>
871
872 Given a manifest file named <tt>MF</tt>, the following Bash shell code
873 demonstrates how to compute the value of the <b>R</b> card in that manifest.
874 This example uses manifest [28987096ac]. Lines starting with <tt>#</tt> are
875 shell input and other lines are output. This demonstration assumes that the
876 file versions represented by the input manifest are checked out
877 under the current directory.
878
@@ -900,8 +900,8 @@
900 Minor caveats: the above demonstration will work only when none of the
901 filenames in the manifest are "fossilized" (encoded) because they contain
902 spaces. In that case the shell-generated hash would differ because the
903 <tt>stat</tt> calls will fail to find such files (which are output in encoded
904 form here). That approach also won't work for delta manifests. Calculating
905 the <b>R</b> card for delta manifests requires traversing both the delta and its baseline in
906 lexical order of the files, preferring the delta's copy if both contain
907 a given file.
908
909 DDED www/grep.md
--- a/www/grep.md
+++ b/www/grep.md
@@ -0,0 +1,3 @@
1
+# Fossil grep vs POSIX grep
2
+
3
+As of Fossil 2.7, there is a `grep` command which acts roughly likea
--- a/www/grep.md
+++ b/www/grep.md
@@ -0,0 +1,3 @@
 
 
 
--- a/www/grep.md
+++ b/www/grep.md
@@ -0,0 +1,3 @@
1 # Fossil grep vs POSIX grep
2
3 As of Fossil 2.7, there is a `grep` command which acts roughly likea
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -9,14 +9,16 @@
99
set doclist {
1010
aboutcgi.wiki {How CGI Works In Fossil}
1111
aboutdownload.wiki {How The Download Page Works}
1212
adding_code.wiki {Adding New Features To Fossil}
1313
adding_code.wiki {Hacking Fossil}
14
+ admin-v-setup.md {The Differences Between the Setup and Admin User Capabilities}
1415
alerts.md {Email Alerts And Notifications}
1516
antibot.wiki {Defense against Spiders and Bots}
1617
backoffice.md {The "Backoffice" mechanism of Fossil}
1718
blame.wiki {The Annotate/Blame Algorithm Of Fossil}
19
+ blockchain.md {Fossil As Blockchain}
1820
branching.wiki {Branching, Forking, Merging, and Tagging}
1921
bugtheory.wiki {Bug Tracking In Fossil}
2022
build.wiki {Compiling and Installing Fossil}
2123
changes.wiki {Fossil Changelog}
2224
checkin_names.wiki {Check-in And Version Names}
@@ -25,10 +27,11 @@
2527
copyright-release.html {Contributor License Agreement}
2628
concepts.wiki {Fossil Core Concepts}
2729
contribute.wiki {Contributing Code or Documentation To The Fossil Project}
2830
customgraph.md {Theming: Customizing the Timeline Graph}
2931
customskin.md {Theming: Customizing The Appearance of Web Pages}
32
+ customskin.md {Custom Skins}
3033
custom_ticket.wiki {Customizing The Ticket System}
3134
delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm}
3235
delta_format.wiki {Fossil Delta Format}
3336
embeddeddoc.wiki {Embedded Project Documentation}
3437
encryptedrepos.wiki {How To Use Encrypted Repositories}
@@ -40,10 +43,11 @@
4043
forum.wiki {Fossil Forums}
4144
foss-cklist.wiki {Checklist For Successful Open-Source Projects}
4245
fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
4346
fossil-v-git.wiki {Fossil Versus Git}
4447
globs.md {File Name Glob Patterns}
48
+ grep.md {Fossil grep vs POSIX grep}
4549
hacker-howto.wiki {Hacker How-To}
4650
hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
4751
/help {Lists of Commands and Webpages}
4852
hints.wiki {Fossil Tips And Usage Hints}
4953
index.wiki {Home Page}
5054
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -9,14 +9,16 @@
9 set doclist {
10 aboutcgi.wiki {How CGI Works In Fossil}
11 aboutdownload.wiki {How The Download Page Works}
12 adding_code.wiki {Adding New Features To Fossil}
13 adding_code.wiki {Hacking Fossil}
 
14 alerts.md {Email Alerts And Notifications}
15 antibot.wiki {Defense against Spiders and Bots}
16 backoffice.md {The "Backoffice" mechanism of Fossil}
17 blame.wiki {The Annotate/Blame Algorithm Of Fossil}
 
18 branching.wiki {Branching, Forking, Merging, and Tagging}
19 bugtheory.wiki {Bug Tracking In Fossil}
20 build.wiki {Compiling and Installing Fossil}
21 changes.wiki {Fossil Changelog}
22 checkin_names.wiki {Check-in And Version Names}
@@ -25,10 +27,11 @@
25 copyright-release.html {Contributor License Agreement}
26 concepts.wiki {Fossil Core Concepts}
27 contribute.wiki {Contributing Code or Documentation To The Fossil Project}
28 customgraph.md {Theming: Customizing the Timeline Graph}
29 customskin.md {Theming: Customizing The Appearance of Web Pages}
 
30 custom_ticket.wiki {Customizing The Ticket System}
31 delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm}
32 delta_format.wiki {Fossil Delta Format}
33 embeddeddoc.wiki {Embedded Project Documentation}
34 encryptedrepos.wiki {How To Use Encrypted Repositories}
@@ -40,10 +43,11 @@
40 forum.wiki {Fossil Forums}
41 foss-cklist.wiki {Checklist For Successful Open-Source Projects}
42 fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
43 fossil-v-git.wiki {Fossil Versus Git}
44 globs.md {File Name Glob Patterns}
 
45 hacker-howto.wiki {Hacker How-To}
46 hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
47 /help {Lists of Commands and Webpages}
48 hints.wiki {Fossil Tips And Usage Hints}
49 index.wiki {Home Page}
50
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -9,14 +9,16 @@
9 set doclist {
10 aboutcgi.wiki {How CGI Works In Fossil}
11 aboutdownload.wiki {How The Download Page Works}
12 adding_code.wiki {Adding New Features To Fossil}
13 adding_code.wiki {Hacking Fossil}
14 admin-v-setup.md {The Differences Between the Setup and Admin User Capabilities}
15 alerts.md {Email Alerts And Notifications}
16 antibot.wiki {Defense against Spiders and Bots}
17 backoffice.md {The "Backoffice" mechanism of Fossil}
18 blame.wiki {The Annotate/Blame Algorithm Of Fossil}
19 blockchain.md {Fossil As Blockchain}
20 branching.wiki {Branching, Forking, Merging, and Tagging}
21 bugtheory.wiki {Bug Tracking In Fossil}
22 build.wiki {Compiling and Installing Fossil}
23 changes.wiki {Fossil Changelog}
24 checkin_names.wiki {Check-in And Version Names}
@@ -25,10 +27,11 @@
27 copyright-release.html {Contributor License Agreement}
28 concepts.wiki {Fossil Core Concepts}
29 contribute.wiki {Contributing Code or Documentation To The Fossil Project}
30 customgraph.md {Theming: Customizing the Timeline Graph}
31 customskin.md {Theming: Customizing The Appearance of Web Pages}
32 customskin.md {Custom Skins}
33 custom_ticket.wiki {Customizing The Ticket System}
34 delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm}
35 delta_format.wiki {Fossil Delta Format}
36 embeddeddoc.wiki {Embedded Project Documentation}
37 encryptedrepos.wiki {How To Use Encrypted Repositories}
@@ -40,10 +43,11 @@
43 forum.wiki {Fossil Forums}
44 foss-cklist.wiki {Checklist For Successful Open-Source Projects}
45 fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
46 fossil-v-git.wiki {Fossil Versus Git}
47 globs.md {File Name Glob Patterns}
48 grep.md {Fossil grep vs POSIX grep}
49 hacker-howto.wiki {Hacker How-To}
50 hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
51 /help {Lists of Commands and Webpages}
52 hints.wiki {Fossil Tips And Usage Hints}
53 index.wiki {Home Page}
54
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -22,10 +22,11 @@
2222
<ul>
2323
<li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Up and Running in</a></li>
2424
<li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
2525
<li><a href="tech_overview.wiki"><b>A Technical Overview Of The Design And Implementation Of Fossil</b></a></li>
2626
<li><a href="adding_code.wiki"><b>Adding New Features To Fossil</b></a></li>
27
+<li><a href="admin-v-setup.md">Admin User Capabilities &mdash; The Differences Between the Setup and</a></li>
2728
<li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
2829
<li><a href="alerts.md">Alerts And Notifications &mdash; Email</a></li>
2930
<li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
3031
<li><a href="blame.wiki">Algorithm Of Fossil &mdash; The Annotate/Blame</a></li>
3132
<li><a href="blame.wiki">Annotate/Blame Algorithm Of Fossil &mdash; The</a></li>
@@ -33,15 +34,18 @@
3334
<li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
3435
<li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
3536
<li><a href="backoffice.md">Backoffice mechanism of Fossil &mdash; The</a></li>
3637
<li><a href="whyusefossil.wiki"><b>Benefits Of Version Control</b></a></li>
3738
<li><a href="hashpolicy.wiki">Between SHA1 and SHA3-256 &mdash; Hash Policy: Choosing</a></li>
39
+<li><a href="admin-v-setup.md">Between the Setup and Admin User Capabilities &mdash; The Differences</a></li>
40
+<li><a href="blockchain.md">Blockchain &mdash; Fossil As</a></li>
3841
<li><a href="antibot.wiki">Bots &mdash; Defense against Spiders and</a></li>
3942
<li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
4043
<li><a href="branching.wiki"><b>Branching, Forking, Merging, and Tagging</b></a></li>
4144
<li><a href="bugtheory.wiki"><b>Bug Tracking In Fossil</b></a></li>
4245
<li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>
46
+<li><a href="admin-v-setup.md">Capabilities &mdash; The Differences Between the Setup and Admin User</a></li>
4347
<li><a href="aboutcgi.wiki">CGI Works In Fossil &mdash; How</a></li>
4448
<li><a href="changes.wiki">Changelog &mdash; Fossil</a></li>
4549
<li><a href="checkin_names.wiki"><b>Check-in And Version Names</b></a></li>
4650
<li><a href="checkin.wiki"><b>Check-in Checklist</b></a></li>
4751
<li><a href="checkin.wiki">Checklist &mdash; Check-in</a></li>
@@ -62,10 +66,11 @@
6266
<li><a href="whyusefossil.wiki">Control &mdash; Benefits Of Version</a></li>
6367
<li><a href="concepts.wiki">Core Concepts &mdash; Fossil</a></li>
6468
<li><a href="newrepo.wiki">Create A New Fossil Repository &mdash; How To</a></li>
6569
<li><a href="private.wiki"><b>Creating, Syncing, and Deleting Private Branches</b></a></li>
6670
<li><a href="qandc.wiki">Criticisms &mdash; Questions And</a></li>
71
+<li><a href="customskin.md"><b>Custom Skins</b></a></li>
6772
<li><a href="customskin.md">Customizing The Appearance of Web Pages &mdash; Theming:</a></li>
6873
<li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li>
6974
<li><a href="customgraph.md">Customizing the Timeline Graph &mdash; Theming:</a></li>
7075
<li><a href="tech_overview.wiki">Databases Used By Fossil &mdash; SQLite</a></li>
7176
<li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li>
@@ -73,10 +78,11 @@
7378
<li><a href="private.wiki">Deleting Private Branches &mdash; Creating, Syncing, and</a></li>
7479
<li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm &mdash; Fossil</a></li>
7580
<li><a href="delta_format.wiki">Delta Format &mdash; Fossil</a></li>
7681
<li><a href="tech_overview.wiki">Design And Implementation Of Fossil &mdash; A Technical Overview Of The</a></li>
7782
<li><a href="theory1.wiki">Design Of The Fossil DVCS &mdash; Thoughts On The</a></li>
83
+<li><a href="admin-v-setup.md">Differences Between the Setup and Admin User Capabilities &mdash; The</a></li>
7884
<li><a href="embeddeddoc.wiki">Documentation &mdash; Embedded Project</a></li>
7985
<li><a href="contribute.wiki">Documentation To The Fossil Project &mdash; Contributing Code or</a></li>
8086
<li><a href="aboutdownload.wiki">Download Page Works &mdash; How The</a></li>
8187
<li><a href="theory1.wiki">DVCS &mdash; Thoughts On The Design Of The Fossil</a></li>
8288
<li><a href="quotes.wiki">DVCSes in General &mdash; Quotes: What People Are Saying About Fossil, Git, and</a></li>
@@ -97,16 +103,18 @@
97103
<li><a href="delta_format.wiki">Format &mdash; Fossil Delta</a></li>
98104
<li><a href="fileformat.wiki">Format &mdash; Fossil File</a></li>
99105
<li><a href="../../../md_rules">Formatting Rules &mdash; Markdown</a></li>
100106
<li><a href="../../../wiki_rules">Formatting Rules &mdash; Wiki</a></li>
101107
<li><a href="forum.wiki">Forums &mdash; Fossil</a></li>
108
+<li><a href="blockchain.md"><b>Fossil As Blockchain</b></a></li>
102109
<li><a href="changes.wiki"><b>Fossil Changelog</b></a></li>
103110
<li><a href="concepts.wiki"><b>Fossil Core Concepts</b></a></li>
104111
<li><a href="delta_encoder_algorithm.wiki"><b>Fossil Delta Encoding Algorithm</b></a></li>
105112
<li><a href="delta_format.wiki"><b>Fossil Delta Format</b></a></li>
106113
<li><a href="fileformat.wiki"><b>Fossil File Format</b></a></li>
107114
<li><a href="forum.wiki"><b>Fossil Forums</b></a></li>
115
+<li><a href="grep.md"><b>Fossil grep vs POSIX grep</b></a></li>
108116
<li><a href="quickstart.wiki"><b>Fossil Quick Start Guide</b></a></li>
109117
<li><a href="selfcheck.wiki"><b>Fossil Repository Integrity Self Checks</b></a></li>
110118
<li><a href="selfhost.wiki"><b>Fossil Self Hosting Repositories</b></a></li>
111119
<li><a href="settings.wiki"><b>Fossil Settings</b></a></li>
112120
<li><a href="hints.wiki"><b>Fossil Tips And Usage Hints</b></a></li>
@@ -118,10 +126,12 @@
118126
<li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
119127
<li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
120128
<li><a href="globs.md">Glob Patterns &mdash; File Name</a></li>
121129
<li><a href="env-opts.md">Global Options &mdash; Environment Variables and</a></li>
122130
<li><a href="customgraph.md">Graph &mdash; Theming: Customizing the Timeline</a></li>
131
+<li><a href="grep.md">grep &mdash; Fossil grep vs POSIX</a></li>
132
+<li><a href="grep.md">grep vs POSIX grep &mdash; Fossil</a></li>
123133
<li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
124134
<li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>
125135
<li><a href="hacker-howto.wiki"><b>Hacker How-To</b></a></li>
126136
<li><a href="adding_code.wiki"><b>Hacking Fossil</b></a></li>
127137
<li><a href="hashpolicy.wiki"><b>Hash Policy: Choosing Between SHA1 and SHA3-256</b></a></li>
@@ -166,10 +176,11 @@
166176
<li><a href="password.wiki"><b>Password Management And Authentication</b></a></li>
167177
<li><a href="globs.md">Patterns &mdash; File Name Glob</a></li>
168178
<li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General &mdash; Quotes: What</a></li>
169179
<li><a href="stats.wiki"><b>Performance Statistics</b></a></li>
170180
<li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 &mdash; Hash</a></li>
181
+<li><a href="grep.md">POSIX grep &mdash; Fossil grep vs</a></li>
171182
<li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li>
172183
<li><a href="pop.wiki"><b>Principles Of Operation</b></a></li>
173184
<li><a href="private.wiki">Private Branches &mdash; Creating, Syncing, and Deleting</a></li>
174185
<li><a href="makefile.wiki">Process &mdash; The Fossil Build</a></li>
175186
<li><a href="contribute.wiki">Project &mdash; Contributing Code or Documentation To The Fossil</a></li>
@@ -193,15 +204,17 @@
193204
<li><a href="th1.md">Scripting Language &mdash; The TH1</a></li>
194205
<li><a href="selfcheck.wiki">Self Checks &mdash; Fossil Repository Integrity</a></li>
195206
<li><a href="selfhost.wiki">Self Hosting Repositories &mdash; Fossil</a></li>
196207
<li><a href="server.wiki">Server &mdash; How To Configure A Fossil</a></li>
197208
<li><a href="settings.wiki">Settings &mdash; Fossil</a></li>
209
+<li><a href="admin-v-setup.md">Setup and Admin User Capabilities &mdash; The Differences Between the</a></li>
198210
<li><a href="hashpolicy.wiki">SHA1 and SHA3-256 &mdash; Hash Policy: Choosing Between</a></li>
199211
<li><a href="hashpolicy.wiki">SHA3-256 &mdash; Hash Policy: Choosing Between SHA1 and</a></li>
200212
<li><a href="shunning.wiki"><b>Shunning: Deleting Content From Fossil</b></a></li>
201213
<li><a href="fiveminutes.wiki">Single User &mdash; Up and Running in 5 Minutes as a</a></li>
202214
<li><a href="../../../sitemap"><b>Site Map</b></a></li>
215
+<li><a href="customskin.md">Skins &mdash; Custom</a></li>
203216
<li><a href="style.wiki"><b>Source Code Style Guidelines</b></a></li>
204217
<li><a href="antibot.wiki">Spiders and Bots &mdash; Defense against</a></li>
205218
<li><a href="tech_overview.wiki"><b>SQLite Databases Used By Fossil</b></a></li>
206219
<li><a href="ssl.wiki">SSL with Fossil &mdash; Using</a></li>
207220
<li><a href="quickstart.wiki">Start Guide &mdash; Fossil Quick</a></li>
@@ -216,10 +229,11 @@
216229
<li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &mdash; A</a></li>
217230
<li><a href="../test/release-checklist.wiki">Testing Checklist &mdash; Pre-Release</a></li>
218231
<li><a href="th1.md">TH1 Scripting Language &mdash; The</a></li>
219232
<li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li>
220233
<li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li>
234
+<li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li>
221235
<li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li>
222236
<li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li>
223237
<li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li>
224238
<li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li>
225239
<li><a href="th1.md"><b>The TH1 Scripting Language</b></a></li>
@@ -233,15 +247,17 @@
233247
<li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
234248
<li><a href="unvers.wiki"><b>Unversioned Files</b></a></li>
235249
<li><a href="fiveminutes.wiki"><b>Up and Running in 5 Minutes as a Single User</b></a></li>
236250
<li><a href="hints.wiki">Usage Hints &mdash; Fossil Tips And</a></li>
237251
<li><a href="fiveminutes.wiki">User &mdash; Up and Running in 5 Minutes as a Single</a></li>
252
+<li><a href="admin-v-setup.md">User Capabilities &mdash; The Differences Between the Setup and Admin</a></li>
238253
<li><a href="ssl.wiki"><b>Using SSL with Fossil</b></a></li>
239254
<li><a href="env-opts.md">Variables and Global Options &mdash; Environment</a></li>
240255
<li><a href="whyusefossil.wiki">Version Control &mdash; Benefits Of</a></li>
241256
<li><a href="checkin_names.wiki">Version Names &mdash; Check-in And</a></li>
242257
<li><a href="fossil-v-git.wiki">Versus Git &mdash; Fossil</a></li>
258
+<li><a href="grep.md">vs POSIX grep &mdash; Fossil grep</a></li>
243259
<li><a href="webui.wiki">Web Interface &mdash; The Fossil</a></li>
244260
<li><a href="customskin.md">Web Pages &mdash; Theming: Customizing The Appearance of</a></li>
245261
<li><a href="webpage-ex.md"><b>Webpage Examples</b></a></li>
246262
<li><a href="../../../help">Webpages &mdash; Lists of Commands and</a></li>
247263
<li><a href="quotes.wiki">What People Are Saying About Fossil, Git, and DVCSes in General &mdash; Quotes:</a></li>
248264
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -22,10 +22,11 @@
22 <ul>
23 <li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Up and Running in</a></li>
24 <li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
25 <li><a href="tech_overview.wiki"><b>A Technical Overview Of The Design And Implementation Of Fossil</b></a></li>
26 <li><a href="adding_code.wiki"><b>Adding New Features To Fossil</b></a></li>
 
27 <li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
28 <li><a href="alerts.md">Alerts And Notifications &mdash; Email</a></li>
29 <li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
30 <li><a href="blame.wiki">Algorithm Of Fossil &mdash; The Annotate/Blame</a></li>
31 <li><a href="blame.wiki">Annotate/Blame Algorithm Of Fossil &mdash; The</a></li>
@@ -33,15 +34,18 @@
33 <li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
34 <li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
35 <li><a href="backoffice.md">Backoffice mechanism of Fossil &mdash; The</a></li>
36 <li><a href="whyusefossil.wiki"><b>Benefits Of Version Control</b></a></li>
37 <li><a href="hashpolicy.wiki">Between SHA1 and SHA3-256 &mdash; Hash Policy: Choosing</a></li>
 
 
38 <li><a href="antibot.wiki">Bots &mdash; Defense against Spiders and</a></li>
39 <li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
40 <li><a href="branching.wiki"><b>Branching, Forking, Merging, and Tagging</b></a></li>
41 <li><a href="bugtheory.wiki"><b>Bug Tracking In Fossil</b></a></li>
42 <li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>
 
43 <li><a href="aboutcgi.wiki">CGI Works In Fossil &mdash; How</a></li>
44 <li><a href="changes.wiki">Changelog &mdash; Fossil</a></li>
45 <li><a href="checkin_names.wiki"><b>Check-in And Version Names</b></a></li>
46 <li><a href="checkin.wiki"><b>Check-in Checklist</b></a></li>
47 <li><a href="checkin.wiki">Checklist &mdash; Check-in</a></li>
@@ -62,10 +66,11 @@
62 <li><a href="whyusefossil.wiki">Control &mdash; Benefits Of Version</a></li>
63 <li><a href="concepts.wiki">Core Concepts &mdash; Fossil</a></li>
64 <li><a href="newrepo.wiki">Create A New Fossil Repository &mdash; How To</a></li>
65 <li><a href="private.wiki"><b>Creating, Syncing, and Deleting Private Branches</b></a></li>
66 <li><a href="qandc.wiki">Criticisms &mdash; Questions And</a></li>
 
67 <li><a href="customskin.md">Customizing The Appearance of Web Pages &mdash; Theming:</a></li>
68 <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li>
69 <li><a href="customgraph.md">Customizing the Timeline Graph &mdash; Theming:</a></li>
70 <li><a href="tech_overview.wiki">Databases Used By Fossil &mdash; SQLite</a></li>
71 <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li>
@@ -73,10 +78,11 @@
73 <li><a href="private.wiki">Deleting Private Branches &mdash; Creating, Syncing, and</a></li>
74 <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm &mdash; Fossil</a></li>
75 <li><a href="delta_format.wiki">Delta Format &mdash; Fossil</a></li>
76 <li><a href="tech_overview.wiki">Design And Implementation Of Fossil &mdash; A Technical Overview Of The</a></li>
77 <li><a href="theory1.wiki">Design Of The Fossil DVCS &mdash; Thoughts On The</a></li>
 
78 <li><a href="embeddeddoc.wiki">Documentation &mdash; Embedded Project</a></li>
79 <li><a href="contribute.wiki">Documentation To The Fossil Project &mdash; Contributing Code or</a></li>
80 <li><a href="aboutdownload.wiki">Download Page Works &mdash; How The</a></li>
81 <li><a href="theory1.wiki">DVCS &mdash; Thoughts On The Design Of The Fossil</a></li>
82 <li><a href="quotes.wiki">DVCSes in General &mdash; Quotes: What People Are Saying About Fossil, Git, and</a></li>
@@ -97,16 +103,18 @@
97 <li><a href="delta_format.wiki">Format &mdash; Fossil Delta</a></li>
98 <li><a href="fileformat.wiki">Format &mdash; Fossil File</a></li>
99 <li><a href="../../../md_rules">Formatting Rules &mdash; Markdown</a></li>
100 <li><a href="../../../wiki_rules">Formatting Rules &mdash; Wiki</a></li>
101 <li><a href="forum.wiki">Forums &mdash; Fossil</a></li>
 
102 <li><a href="changes.wiki"><b>Fossil Changelog</b></a></li>
103 <li><a href="concepts.wiki"><b>Fossil Core Concepts</b></a></li>
104 <li><a href="delta_encoder_algorithm.wiki"><b>Fossil Delta Encoding Algorithm</b></a></li>
105 <li><a href="delta_format.wiki"><b>Fossil Delta Format</b></a></li>
106 <li><a href="fileformat.wiki"><b>Fossil File Format</b></a></li>
107 <li><a href="forum.wiki"><b>Fossil Forums</b></a></li>
 
108 <li><a href="quickstart.wiki"><b>Fossil Quick Start Guide</b></a></li>
109 <li><a href="selfcheck.wiki"><b>Fossil Repository Integrity Self Checks</b></a></li>
110 <li><a href="selfhost.wiki"><b>Fossil Self Hosting Repositories</b></a></li>
111 <li><a href="settings.wiki"><b>Fossil Settings</b></a></li>
112 <li><a href="hints.wiki"><b>Fossil Tips And Usage Hints</b></a></li>
@@ -118,10 +126,12 @@
118 <li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
119 <li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
120 <li><a href="globs.md">Glob Patterns &mdash; File Name</a></li>
121 <li><a href="env-opts.md">Global Options &mdash; Environment Variables and</a></li>
122 <li><a href="customgraph.md">Graph &mdash; Theming: Customizing the Timeline</a></li>
 
 
123 <li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
124 <li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>
125 <li><a href="hacker-howto.wiki"><b>Hacker How-To</b></a></li>
126 <li><a href="adding_code.wiki"><b>Hacking Fossil</b></a></li>
127 <li><a href="hashpolicy.wiki"><b>Hash Policy: Choosing Between SHA1 and SHA3-256</b></a></li>
@@ -166,10 +176,11 @@
166 <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li>
167 <li><a href="globs.md">Patterns &mdash; File Name Glob</a></li>
168 <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General &mdash; Quotes: What</a></li>
169 <li><a href="stats.wiki"><b>Performance Statistics</b></a></li>
170 <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 &mdash; Hash</a></li>
 
171 <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li>
172 <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li>
173 <li><a href="private.wiki">Private Branches &mdash; Creating, Syncing, and Deleting</a></li>
174 <li><a href="makefile.wiki">Process &mdash; The Fossil Build</a></li>
175 <li><a href="contribute.wiki">Project &mdash; Contributing Code or Documentation To The Fossil</a></li>
@@ -193,15 +204,17 @@
193 <li><a href="th1.md">Scripting Language &mdash; The TH1</a></li>
194 <li><a href="selfcheck.wiki">Self Checks &mdash; Fossil Repository Integrity</a></li>
195 <li><a href="selfhost.wiki">Self Hosting Repositories &mdash; Fossil</a></li>
196 <li><a href="server.wiki">Server &mdash; How To Configure A Fossil</a></li>
197 <li><a href="settings.wiki">Settings &mdash; Fossil</a></li>
 
198 <li><a href="hashpolicy.wiki">SHA1 and SHA3-256 &mdash; Hash Policy: Choosing Between</a></li>
199 <li><a href="hashpolicy.wiki">SHA3-256 &mdash; Hash Policy: Choosing Between SHA1 and</a></li>
200 <li><a href="shunning.wiki"><b>Shunning: Deleting Content From Fossil</b></a></li>
201 <li><a href="fiveminutes.wiki">Single User &mdash; Up and Running in 5 Minutes as a</a></li>
202 <li><a href="../../../sitemap"><b>Site Map</b></a></li>
 
203 <li><a href="style.wiki"><b>Source Code Style Guidelines</b></a></li>
204 <li><a href="antibot.wiki">Spiders and Bots &mdash; Defense against</a></li>
205 <li><a href="tech_overview.wiki"><b>SQLite Databases Used By Fossil</b></a></li>
206 <li><a href="ssl.wiki">SSL with Fossil &mdash; Using</a></li>
207 <li><a href="quickstart.wiki">Start Guide &mdash; Fossil Quick</a></li>
@@ -216,10 +229,11 @@
216 <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &mdash; A</a></li>
217 <li><a href="../test/release-checklist.wiki">Testing Checklist &mdash; Pre-Release</a></li>
218 <li><a href="th1.md">TH1 Scripting Language &mdash; The</a></li>
219 <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li>
220 <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li>
 
221 <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li>
222 <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li>
223 <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li>
224 <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li>
225 <li><a href="th1.md"><b>The TH1 Scripting Language</b></a></li>
@@ -233,15 +247,17 @@
233 <li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
234 <li><a href="unvers.wiki"><b>Unversioned Files</b></a></li>
235 <li><a href="fiveminutes.wiki"><b>Up and Running in 5 Minutes as a Single User</b></a></li>
236 <li><a href="hints.wiki">Usage Hints &mdash; Fossil Tips And</a></li>
237 <li><a href="fiveminutes.wiki">User &mdash; Up and Running in 5 Minutes as a Single</a></li>
 
238 <li><a href="ssl.wiki"><b>Using SSL with Fossil</b></a></li>
239 <li><a href="env-opts.md">Variables and Global Options &mdash; Environment</a></li>
240 <li><a href="whyusefossil.wiki">Version Control &mdash; Benefits Of</a></li>
241 <li><a href="checkin_names.wiki">Version Names &mdash; Check-in And</a></li>
242 <li><a href="fossil-v-git.wiki">Versus Git &mdash; Fossil</a></li>
 
243 <li><a href="webui.wiki">Web Interface &mdash; The Fossil</a></li>
244 <li><a href="customskin.md">Web Pages &mdash; Theming: Customizing The Appearance of</a></li>
245 <li><a href="webpage-ex.md"><b>Webpage Examples</b></a></li>
246 <li><a href="../../../help">Webpages &mdash; Lists of Commands and</a></li>
247 <li><a href="quotes.wiki">What People Are Saying About Fossil, Git, and DVCSes in General &mdash; Quotes:</a></li>
248
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -22,10 +22,11 @@
22 <ul>
23 <li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Up and Running in</a></li>
24 <li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
25 <li><a href="tech_overview.wiki"><b>A Technical Overview Of The Design And Implementation Of Fossil</b></a></li>
26 <li><a href="adding_code.wiki"><b>Adding New Features To Fossil</b></a></li>
27 <li><a href="admin-v-setup.md">Admin User Capabilities &mdash; The Differences Between the Setup and</a></li>
28 <li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
29 <li><a href="alerts.md">Alerts And Notifications &mdash; Email</a></li>
30 <li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
31 <li><a href="blame.wiki">Algorithm Of Fossil &mdash; The Annotate/Blame</a></li>
32 <li><a href="blame.wiki">Annotate/Blame Algorithm Of Fossil &mdash; The</a></li>
@@ -33,15 +34,18 @@
34 <li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
35 <li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
36 <li><a href="backoffice.md">Backoffice mechanism of Fossil &mdash; The</a></li>
37 <li><a href="whyusefossil.wiki"><b>Benefits Of Version Control</b></a></li>
38 <li><a href="hashpolicy.wiki">Between SHA1 and SHA3-256 &mdash; Hash Policy: Choosing</a></li>
39 <li><a href="admin-v-setup.md">Between the Setup and Admin User Capabilities &mdash; The Differences</a></li>
40 <li><a href="blockchain.md">Blockchain &mdash; Fossil As</a></li>
41 <li><a href="antibot.wiki">Bots &mdash; Defense against Spiders and</a></li>
42 <li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
43 <li><a href="branching.wiki"><b>Branching, Forking, Merging, and Tagging</b></a></li>
44 <li><a href="bugtheory.wiki"><b>Bug Tracking In Fossil</b></a></li>
45 <li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>
46 <li><a href="admin-v-setup.md">Capabilities &mdash; The Differences Between the Setup and Admin User</a></li>
47 <li><a href="aboutcgi.wiki">CGI Works In Fossil &mdash; How</a></li>
48 <li><a href="changes.wiki">Changelog &mdash; Fossil</a></li>
49 <li><a href="checkin_names.wiki"><b>Check-in And Version Names</b></a></li>
50 <li><a href="checkin.wiki"><b>Check-in Checklist</b></a></li>
51 <li><a href="checkin.wiki">Checklist &mdash; Check-in</a></li>
@@ -62,10 +66,11 @@
66 <li><a href="whyusefossil.wiki">Control &mdash; Benefits Of Version</a></li>
67 <li><a href="concepts.wiki">Core Concepts &mdash; Fossil</a></li>
68 <li><a href="newrepo.wiki">Create A New Fossil Repository &mdash; How To</a></li>
69 <li><a href="private.wiki"><b>Creating, Syncing, and Deleting Private Branches</b></a></li>
70 <li><a href="qandc.wiki">Criticisms &mdash; Questions And</a></li>
71 <li><a href="customskin.md"><b>Custom Skins</b></a></li>
72 <li><a href="customskin.md">Customizing The Appearance of Web Pages &mdash; Theming:</a></li>
73 <li><a href="custom_ticket.wiki"><b>Customizing The Ticket System</b></a></li>
74 <li><a href="customgraph.md">Customizing the Timeline Graph &mdash; Theming:</a></li>
75 <li><a href="tech_overview.wiki">Databases Used By Fossil &mdash; SQLite</a></li>
76 <li><a href="antibot.wiki"><b>Defense against Spiders and Bots</b></a></li>
@@ -73,10 +78,11 @@
78 <li><a href="private.wiki">Deleting Private Branches &mdash; Creating, Syncing, and</a></li>
79 <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm &mdash; Fossil</a></li>
80 <li><a href="delta_format.wiki">Delta Format &mdash; Fossil</a></li>
81 <li><a href="tech_overview.wiki">Design And Implementation Of Fossil &mdash; A Technical Overview Of The</a></li>
82 <li><a href="theory1.wiki">Design Of The Fossil DVCS &mdash; Thoughts On The</a></li>
83 <li><a href="admin-v-setup.md">Differences Between the Setup and Admin User Capabilities &mdash; The</a></li>
84 <li><a href="embeddeddoc.wiki">Documentation &mdash; Embedded Project</a></li>
85 <li><a href="contribute.wiki">Documentation To The Fossil Project &mdash; Contributing Code or</a></li>
86 <li><a href="aboutdownload.wiki">Download Page Works &mdash; How The</a></li>
87 <li><a href="theory1.wiki">DVCS &mdash; Thoughts On The Design Of The Fossil</a></li>
88 <li><a href="quotes.wiki">DVCSes in General &mdash; Quotes: What People Are Saying About Fossil, Git, and</a></li>
@@ -97,16 +103,18 @@
103 <li><a href="delta_format.wiki">Format &mdash; Fossil Delta</a></li>
104 <li><a href="fileformat.wiki">Format &mdash; Fossil File</a></li>
105 <li><a href="../../../md_rules">Formatting Rules &mdash; Markdown</a></li>
106 <li><a href="../../../wiki_rules">Formatting Rules &mdash; Wiki</a></li>
107 <li><a href="forum.wiki">Forums &mdash; Fossil</a></li>
108 <li><a href="blockchain.md"><b>Fossil As Blockchain</b></a></li>
109 <li><a href="changes.wiki"><b>Fossil Changelog</b></a></li>
110 <li><a href="concepts.wiki"><b>Fossil Core Concepts</b></a></li>
111 <li><a href="delta_encoder_algorithm.wiki"><b>Fossil Delta Encoding Algorithm</b></a></li>
112 <li><a href="delta_format.wiki"><b>Fossil Delta Format</b></a></li>
113 <li><a href="fileformat.wiki"><b>Fossil File Format</b></a></li>
114 <li><a href="forum.wiki"><b>Fossil Forums</b></a></li>
115 <li><a href="grep.md"><b>Fossil grep vs POSIX grep</b></a></li>
116 <li><a href="quickstart.wiki"><b>Fossil Quick Start Guide</b></a></li>
117 <li><a href="selfcheck.wiki"><b>Fossil Repository Integrity Self Checks</b></a></li>
118 <li><a href="selfhost.wiki"><b>Fossil Self Hosting Repositories</b></a></li>
119 <li><a href="settings.wiki"><b>Fossil Settings</b></a></li>
120 <li><a href="hints.wiki"><b>Fossil Tips And Usage Hints</b></a></li>
@@ -118,10 +126,12 @@
126 <li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
127 <li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
128 <li><a href="globs.md">Glob Patterns &mdash; File Name</a></li>
129 <li><a href="env-opts.md">Global Options &mdash; Environment Variables and</a></li>
130 <li><a href="customgraph.md">Graph &mdash; Theming: Customizing the Timeline</a></li>
131 <li><a href="grep.md">grep &mdash; Fossil grep vs POSIX</a></li>
132 <li><a href="grep.md">grep vs POSIX grep &mdash; Fossil</a></li>
133 <li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
134 <li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>
135 <li><a href="hacker-howto.wiki"><b>Hacker How-To</b></a></li>
136 <li><a href="adding_code.wiki"><b>Hacking Fossil</b></a></li>
137 <li><a href="hashpolicy.wiki"><b>Hash Policy: Choosing Between SHA1 and SHA3-256</b></a></li>
@@ -166,10 +176,11 @@
176 <li><a href="password.wiki"><b>Password Management And Authentication</b></a></li>
177 <li><a href="globs.md">Patterns &mdash; File Name Glob</a></li>
178 <li><a href="quotes.wiki">People Are Saying About Fossil, Git, and DVCSes in General &mdash; Quotes: What</a></li>
179 <li><a href="stats.wiki"><b>Performance Statistics</b></a></li>
180 <li><a href="hashpolicy.wiki">Policy: Choosing Between SHA1 and SHA3-256 &mdash; Hash</a></li>
181 <li><a href="grep.md">POSIX grep &mdash; Fossil grep vs</a></li>
182 <li><a href="../test/release-checklist.wiki"><b>Pre-Release Testing Checklist</b></a></li>
183 <li><a href="pop.wiki"><b>Principles Of Operation</b></a></li>
184 <li><a href="private.wiki">Private Branches &mdash; Creating, Syncing, and Deleting</a></li>
185 <li><a href="makefile.wiki">Process &mdash; The Fossil Build</a></li>
186 <li><a href="contribute.wiki">Project &mdash; Contributing Code or Documentation To The Fossil</a></li>
@@ -193,15 +204,17 @@
204 <li><a href="th1.md">Scripting Language &mdash; The TH1</a></li>
205 <li><a href="selfcheck.wiki">Self Checks &mdash; Fossil Repository Integrity</a></li>
206 <li><a href="selfhost.wiki">Self Hosting Repositories &mdash; Fossil</a></li>
207 <li><a href="server.wiki">Server &mdash; How To Configure A Fossil</a></li>
208 <li><a href="settings.wiki">Settings &mdash; Fossil</a></li>
209 <li><a href="admin-v-setup.md">Setup and Admin User Capabilities &mdash; The Differences Between the</a></li>
210 <li><a href="hashpolicy.wiki">SHA1 and SHA3-256 &mdash; Hash Policy: Choosing Between</a></li>
211 <li><a href="hashpolicy.wiki">SHA3-256 &mdash; Hash Policy: Choosing Between SHA1 and</a></li>
212 <li><a href="shunning.wiki"><b>Shunning: Deleting Content From Fossil</b></a></li>
213 <li><a href="fiveminutes.wiki">Single User &mdash; Up and Running in 5 Minutes as a</a></li>
214 <li><a href="../../../sitemap"><b>Site Map</b></a></li>
215 <li><a href="customskin.md">Skins &mdash; Custom</a></li>
216 <li><a href="style.wiki"><b>Source Code Style Guidelines</b></a></li>
217 <li><a href="antibot.wiki">Spiders and Bots &mdash; Defense against</a></li>
218 <li><a href="tech_overview.wiki"><b>SQLite Databases Used By Fossil</b></a></li>
219 <li><a href="ssl.wiki">SSL with Fossil &mdash; Using</a></li>
220 <li><a href="quickstart.wiki">Start Guide &mdash; Fossil Quick</a></li>
@@ -216,10 +229,11 @@
229 <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &mdash; A</a></li>
230 <li><a href="../test/release-checklist.wiki">Testing Checklist &mdash; Pre-Release</a></li>
231 <li><a href="th1.md">TH1 Scripting Language &mdash; The</a></li>
232 <li><a href="backoffice.md"><b>The "Backoffice" mechanism of Fossil</b></a></li>
233 <li><a href="blame.wiki"><b>The Annotate/Blame Algorithm Of Fossil</b></a></li>
234 <li><a href="admin-v-setup.md"><b>The Differences Between the Setup and Admin User Capabilities</b></a></li>
235 <li><a href="makefile.wiki"><b>The Fossil Build Process</b></a></li>
236 <li><a href="sync.wiki"><b>The Fossil Sync Protocol</b></a></li>
237 <li><a href="tickets.wiki"><b>The Fossil Ticket System</b></a></li>
238 <li><a href="webui.wiki"><b>The Fossil Web Interface</b></a></li>
239 <li><a href="th1.md"><b>The TH1 Scripting Language</b></a></li>
@@ -233,15 +247,17 @@
247 <li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
248 <li><a href="unvers.wiki"><b>Unversioned Files</b></a></li>
249 <li><a href="fiveminutes.wiki"><b>Up and Running in 5 Minutes as a Single User</b></a></li>
250 <li><a href="hints.wiki">Usage Hints &mdash; Fossil Tips And</a></li>
251 <li><a href="fiveminutes.wiki">User &mdash; Up and Running in 5 Minutes as a Single</a></li>
252 <li><a href="admin-v-setup.md">User Capabilities &mdash; The Differences Between the Setup and Admin</a></li>
253 <li><a href="ssl.wiki"><b>Using SSL with Fossil</b></a></li>
254 <li><a href="env-opts.md">Variables and Global Options &mdash; Environment</a></li>
255 <li><a href="whyusefossil.wiki">Version Control &mdash; Benefits Of</a></li>
256 <li><a href="checkin_names.wiki">Version Names &mdash; Check-in And</a></li>
257 <li><a href="fossil-v-git.wiki">Versus Git &mdash; Fossil</a></li>
258 <li><a href="grep.md">vs POSIX grep &mdash; Fossil grep</a></li>
259 <li><a href="webui.wiki">Web Interface &mdash; The Fossil</a></li>
260 <li><a href="customskin.md">Web Pages &mdash; Theming: Customizing The Appearance of</a></li>
261 <li><a href="webpage-ex.md"><b>Webpage Examples</b></a></li>
262 <li><a href="../../../help">Webpages &mdash; Lists of Commands and</a></li>
263 <li><a href="quotes.wiki">What People Are Saying About Fossil, Git, and DVCSes in General &mdash; Quotes:</a></li>
264

Keyboard Shortcuts

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