Fossil SCM

Merged in trunk. Minor help text corrections for add/rm --reset.

stephan 2020-05-12 08:48 unaddremove-command merge
Commit 822f3aee48de082de0e441c300e80133446f79abc70a6be7b10adf7f4e4bd0d4
+8 -4
--- src/add.c
+++ src/add.c
@@ -367,13 +367,16 @@
367367
** -f|--force Add files without prompting
368368
** --ignore <CSG> Ignore unmanaged files matching patterns from
369369
** the comma separated list of glob patterns.
370370
** --clean <CSG> Also ignore files matching patterns from
371371
** the comma separated list of glob patterns.
372
-** --reset Reset the ADDEd state of a checkout, such that
373
-** all newly-added (but not yet committed) files
374
-** are no longer added.
372
+
373
+** --reset Reset the ADDEd state of a checkout, such
374
+** that all newly-added (but not yet committed)
375
+** files are no longer added. No flags other
376
+** than --verbose and --dry-run may be used
377
+** with --reset.
375378
**
376379
** The following options are only valid with --reset:
377380
** -v|--verbose Outputs information about each --reset file.
378381
** -n|--dry-run Display instead of run actions.
379382
**
@@ -552,11 +555,12 @@
552555
** --case-sensitive <BOOL> Override the case-sensitive setting.
553556
** -n|--dry-run If given, display instead of run actions.
554557
** --reset Reset the DELETED state of a checkout, such
555558
** that all newly-rm'd (but not yet committed)
556559
** files are no longer removed. No flags other
557
-** than --verbose may be used with --reset.
560
+** than --verbose or --dry-run may be used with
561
+** --reset.
558562
** --verbose|-v Outputs information about each --reset file.
559563
** Only usable with --reset.
560564
**
561565
** See also: addremove, add
562566
*/
563567
--- src/add.c
+++ src/add.c
@@ -367,13 +367,16 @@
367 ** -f|--force Add files without prompting
368 ** --ignore <CSG> Ignore unmanaged files matching patterns from
369 ** the comma separated list of glob patterns.
370 ** --clean <CSG> Also ignore files matching patterns from
371 ** the comma separated list of glob patterns.
372 ** --reset Reset the ADDEd state of a checkout, such that
373 ** all newly-added (but not yet committed) files
374 ** are no longer added.
 
 
 
375 **
376 ** The following options are only valid with --reset:
377 ** -v|--verbose Outputs information about each --reset file.
378 ** -n|--dry-run Display instead of run actions.
379 **
@@ -552,11 +555,12 @@
552 ** --case-sensitive <BOOL> Override the case-sensitive setting.
553 ** -n|--dry-run If given, display instead of run actions.
554 ** --reset Reset the DELETED state of a checkout, such
555 ** that all newly-rm'd (but not yet committed)
556 ** files are no longer removed. No flags other
557 ** than --verbose may be used with --reset.
 
558 ** --verbose|-v Outputs information about each --reset file.
559 ** Only usable with --reset.
560 **
561 ** See also: addremove, add
562 */
563
--- src/add.c
+++ src/add.c
@@ -367,13 +367,16 @@
367 ** -f|--force Add files without prompting
368 ** --ignore <CSG> Ignore unmanaged files matching patterns from
369 ** the comma separated list of glob patterns.
370 ** --clean <CSG> Also ignore files matching patterns from
371 ** the comma separated list of glob patterns.
372
373 ** --reset Reset the ADDEd state of a checkout, such
374 ** that all newly-added (but not yet committed)
375 ** files are no longer added. No flags other
376 ** than --verbose and --dry-run may be used
377 ** with --reset.
378 **
379 ** The following options are only valid with --reset:
380 ** -v|--verbose Outputs information about each --reset file.
381 ** -n|--dry-run Display instead of run actions.
382 **
@@ -552,11 +555,12 @@
555 ** --case-sensitive <BOOL> Override the case-sensitive setting.
556 ** -n|--dry-run If given, display instead of run actions.
557 ** --reset Reset the DELETED state of a checkout, such
558 ** that all newly-rm'd (but not yet committed)
559 ** files are no longer removed. No flags other
560 ** than --verbose or --dry-run may be used with
561 ** --reset.
562 ** --verbose|-v Outputs information about each --reset file.
563 ** Only usable with --reset.
564 **
565 ** See also: addremove, add
566 */
567
+8 -4
--- src/add.c
+++ src/add.c
@@ -367,13 +367,16 @@
367367
** -f|--force Add files without prompting
368368
** --ignore <CSG> Ignore unmanaged files matching patterns from
369369
** the comma separated list of glob patterns.
370370
** --clean <CSG> Also ignore files matching patterns from
371371
** the comma separated list of glob patterns.
372
-** --reset Reset the ADDEd state of a checkout, such that
373
-** all newly-added (but not yet committed) files
374
-** are no longer added.
372
+
373
+** --reset Reset the ADDEd state of a checkout, such
374
+** that all newly-added (but not yet committed)
375
+** files are no longer added. No flags other
376
+** than --verbose and --dry-run may be used
377
+** with --reset.
375378
**
376379
** The following options are only valid with --reset:
377380
** -v|--verbose Outputs information about each --reset file.
378381
** -n|--dry-run Display instead of run actions.
379382
**
@@ -552,11 +555,12 @@
552555
** --case-sensitive <BOOL> Override the case-sensitive setting.
553556
** -n|--dry-run If given, display instead of run actions.
554557
** --reset Reset the DELETED state of a checkout, such
555558
** that all newly-rm'd (but not yet committed)
556559
** files are no longer removed. No flags other
557
-** than --verbose may be used with --reset.
560
+** than --verbose or --dry-run may be used with
561
+** --reset.
558562
** --verbose|-v Outputs information about each --reset file.
559563
** Only usable with --reset.
560564
**
561565
** See also: addremove, add
562566
*/
563567
--- src/add.c
+++ src/add.c
@@ -367,13 +367,16 @@
367 ** -f|--force Add files without prompting
368 ** --ignore <CSG> Ignore unmanaged files matching patterns from
369 ** the comma separated list of glob patterns.
370 ** --clean <CSG> Also ignore files matching patterns from
371 ** the comma separated list of glob patterns.
372 ** --reset Reset the ADDEd state of a checkout, such that
373 ** all newly-added (but not yet committed) files
374 ** are no longer added.
 
 
 
375 **
376 ** The following options are only valid with --reset:
377 ** -v|--verbose Outputs information about each --reset file.
378 ** -n|--dry-run Display instead of run actions.
379 **
@@ -552,11 +555,12 @@
552 ** --case-sensitive <BOOL> Override the case-sensitive setting.
553 ** -n|--dry-run If given, display instead of run actions.
554 ** --reset Reset the DELETED state of a checkout, such
555 ** that all newly-rm'd (but not yet committed)
556 ** files are no longer removed. No flags other
557 ** than --verbose may be used with --reset.
 
558 ** --verbose|-v Outputs information about each --reset file.
559 ** Only usable with --reset.
560 **
561 ** See also: addremove, add
562 */
563
--- src/add.c
+++ src/add.c
@@ -367,13 +367,16 @@
367 ** -f|--force Add files without prompting
368 ** --ignore <CSG> Ignore unmanaged files matching patterns from
369 ** the comma separated list of glob patterns.
370 ** --clean <CSG> Also ignore files matching patterns from
371 ** the comma separated list of glob patterns.
372
373 ** --reset Reset the ADDEd state of a checkout, such
374 ** that all newly-added (but not yet committed)
375 ** files are no longer added. No flags other
376 ** than --verbose and --dry-run may be used
377 ** with --reset.
378 **
379 ** The following options are only valid with --reset:
380 ** -v|--verbose Outputs information about each --reset file.
381 ** -n|--dry-run Display instead of run actions.
382 **
@@ -552,11 +555,12 @@
555 ** --case-sensitive <BOOL> Override the case-sensitive setting.
556 ** -n|--dry-run If given, display instead of run actions.
557 ** --reset Reset the DELETED state of a checkout, such
558 ** that all newly-rm'd (but not yet committed)
559 ** files are no longer removed. No flags other
560 ** than --verbose or --dry-run may be used with
561 ** --reset.
562 ** --verbose|-v Outputs information about each --reset file.
563 ** Only usable with --reset.
564 **
565 ** See also: addremove, add
566 */
567
+1 -1
--- src/allrepo.c
+++ src/allrepo.c
@@ -128,11 +128,11 @@
128128
** supported by the rebuild command itself, if any are
129129
** present, are passed along verbatim. The --force and
130130
** --randomize options are not supported.
131131
**
132132
** sync Run a "sync" on all repositories. Only the --verbose
133
-** option is supported.
133
+** and --unversioned options are supported.
134134
**
135135
** setting Run the "setting", "set", or "unset" commands on all
136136
** set repositories. These command are particularly useful in
137137
** unset conjunction with the "max-loadavg" setting which cannot
138138
** otherwise be set globally.
139139
--- src/allrepo.c
+++ src/allrepo.c
@@ -128,11 +128,11 @@
128 ** supported by the rebuild command itself, if any are
129 ** present, are passed along verbatim. The --force and
130 ** --randomize options are not supported.
131 **
132 ** sync Run a "sync" on all repositories. Only the --verbose
133 ** option is supported.
134 **
135 ** setting Run the "setting", "set", or "unset" commands on all
136 ** set repositories. These command are particularly useful in
137 ** unset conjunction with the "max-loadavg" setting which cannot
138 ** otherwise be set globally.
139
--- src/allrepo.c
+++ src/allrepo.c
@@ -128,11 +128,11 @@
128 ** supported by the rebuild command itself, if any are
129 ** present, are passed along verbatim. The --force and
130 ** --randomize options are not supported.
131 **
132 ** sync Run a "sync" on all repositories. Only the --verbose
133 ** and --unversioned options are supported.
134 **
135 ** setting Run the "setting", "set", or "unset" commands on all
136 ** set repositories. These command are particularly useful in
137 ** unset conjunction with the "max-loadavg" setting which cannot
138 ** otherwise be set globally.
139
+14
--- src/branch.c
+++ src/branch.c
@@ -18,10 +18,24 @@
1818
** This file contains code used to create new branches within a repository.
1919
*/
2020
#include "config.h"
2121
#include "branch.h"
2222
#include <assert.h>
23
+
24
+/*
25
+** Return true if zBr is the branch name associated with check-in with
26
+** blob.uuid value of zUuid
27
+*/
28
+int branch_includes_uuid(const char *zBr, const char *zUuid){
29
+ return db_exists(
30
+ "SELECT 1 FROM tagxref, blob"
31
+ " WHERE blob.uuid=%Q AND tagxref.rid=blob.rid"
32
+ " AND tagxref.value=%Q AND tagxref.tagtype>0"
33
+ " AND tagxref.tagid=%d",
34
+ zUuid, zBr, TAG_BRANCH
35
+ );
36
+}
2337
2438
/*
2539
** If RID refers to a check-in, return the name of the branch for that
2640
** check-in.
2741
**
2842
--- src/branch.c
+++ src/branch.c
@@ -18,10 +18,24 @@
18 ** This file contains code used to create new branches within a repository.
19 */
20 #include "config.h"
21 #include "branch.h"
22 #include <assert.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24 /*
25 ** If RID refers to a check-in, return the name of the branch for that
26 ** check-in.
27 **
28
--- src/branch.c
+++ src/branch.c
@@ -18,10 +18,24 @@
18 ** This file contains code used to create new branches within a repository.
19 */
20 #include "config.h"
21 #include "branch.h"
22 #include <assert.h>
23
24 /*
25 ** Return true if zBr is the branch name associated with check-in with
26 ** blob.uuid value of zUuid
27 */
28 int branch_includes_uuid(const char *zBr, const char *zUuid){
29 return db_exists(
30 "SELECT 1 FROM tagxref, blob"
31 " WHERE blob.uuid=%Q AND tagxref.rid=blob.rid"
32 " AND tagxref.value=%Q AND tagxref.tagtype>0"
33 " AND tagxref.tagid=%d",
34 zUuid, zBr, TAG_BRANCH
35 );
36 }
37
38 /*
39 ** If RID refers to a check-in, return the name of the branch for that
40 ** check-in.
41 **
42
+144 -75
--- src/browse.c
+++ src/browse.c
@@ -59,10 +59,18 @@
5959
zOut = sqlite3_mprintf("/%.*s", i-n, &z[n]);
6060
sqlite3_result_text(context, zOut, i-n+1, sqlite3_free);
6161
}
6262
}
6363
64
+/*
65
+** Flag arguments for hyperlinked_path()
66
+*/
67
+#if INTERFACE
68
+# define LINKPATH_FINFO 0x0001 /* Link final term to /finfo */
69
+# define LINKPATH_FILE 0x0002 /* Link final term to /file */
70
+#endif
71
+
6472
/*
6573
** Given a pathname which is a relative path from the root of
6674
** the repository to a file or directory, compute a string which
6775
** is an HTML rendering of that path with hyperlinks on each
6876
** directory component of the path where the hyperlink redirects
@@ -76,29 +84,36 @@
7684
void hyperlinked_path(
7785
const char *zPath, /* Path to render */
7886
Blob *pOut, /* Write into this blob */
7987
const char *zCI, /* check-in name, or NULL */
8088
const char *zURI, /* "dir" or "tree" */
81
- const char *zREx /* Extra query parameters */
89
+ const char *zREx, /* Extra query parameters */
90
+ unsigned int mFlags /* Extra flags */
8291
){
8392
int i, j;
8493
char *zSep = "";
8594
8695
for(i=0; zPath[i]; i=j){
8796
for(j=i; zPath[j] && zPath[j]!='/'; j++){}
88
- if( zPath[j] && g.perm.Hyperlink ){
89
- if( zCI ){
90
- char *zLink = href("%R/%s?name=%#T%s&ci=%!S", zURI, j, zPath, zREx,zCI);
91
- blob_appendf(pOut, "%s%z%#h</a>",
92
- zSep, zLink, j-i, &zPath[i]);
93
- }else{
94
- char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx);
95
- blob_appendf(pOut, "%s%z%#h</a>",
96
- zSep, zLink, j-i, &zPath[i]);
97
- }
98
- }else{
99
- blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]);
97
+ if( zPath[j]==0 ){
98
+ if( mFlags & LINKPATH_FILE ){
99
+ zURI = "file";
100
+ }else if( mFlags & LINKPATH_FINFO ){
101
+ zURI = "finfo";
102
+ }else{
103
+ blob_appendf(pOut, "/%h", zPath+i);
104
+ break;
105
+ }
106
+ }
107
+ if( zCI ){
108
+ char *zLink = href("%R/%s?name=%#T%s&ci=%T", zURI, j, zPath, zREx,zCI);
109
+ blob_appendf(pOut, "%s%z%#h</a>",
110
+ zSep, zLink, j-i, &zPath[i]);
111
+ }else{
112
+ char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx);
113
+ blob_appendf(pOut, "%s%z%#h</a>",
114
+ zSep, zLink, j-i, &zPath[i]);
100115
}
101116
zSep = "/";
102117
while( zPath[j]=='/' ){ j++; }
103118
}
104119
}
@@ -127,27 +142,24 @@
127142
char *zPrefix;
128143
Stmt q;
129144
const char *zCI = P("ci");
130145
int rid = 0;
131146
char *zUuid = 0;
132
- Blob dirname;
133147
Manifest *pM = 0;
134148
const char *zSubdirLink;
135149
int linkTrunk = 1;
136150
int linkTip = 1;
137151
HQuery sURI;
152
+ int isSymbolicCI = 0; /* ci= is symbolic name, not a hash prefix */
153
+ int isBranchCI = 0; /* True if ci= refers to a branch name */
154
+ char *zHeader = 0;
138155
156
+ if( zCI && strlen(zCI)==0 ){ zCI = 0; }
139157
if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; }
140158
login_check_credentials();
141159
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
142160
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
143
- style_header("File List");
144
- style_adunit_config(ADUNIT_RIGHT_OK);
145
- sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
146
- pathelementFunc, 0, 0);
147
- url_initialize(&sURI, "dir");
148
- cgi_query_parameters_to_url(&sURI);
149161
150162
/* If the name= parameter is an empty string, make it a NULL pointer */
151163
if( zD && strlen(zD)==0 ){ zD = 0; }
152164
153165
/* If a specific check-in is requested, fetch and parse it. If the
@@ -159,53 +171,79 @@
159171
if( pM ){
160172
int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
161173
linkTrunk = trunkRid && rid != trunkRid;
162174
linkTip = rid != symbolic_name_to_rid("tip", "ci");
163175
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
176
+ isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI))!=0);
177
+ isBranchCI = branch_includes_uuid(zCI, zUuid);
164178
}else{
165179
zCI = 0;
166180
}
167181
}
168182
183
+ assert( isSymbolicCI==0 || (zCI!=0 && zCI[0]!=0) );
184
+ if( zD==0 ){
185
+ if( zCI ){
186
+ zHeader = mprintf("Top-level Files of %s", zCI);
187
+ }else{
188
+ zHeader = mprintf("All Top-level Files");
189
+ }
190
+ }else{
191
+ if( zCI ){
192
+ zHeader = mprintf("Files in %s/ of %s", zD, zCI);
193
+ }else{
194
+ zHeader = mprintf("All File in %s/", zD);
195
+ }
196
+ }
197
+ style_header("%s", zHeader);
198
+ fossil_free(zHeader);
199
+ style_adunit_config(ADUNIT_RIGHT_OK);
200
+ sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
201
+ pathelementFunc, 0, 0);
202
+ url_initialize(&sURI, "dir");
203
+ cgi_query_parameters_to_url(&sURI);
204
+
169205
/* Compute the title of the page */
170
- blob_zero(&dirname);
171206
if( zD ){
172
- blob_append(&dirname, "in directory ", -1);
173
- hyperlinked_path(zD, &dirname, zCI, "dir", "");
207
+ Blob dirname;
208
+ blob_init(&dirname, 0, 0);
209
+ hyperlinked_path(zD, &dirname, zCI, "dir", "", 0);
210
+ @ <h2>Files in directory %s(blob_str(&dirname)) \
211
+ blob_reset(&dirname);
174212
zPrefix = mprintf("%s/", zD);
175213
style_submenu_element("Top-Level", "%s",
176214
url_render(&sURI, "name", 0, 0, 0));
177215
}else{
178
- blob_append(&dirname, "in the top-level directory", -1);
216
+ @ <h2>Files in the top-level directory \
179217
zPrefix = "";
180218
}
219
+ if( zCI ){
220
+ if( fossil_strcmp(zCI,"tip")==0 ){
221
+ @ from the %z(href("%R/info?name=%T",zCI))latest check-in</a></h2>
222
+ }else if( isBranchCI ){
223
+ @ from the %z(href("%R/info?name=%T",zCI))latest check-in</a> \
224
+ @ of branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
225
+ }else {
226
+ @ of check-in %z(href("%R/info?name=%T",zCI))%h(zCI)</a></h2>
227
+ }
228
+ zSubdirLink = mprintf("%R/dir?ci=%T&name=%T", zCI, zPrefix);
229
+ if( nD==0 ){
230
+ style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
231
+ }
232
+ }else{
233
+ @ in any check-in</h2>
234
+ zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
235
+ }
181236
if( linkTrunk ){
182237
style_submenu_element("Trunk", "%s",
183238
url_render(&sURI, "ci", "trunk", 0, 0));
184239
}
185240
if( linkTip ){
186241
style_submenu_element("Tip", "%s", url_render(&sURI, "ci", "tip", 0, 0));
187242
}
188
- if( zCI ){
189
- @ <h2>Files of check-in [%z(href("vinfo?name=%!S",zUuid))%S(zUuid)</a>]
190
- @ %s(blob_str(&dirname))
191
- if( zD ){
192
- @ &nbsp;&nbsp;%z(href("%R/timeline?chng=%T/*", zD))[history]</a>
193
- }
194
- @ </h2>
195
- zSubdirLink = mprintf("%R/dir?ci=%!S&name=%T", zUuid, zPrefix);
196
- if( nD==0 ){
197
- style_submenu_element("File Ages", "%R/fileage?name=%!S", zUuid);
198
- }
199
- }else{
200
- @ <h2>The union of all files from all check-ins
201
- @ %s(blob_str(&dirname))
202
- if( zD ){
203
- @ &nbsp;&nbsp;%z(href("%R/timeline?chng=%T/*", zD))[history]</a>
204
- }
205
- @ </h2>
206
- zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
243
+ if( zD ){
244
+ style_submenu_element("History","%R/timeline?chng=%T/*", zD);
207245
}
208246
style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
209247
style_submenu_element("Tree-View", "%s",
210248
url_render(&sURI, "type", "tree", 0, 0));
211249
@@ -282,12 +320,11 @@
282320
zFN++;
283321
@ <li class="dir">%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li>
284322
}else{
285323
const char *zLink;
286324
if( zCI ){
287
- const char *zUuid = db_column_text(&q, 1);
288
- zLink = href("%R/artifact/%!S",zUuid);
325
+ zLink = href("%R/file?name=%T%T&ci=%T",zPrefix,zFN,zCI);
289326
}else{
290327
zLink = href("%R/finfo?name=%T%T",zPrefix,zFN);
291328
}
292329
@ <li class="%z(fileext_class(zFN))">%z(zLink)%h(zFN)</a></li>
293330
}
@@ -612,11 +649,15 @@
612649
HQuery sURI; /* Hyperlink */
613650
int startExpanded; /* True to start out with the tree expanded */
614651
int showDirOnly; /* Show directories only. Omit files */
615652
int nDir = 0; /* Number of directories. Used for ID attributes */
616653
char *zProjectName = db_get("project-name", 0);
654
+ int isSymbolicCI = 0; /* ci= is a symbolic name, not a hash prefix */
655
+ int isBranchCI = 0; /* ci= refers to a branch name */
656
+ char *zHeader = 0;
617657
658
+ if( zCI && strlen(zCI)==0 ){ zCI = 0; }
618659
if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; }
619660
memset(&sTree, 0, sizeof(sTree));
620661
login_check_credentials();
621662
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
622663
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
@@ -624,14 +665,12 @@
624665
pathelementFunc, 0, 0);
625666
url_initialize(&sURI, "tree");
626667
cgi_query_parameters_to_url(&sURI);
627668
if( PB("nofiles") ){
628669
showDirOnly = 1;
629
- style_header("Folder Hierarchy");
630670
}else{
631671
showDirOnly = 0;
632
- style_header("File Tree");
633672
}
634673
style_adunit_config(ADUNIT_RIGHT_OK);
635674
if( PB("expand") ){
636675
startExpanded = 1;
637676
}else{
@@ -660,37 +699,54 @@
660699
linkTip = rid != symbolic_name_to_rid("tip", "ci");
661700
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
662701
rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
663702
zNow = db_text("", "SELECT datetime(mtime,toLocal())"
664703
" FROM event WHERE objid=%d", rid);
704
+ isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI)) != 0);
705
+ isBranchCI = branch_includes_uuid(zCI, zUuid);
665706
}else{
666707
zCI = 0;
667708
}
668709
}
669710
if( zCI==0 ){
670711
rNow = db_double(0.0, "SELECT max(mtime) FROM event");
671712
zNow = db_text("", "SELECT datetime(max(mtime),toLocal()) FROM event");
672713
}
714
+
715
+ assert( isSymbolicCI==0 || (zCI!=0 && zCI[0]!=0) );
716
+ if( zD==0 ){
717
+ if( zCI ){
718
+ zHeader = mprintf("Top-level Files of %s", zCI);
719
+ }else{
720
+ zHeader = mprintf("All Top-level Files");
721
+ }
722
+ }else{
723
+ if( zCI ){
724
+ zHeader = mprintf("Files in %s/ of %s", zD, zCI);
725
+ }else{
726
+ zHeader = mprintf("All File in %s/", zD);
727
+ }
728
+ }
729
+ style_header("%s", zHeader);
730
+ fossil_free(zHeader);
673731
674732
/* Compute the title of the page */
675733
blob_zero(&dirname);
676734
if( zD ){
677735
blob_append(&dirname, "within directory ", -1);
678
- hyperlinked_path(zD, &dirname, zCI, "tree", zREx);
736
+ hyperlinked_path(zD, &dirname, zCI, "tree", zREx, 0);
679737
if( zRE ) blob_appendf(&dirname, " matching \"%s\"", zRE);
680738
style_submenu_element("Top-Level", "%s",
681739
url_render(&sURI, "name", 0, 0, 0));
682
- }else{
683
- if( zRE ){
684
- blob_appendf(&dirname, "matching \"%s\"", zRE);
685
- }
740
+ }else if( zRE ){
741
+ blob_appendf(&dirname, "matching \"%s\"", zRE);
686742
}
687743
style_submenu_binary("mtime","Sort By Time","Sort By Filename", 0);
688744
if( zCI ){
689745
style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
690746
if( nD==0 && !showDirOnly ){
691
- style_submenu_element("File Ages", "%R/fileage?name=%s", zUuid);
747
+ style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
692748
}
693749
}
694750
if( linkTrunk ){
695751
style_submenu_element("Trunk", "%s",
696752
url_render(&sURI, "ci", "trunk", 0, 0));
@@ -745,10 +801,11 @@
745801
tree_add_node(&sTree, zName, zUuid, mtime);
746802
nFile++;
747803
}
748804
db_finalize(&q);
749805
}
806
+ style_submenu_checkbox("nofiles", "Folders Only", 0, 0);
750807
751808
if( showDirOnly ){
752809
for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
753810
if( p->pChild!=0 && p->nFullName>nD ) nFile++;
754811
}
@@ -755,18 +812,24 @@
755812
zObjType = "Folders";
756813
}else{
757814
zObjType = "Files";
758815
}
759816
760
- style_submenu_checkbox("nofiles", "Folders Only", 0, 0);
761
-
762
- if( zCI ){
763
- @ <h2>%s(zObjType) from
764
- if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
765
- @ "%h(zCI)"
766
- }
767
- @ [%z(href("vinfo?name=%!S",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))
817
+ if( zCI && strcmp(zCI,"tip")==0 ){
818
+ @ <h2>%s(zObjType) in the %z(href("%R/info?name=tip"))latest check-in</a>
819
+ }else if( isBranchCI ){
820
+ @ <h2>%s(zObjType) in the %z(href("%R/info?name=%T",zCI))latest check-in\
821
+ @ </a> for branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a>
822
+ if( blob_size(&dirname) ){
823
+ @ and %s(blob_str(&dirname))</h2>
824
+ }
825
+ }else if( zCI ){
826
+ @ <h2>%s(zObjType) for check-in \
827
+ @ %z(href("%R/info?name=%T",zCI))%h(zCI)</a></h2>
828
+ if( blob_size(&dirname) ){
829
+ @ and %s(blob_str(&dirname))</h2>
830
+ }
768831
}else{
769832
int n = db_int(0, "SELECT count(*) FROM plink");
770833
@ <h2>%s(zObjType) from all %d(n) check-ins %s(blob_str(&dirname))
771834
}
772835
if( useMtime ){
@@ -824,11 +887,11 @@
824887
nDir++;
825888
}else if( !showDirOnly ){
826889
const char *zFileClass = fileext_class(p->zName);
827890
char *zLink;
828891
if( zCI ){
829
- zLink = href("%R/artifact/%!S",p->zUuid);
892
+ zLink = href("%R/file?name=%T&ci=%T",p->zFullName,zCI);
830893
}else{
831894
zLink = href("%R/finfo?name=%T",p->zFullName);
832895
}
833896
@ <li class="%z(zFileClass)%s(zLastClass)"><div class="filetreeline">
834897
@ %z(zLink)%h(p->zName)</a>
@@ -1001,10 +1064,11 @@
10011064
int rid;
10021065
const char *zName;
10031066
const char *zGlob;
10041067
const char *zUuid;
10051068
const char *zNow; /* Time of check-in */
1069
+ int isBranchCI; /* name= is a branch name */
10061070
int showId = PB("showid");
10071071
Stmt q1, q2;
10081072
double baseTime;
10091073
login_check_credentials();
10101074
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1014,28 +1078,34 @@
10141078
rid = symbolic_name_to_rid(zName, "ci");
10151079
if( rid==0 ){
10161080
fossil_fatal("not a valid check-in: %s", zName);
10171081
}
10181082
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1083
+ isBranchCI = branch_includes_uuid(zName,zUuid);
10191084
baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
10201085
zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
10211086
" WHERE objid=%d", rid);
10221087
style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
10231088
style_header("File Ages");
10241089
zGlob = P("glob");
10251090
compute_fileage(rid,zGlob);
10261091
db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
10271092
1028
- @ <h1>Files in
1029
- @ %z(href("%R/info/%!S",zUuid))[%S(zUuid)]</a>
1093
+ if( fossil_strcmp(zName,"tip")==0 ){
1094
+ @ <h1>Files in the %z(href("%R/info?name=tip"))latest check-in</a>
1095
+ }else if( isBranchCI ){
1096
+ @ <h1>Files in the %z(href("%R/info?name=%T",zName))latest check-in</a>
1097
+ @ of branch %z(href("%R/timeline?r=%T",zName))%h(zName)</a>
1098
+ }else{
1099
+ @ <h1>Files in check-in %z(href("%R/info?name=%T",zName))%h(zName)</a>
1100
+ }
10301101
if( zGlob && zGlob[0] ){
10311102
@ that match "%h(zGlob)"
10321103
}
10331104
@ ordered by age</h1>
10341105
@
1035
- @ <p>File ages are expressed relative to the
1036
- @ %z(href("%R/ci/%!S",zUuid))[%S(zUuid)]</a> check-in time of
1106
+ @ <p>File ages are expressed relative to the check-in time of
10371107
@ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
10381108
@
10391109
@ <div class='fileage'><table>
10401110
@ <tr><th>Age</th><th>Files</th><th>Check-in</th></tr>
10411111
db_prepare(&q1,
@@ -1050,14 +1120,13 @@
10501120
" AND blob.rid=event.objid\n"
10511121
" ORDER BY event.mtime DESC;",
10521122
TAG_BRANCH
10531123
);
10541124
db_prepare(&q2,
1055
- "SELECT blob.uuid, filename.name, fileage.fid\n"
1056
- " FROM fileage, blob, filename\n"
1125
+ "SELECT filename.name, fileage.fid\n"
1126
+ " FROM fileage, filename\n"
10571127
" WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
1058
- " AND blob.rid=fileage.fid;"
10591128
);
10601129
while( db_step(&q1)==SQLITE_ROW ){
10611130
double age = baseTime - db_column_double(&q1, 0);
10621131
int mid = db_column_int(&q1, 1);
10631132
const char *zUuid = db_column_text(&q1, 2);
@@ -1067,24 +1136,24 @@
10671136
char *zAge = human_readable_age(age);
10681137
@ <tr><td>%s(zAge)</td>
10691138
@ <td>
10701139
db_bind_int(&q2, ":mid", mid);
10711140
while( db_step(&q2)==SQLITE_ROW ){
1072
- const char *zFUuid = db_column_text(&q2,0);
1073
- const char *zFile = db_column_text(&q2,1);
1074
- int fid = db_column_int(&q2,2);
1141
+ const char *zFile = db_column_text(&q2,0);
1142
+ @ %z(href("%R/file?name=%T&ci=%!S",zFile,zUuid))%h(zFile)</a> \
10751143
if( showId ){
1076
- @ %z(href("%R/artifact/%!S",zFUuid))%h(zFile)</a> (%d(fid))<br />
1144
+ int fid = db_column_int(&q2,1);
1145
+ @ (%d(fid))<br />
10771146
}else{
1078
- @ %z(href("%R/artifact/%!S",zFUuid))%h(zFile)</a><br />
1147
+ @ </a><br />
10791148
}
10801149
}
10811150
db_reset(&q2);
10821151
@ </td>
10831152
@ <td>
10841153
@ %W(zComment)
1085
- @ (check-in:&nbsp;%z(href("%R/ci/%!S",zUuid))%S(zUuid)</a>,
1154
+ @ (check-in:&nbsp;%z(href("%R/info/%!S",zUuid))%S(zUuid)</a>,
10861155
if( showId ){
10871156
@ id: %d(mid)
10881157
}
10891158
@ user:&nbsp;%z(href("%R/timeline?u=%t&c=%!S&nd",zUser,zUuid))%h(zUser)</a>,
10901159
@ branch:&nbsp;\
10911160
--- src/browse.c
+++ src/browse.c
@@ -59,10 +59,18 @@
59 zOut = sqlite3_mprintf("/%.*s", i-n, &z[n]);
60 sqlite3_result_text(context, zOut, i-n+1, sqlite3_free);
61 }
62 }
63
 
 
 
 
 
 
 
 
64 /*
65 ** Given a pathname which is a relative path from the root of
66 ** the repository to a file or directory, compute a string which
67 ** is an HTML rendering of that path with hyperlinks on each
68 ** directory component of the path where the hyperlink redirects
@@ -76,29 +84,36 @@
76 void hyperlinked_path(
77 const char *zPath, /* Path to render */
78 Blob *pOut, /* Write into this blob */
79 const char *zCI, /* check-in name, or NULL */
80 const char *zURI, /* "dir" or "tree" */
81 const char *zREx /* Extra query parameters */
 
82 ){
83 int i, j;
84 char *zSep = "";
85
86 for(i=0; zPath[i]; i=j){
87 for(j=i; zPath[j] && zPath[j]!='/'; j++){}
88 if( zPath[j] && g.perm.Hyperlink ){
89 if( zCI ){
90 char *zLink = href("%R/%s?name=%#T%s&ci=%!S", zURI, j, zPath, zREx,zCI);
91 blob_appendf(pOut, "%s%z%#h</a>",
92 zSep, zLink, j-i, &zPath[i]);
93 }else{
94 char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx);
95 blob_appendf(pOut, "%s%z%#h</a>",
96 zSep, zLink, j-i, &zPath[i]);
97 }
98 }else{
99 blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]);
 
 
 
 
 
 
100 }
101 zSep = "/";
102 while( zPath[j]=='/' ){ j++; }
103 }
104 }
@@ -127,27 +142,24 @@
127 char *zPrefix;
128 Stmt q;
129 const char *zCI = P("ci");
130 int rid = 0;
131 char *zUuid = 0;
132 Blob dirname;
133 Manifest *pM = 0;
134 const char *zSubdirLink;
135 int linkTrunk = 1;
136 int linkTip = 1;
137 HQuery sURI;
 
 
 
138
 
139 if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; }
140 login_check_credentials();
141 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
142 while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
143 style_header("File List");
144 style_adunit_config(ADUNIT_RIGHT_OK);
145 sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
146 pathelementFunc, 0, 0);
147 url_initialize(&sURI, "dir");
148 cgi_query_parameters_to_url(&sURI);
149
150 /* If the name= parameter is an empty string, make it a NULL pointer */
151 if( zD && strlen(zD)==0 ){ zD = 0; }
152
153 /* If a specific check-in is requested, fetch and parse it. If the
@@ -159,53 +171,79 @@
159 if( pM ){
160 int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
161 linkTrunk = trunkRid && rid != trunkRid;
162 linkTip = rid != symbolic_name_to_rid("tip", "ci");
163 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
 
 
164 }else{
165 zCI = 0;
166 }
167 }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169 /* Compute the title of the page */
170 blob_zero(&dirname);
171 if( zD ){
172 blob_append(&dirname, "in directory ", -1);
173 hyperlinked_path(zD, &dirname, zCI, "dir", "");
 
 
 
174 zPrefix = mprintf("%s/", zD);
175 style_submenu_element("Top-Level", "%s",
176 url_render(&sURI, "name", 0, 0, 0));
177 }else{
178 blob_append(&dirname, "in the top-level directory", -1);
179 zPrefix = "";
180 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181 if( linkTrunk ){
182 style_submenu_element("Trunk", "%s",
183 url_render(&sURI, "ci", "trunk", 0, 0));
184 }
185 if( linkTip ){
186 style_submenu_element("Tip", "%s", url_render(&sURI, "ci", "tip", 0, 0));
187 }
188 if( zCI ){
189 @ <h2>Files of check-in [%z(href("vinfo?name=%!S",zUuid))%S(zUuid)</a>]
190 @ %s(blob_str(&dirname))
191 if( zD ){
192 @ &nbsp;&nbsp;%z(href("%R/timeline?chng=%T/*", zD))[history]</a>
193 }
194 @ </h2>
195 zSubdirLink = mprintf("%R/dir?ci=%!S&name=%T", zUuid, zPrefix);
196 if( nD==0 ){
197 style_submenu_element("File Ages", "%R/fileage?name=%!S", zUuid);
198 }
199 }else{
200 @ <h2>The union of all files from all check-ins
201 @ %s(blob_str(&dirname))
202 if( zD ){
203 @ &nbsp;&nbsp;%z(href("%R/timeline?chng=%T/*", zD))[history]</a>
204 }
205 @ </h2>
206 zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
207 }
208 style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
209 style_submenu_element("Tree-View", "%s",
210 url_render(&sURI, "type", "tree", 0, 0));
211
@@ -282,12 +320,11 @@
282 zFN++;
283 @ <li class="dir">%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li>
284 }else{
285 const char *zLink;
286 if( zCI ){
287 const char *zUuid = db_column_text(&q, 1);
288 zLink = href("%R/artifact/%!S",zUuid);
289 }else{
290 zLink = href("%R/finfo?name=%T%T",zPrefix,zFN);
291 }
292 @ <li class="%z(fileext_class(zFN))">%z(zLink)%h(zFN)</a></li>
293 }
@@ -612,11 +649,15 @@
612 HQuery sURI; /* Hyperlink */
613 int startExpanded; /* True to start out with the tree expanded */
614 int showDirOnly; /* Show directories only. Omit files */
615 int nDir = 0; /* Number of directories. Used for ID attributes */
616 char *zProjectName = db_get("project-name", 0);
 
 
 
617
 
618 if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; }
619 memset(&sTree, 0, sizeof(sTree));
620 login_check_credentials();
621 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
622 while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
@@ -624,14 +665,12 @@
624 pathelementFunc, 0, 0);
625 url_initialize(&sURI, "tree");
626 cgi_query_parameters_to_url(&sURI);
627 if( PB("nofiles") ){
628 showDirOnly = 1;
629 style_header("Folder Hierarchy");
630 }else{
631 showDirOnly = 0;
632 style_header("File Tree");
633 }
634 style_adunit_config(ADUNIT_RIGHT_OK);
635 if( PB("expand") ){
636 startExpanded = 1;
637 }else{
@@ -660,37 +699,54 @@
660 linkTip = rid != symbolic_name_to_rid("tip", "ci");
661 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
662 rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
663 zNow = db_text("", "SELECT datetime(mtime,toLocal())"
664 " FROM event WHERE objid=%d", rid);
 
 
665 }else{
666 zCI = 0;
667 }
668 }
669 if( zCI==0 ){
670 rNow = db_double(0.0, "SELECT max(mtime) FROM event");
671 zNow = db_text("", "SELECT datetime(max(mtime),toLocal()) FROM event");
672 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673
674 /* Compute the title of the page */
675 blob_zero(&dirname);
676 if( zD ){
677 blob_append(&dirname, "within directory ", -1);
678 hyperlinked_path(zD, &dirname, zCI, "tree", zREx);
679 if( zRE ) blob_appendf(&dirname, " matching \"%s\"", zRE);
680 style_submenu_element("Top-Level", "%s",
681 url_render(&sURI, "name", 0, 0, 0));
682 }else{
683 if( zRE ){
684 blob_appendf(&dirname, "matching \"%s\"", zRE);
685 }
686 }
687 style_submenu_binary("mtime","Sort By Time","Sort By Filename", 0);
688 if( zCI ){
689 style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
690 if( nD==0 && !showDirOnly ){
691 style_submenu_element("File Ages", "%R/fileage?name=%s", zUuid);
692 }
693 }
694 if( linkTrunk ){
695 style_submenu_element("Trunk", "%s",
696 url_render(&sURI, "ci", "trunk", 0, 0));
@@ -745,10 +801,11 @@
745 tree_add_node(&sTree, zName, zUuid, mtime);
746 nFile++;
747 }
748 db_finalize(&q);
749 }
 
750
751 if( showDirOnly ){
752 for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
753 if( p->pChild!=0 && p->nFullName>nD ) nFile++;
754 }
@@ -755,18 +812,24 @@
755 zObjType = "Folders";
756 }else{
757 zObjType = "Files";
758 }
759
760 style_submenu_checkbox("nofiles", "Folders Only", 0, 0);
761
762 if( zCI ){
763 @ <h2>%s(zObjType) from
764 if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
765 @ "%h(zCI)"
766 }
767 @ [%z(href("vinfo?name=%!S",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))
 
 
 
 
 
 
768 }else{
769 int n = db_int(0, "SELECT count(*) FROM plink");
770 @ <h2>%s(zObjType) from all %d(n) check-ins %s(blob_str(&dirname))
771 }
772 if( useMtime ){
@@ -824,11 +887,11 @@
824 nDir++;
825 }else if( !showDirOnly ){
826 const char *zFileClass = fileext_class(p->zName);
827 char *zLink;
828 if( zCI ){
829 zLink = href("%R/artifact/%!S",p->zUuid);
830 }else{
831 zLink = href("%R/finfo?name=%T",p->zFullName);
832 }
833 @ <li class="%z(zFileClass)%s(zLastClass)"><div class="filetreeline">
834 @ %z(zLink)%h(p->zName)</a>
@@ -1001,10 +1064,11 @@
1001 int rid;
1002 const char *zName;
1003 const char *zGlob;
1004 const char *zUuid;
1005 const char *zNow; /* Time of check-in */
 
1006 int showId = PB("showid");
1007 Stmt q1, q2;
1008 double baseTime;
1009 login_check_credentials();
1010 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1014,28 +1078,34 @@
1014 rid = symbolic_name_to_rid(zName, "ci");
1015 if( rid==0 ){
1016 fossil_fatal("not a valid check-in: %s", zName);
1017 }
1018 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
 
1019 baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
1020 zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
1021 " WHERE objid=%d", rid);
1022 style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
1023 style_header("File Ages");
1024 zGlob = P("glob");
1025 compute_fileage(rid,zGlob);
1026 db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
1027
1028 @ <h1>Files in
1029 @ %z(href("%R/info/%!S",zUuid))[%S(zUuid)]</a>
 
 
 
 
 
 
1030 if( zGlob && zGlob[0] ){
1031 @ that match "%h(zGlob)"
1032 }
1033 @ ordered by age</h1>
1034 @
1035 @ <p>File ages are expressed relative to the
1036 @ %z(href("%R/ci/%!S",zUuid))[%S(zUuid)]</a> check-in time of
1037 @ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
1038 @
1039 @ <div class='fileage'><table>
1040 @ <tr><th>Age</th><th>Files</th><th>Check-in</th></tr>
1041 db_prepare(&q1,
@@ -1050,14 +1120,13 @@
1050 " AND blob.rid=event.objid\n"
1051 " ORDER BY event.mtime DESC;",
1052 TAG_BRANCH
1053 );
1054 db_prepare(&q2,
1055 "SELECT blob.uuid, filename.name, fileage.fid\n"
1056 " FROM fileage, blob, filename\n"
1057 " WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
1058 " AND blob.rid=fileage.fid;"
1059 );
1060 while( db_step(&q1)==SQLITE_ROW ){
1061 double age = baseTime - db_column_double(&q1, 0);
1062 int mid = db_column_int(&q1, 1);
1063 const char *zUuid = db_column_text(&q1, 2);
@@ -1067,24 +1136,24 @@
1067 char *zAge = human_readable_age(age);
1068 @ <tr><td>%s(zAge)</td>
1069 @ <td>
1070 db_bind_int(&q2, ":mid", mid);
1071 while( db_step(&q2)==SQLITE_ROW ){
1072 const char *zFUuid = db_column_text(&q2,0);
1073 const char *zFile = db_column_text(&q2,1);
1074 int fid = db_column_int(&q2,2);
1075 if( showId ){
1076 @ %z(href("%R/artifact/%!S",zFUuid))%h(zFile)</a> (%d(fid))<br />
 
1077 }else{
1078 @ %z(href("%R/artifact/%!S",zFUuid))%h(zFile)</a><br />
1079 }
1080 }
1081 db_reset(&q2);
1082 @ </td>
1083 @ <td>
1084 @ %W(zComment)
1085 @ (check-in:&nbsp;%z(href("%R/ci/%!S",zUuid))%S(zUuid)</a>,
1086 if( showId ){
1087 @ id: %d(mid)
1088 }
1089 @ user:&nbsp;%z(href("%R/timeline?u=%t&c=%!S&nd",zUser,zUuid))%h(zUser)</a>,
1090 @ branch:&nbsp;\
1091
--- src/browse.c
+++ src/browse.c
@@ -59,10 +59,18 @@
59 zOut = sqlite3_mprintf("/%.*s", i-n, &z[n]);
60 sqlite3_result_text(context, zOut, i-n+1, sqlite3_free);
61 }
62 }
63
64 /*
65 ** Flag arguments for hyperlinked_path()
66 */
67 #if INTERFACE
68 # define LINKPATH_FINFO 0x0001 /* Link final term to /finfo */
69 # define LINKPATH_FILE 0x0002 /* Link final term to /file */
70 #endif
71
72 /*
73 ** Given a pathname which is a relative path from the root of
74 ** the repository to a file or directory, compute a string which
75 ** is an HTML rendering of that path with hyperlinks on each
76 ** directory component of the path where the hyperlink redirects
@@ -76,29 +84,36 @@
84 void hyperlinked_path(
85 const char *zPath, /* Path to render */
86 Blob *pOut, /* Write into this blob */
87 const char *zCI, /* check-in name, or NULL */
88 const char *zURI, /* "dir" or "tree" */
89 const char *zREx, /* Extra query parameters */
90 unsigned int mFlags /* Extra flags */
91 ){
92 int i, j;
93 char *zSep = "";
94
95 for(i=0; zPath[i]; i=j){
96 for(j=i; zPath[j] && zPath[j]!='/'; j++){}
97 if( zPath[j]==0 ){
98 if( mFlags & LINKPATH_FILE ){
99 zURI = "file";
100 }else if( mFlags & LINKPATH_FINFO ){
101 zURI = "finfo";
102 }else{
103 blob_appendf(pOut, "/%h", zPath+i);
104 break;
105 }
106 }
107 if( zCI ){
108 char *zLink = href("%R/%s?name=%#T%s&ci=%T", zURI, j, zPath, zREx,zCI);
109 blob_appendf(pOut, "%s%z%#h</a>",
110 zSep, zLink, j-i, &zPath[i]);
111 }else{
112 char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx);
113 blob_appendf(pOut, "%s%z%#h</a>",
114 zSep, zLink, j-i, &zPath[i]);
115 }
116 zSep = "/";
117 while( zPath[j]=='/' ){ j++; }
118 }
119 }
@@ -127,27 +142,24 @@
142 char *zPrefix;
143 Stmt q;
144 const char *zCI = P("ci");
145 int rid = 0;
146 char *zUuid = 0;
 
147 Manifest *pM = 0;
148 const char *zSubdirLink;
149 int linkTrunk = 1;
150 int linkTip = 1;
151 HQuery sURI;
152 int isSymbolicCI = 0; /* ci= is symbolic name, not a hash prefix */
153 int isBranchCI = 0; /* True if ci= refers to a branch name */
154 char *zHeader = 0;
155
156 if( zCI && strlen(zCI)==0 ){ zCI = 0; }
157 if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; }
158 login_check_credentials();
159 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
160 while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
 
 
 
 
 
 
161
162 /* If the name= parameter is an empty string, make it a NULL pointer */
163 if( zD && strlen(zD)==0 ){ zD = 0; }
164
165 /* If a specific check-in is requested, fetch and parse it. If the
@@ -159,53 +171,79 @@
171 if( pM ){
172 int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
173 linkTrunk = trunkRid && rid != trunkRid;
174 linkTip = rid != symbolic_name_to_rid("tip", "ci");
175 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
176 isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI))!=0);
177 isBranchCI = branch_includes_uuid(zCI, zUuid);
178 }else{
179 zCI = 0;
180 }
181 }
182
183 assert( isSymbolicCI==0 || (zCI!=0 && zCI[0]!=0) );
184 if( zD==0 ){
185 if( zCI ){
186 zHeader = mprintf("Top-level Files of %s", zCI);
187 }else{
188 zHeader = mprintf("All Top-level Files");
189 }
190 }else{
191 if( zCI ){
192 zHeader = mprintf("Files in %s/ of %s", zD, zCI);
193 }else{
194 zHeader = mprintf("All File in %s/", zD);
195 }
196 }
197 style_header("%s", zHeader);
198 fossil_free(zHeader);
199 style_adunit_config(ADUNIT_RIGHT_OK);
200 sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
201 pathelementFunc, 0, 0);
202 url_initialize(&sURI, "dir");
203 cgi_query_parameters_to_url(&sURI);
204
205 /* Compute the title of the page */
 
206 if( zD ){
207 Blob dirname;
208 blob_init(&dirname, 0, 0);
209 hyperlinked_path(zD, &dirname, zCI, "dir", "", 0);
210 @ <h2>Files in directory %s(blob_str(&dirname)) \
211 blob_reset(&dirname);
212 zPrefix = mprintf("%s/", zD);
213 style_submenu_element("Top-Level", "%s",
214 url_render(&sURI, "name", 0, 0, 0));
215 }else{
216 @ <h2>Files in the top-level directory \
217 zPrefix = "";
218 }
219 if( zCI ){
220 if( fossil_strcmp(zCI,"tip")==0 ){
221 @ from the %z(href("%R/info?name=%T",zCI))latest check-in</a></h2>
222 }else if( isBranchCI ){
223 @ from the %z(href("%R/info?name=%T",zCI))latest check-in</a> \
224 @ of branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
225 }else {
226 @ of check-in %z(href("%R/info?name=%T",zCI))%h(zCI)</a></h2>
227 }
228 zSubdirLink = mprintf("%R/dir?ci=%T&name=%T", zCI, zPrefix);
229 if( nD==0 ){
230 style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
231 }
232 }else{
233 @ in any check-in</h2>
234 zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
235 }
236 if( linkTrunk ){
237 style_submenu_element("Trunk", "%s",
238 url_render(&sURI, "ci", "trunk", 0, 0));
239 }
240 if( linkTip ){
241 style_submenu_element("Tip", "%s", url_render(&sURI, "ci", "tip", 0, 0));
242 }
243 if( zD ){
244 style_submenu_element("History","%R/timeline?chng=%T/*", zD);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245 }
246 style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
247 style_submenu_element("Tree-View", "%s",
248 url_render(&sURI, "type", "tree", 0, 0));
249
@@ -282,12 +320,11 @@
320 zFN++;
321 @ <li class="dir">%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li>
322 }else{
323 const char *zLink;
324 if( zCI ){
325 zLink = href("%R/file?name=%T%T&ci=%T",zPrefix,zFN,zCI);
 
326 }else{
327 zLink = href("%R/finfo?name=%T%T",zPrefix,zFN);
328 }
329 @ <li class="%z(fileext_class(zFN))">%z(zLink)%h(zFN)</a></li>
330 }
@@ -612,11 +649,15 @@
649 HQuery sURI; /* Hyperlink */
650 int startExpanded; /* True to start out with the tree expanded */
651 int showDirOnly; /* Show directories only. Omit files */
652 int nDir = 0; /* Number of directories. Used for ID attributes */
653 char *zProjectName = db_get("project-name", 0);
654 int isSymbolicCI = 0; /* ci= is a symbolic name, not a hash prefix */
655 int isBranchCI = 0; /* ci= refers to a branch name */
656 char *zHeader = 0;
657
658 if( zCI && strlen(zCI)==0 ){ zCI = 0; }
659 if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; }
660 memset(&sTree, 0, sizeof(sTree));
661 login_check_credentials();
662 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
663 while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
@@ -624,14 +665,12 @@
665 pathelementFunc, 0, 0);
666 url_initialize(&sURI, "tree");
667 cgi_query_parameters_to_url(&sURI);
668 if( PB("nofiles") ){
669 showDirOnly = 1;
 
670 }else{
671 showDirOnly = 0;
 
672 }
673 style_adunit_config(ADUNIT_RIGHT_OK);
674 if( PB("expand") ){
675 startExpanded = 1;
676 }else{
@@ -660,37 +699,54 @@
699 linkTip = rid != symbolic_name_to_rid("tip", "ci");
700 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
701 rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
702 zNow = db_text("", "SELECT datetime(mtime,toLocal())"
703 " FROM event WHERE objid=%d", rid);
704 isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI)) != 0);
705 isBranchCI = branch_includes_uuid(zCI, zUuid);
706 }else{
707 zCI = 0;
708 }
709 }
710 if( zCI==0 ){
711 rNow = db_double(0.0, "SELECT max(mtime) FROM event");
712 zNow = db_text("", "SELECT datetime(max(mtime),toLocal()) FROM event");
713 }
714
715 assert( isSymbolicCI==0 || (zCI!=0 && zCI[0]!=0) );
716 if( zD==0 ){
717 if( zCI ){
718 zHeader = mprintf("Top-level Files of %s", zCI);
719 }else{
720 zHeader = mprintf("All Top-level Files");
721 }
722 }else{
723 if( zCI ){
724 zHeader = mprintf("Files in %s/ of %s", zD, zCI);
725 }else{
726 zHeader = mprintf("All File in %s/", zD);
727 }
728 }
729 style_header("%s", zHeader);
730 fossil_free(zHeader);
731
732 /* Compute the title of the page */
733 blob_zero(&dirname);
734 if( zD ){
735 blob_append(&dirname, "within directory ", -1);
736 hyperlinked_path(zD, &dirname, zCI, "tree", zREx, 0);
737 if( zRE ) blob_appendf(&dirname, " matching \"%s\"", zRE);
738 style_submenu_element("Top-Level", "%s",
739 url_render(&sURI, "name", 0, 0, 0));
740 }else if( zRE ){
741 blob_appendf(&dirname, "matching \"%s\"", zRE);
 
 
742 }
743 style_submenu_binary("mtime","Sort By Time","Sort By Filename", 0);
744 if( zCI ){
745 style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
746 if( nD==0 && !showDirOnly ){
747 style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
748 }
749 }
750 if( linkTrunk ){
751 style_submenu_element("Trunk", "%s",
752 url_render(&sURI, "ci", "trunk", 0, 0));
@@ -745,10 +801,11 @@
801 tree_add_node(&sTree, zName, zUuid, mtime);
802 nFile++;
803 }
804 db_finalize(&q);
805 }
806 style_submenu_checkbox("nofiles", "Folders Only", 0, 0);
807
808 if( showDirOnly ){
809 for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
810 if( p->pChild!=0 && p->nFullName>nD ) nFile++;
811 }
@@ -755,18 +812,24 @@
812 zObjType = "Folders";
813 }else{
814 zObjType = "Files";
815 }
816
817 if( zCI && strcmp(zCI,"tip")==0 ){
818 @ <h2>%s(zObjType) in the %z(href("%R/info?name=tip"))latest check-in</a>
819 }else if( isBranchCI ){
820 @ <h2>%s(zObjType) in the %z(href("%R/info?name=%T",zCI))latest check-in\
821 @ </a> for branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a>
822 if( blob_size(&dirname) ){
823 @ and %s(blob_str(&dirname))</h2>
824 }
825 }else if( zCI ){
826 @ <h2>%s(zObjType) for check-in \
827 @ %z(href("%R/info?name=%T",zCI))%h(zCI)</a></h2>
828 if( blob_size(&dirname) ){
829 @ and %s(blob_str(&dirname))</h2>
830 }
831 }else{
832 int n = db_int(0, "SELECT count(*) FROM plink");
833 @ <h2>%s(zObjType) from all %d(n) check-ins %s(blob_str(&dirname))
834 }
835 if( useMtime ){
@@ -824,11 +887,11 @@
887 nDir++;
888 }else if( !showDirOnly ){
889 const char *zFileClass = fileext_class(p->zName);
890 char *zLink;
891 if( zCI ){
892 zLink = href("%R/file?name=%T&ci=%T",p->zFullName,zCI);
893 }else{
894 zLink = href("%R/finfo?name=%T",p->zFullName);
895 }
896 @ <li class="%z(zFileClass)%s(zLastClass)"><div class="filetreeline">
897 @ %z(zLink)%h(p->zName)</a>
@@ -1001,10 +1064,11 @@
1064 int rid;
1065 const char *zName;
1066 const char *zGlob;
1067 const char *zUuid;
1068 const char *zNow; /* Time of check-in */
1069 int isBranchCI; /* name= is a branch name */
1070 int showId = PB("showid");
1071 Stmt q1, q2;
1072 double baseTime;
1073 login_check_credentials();
1074 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
@@ -1014,28 +1078,34 @@
1078 rid = symbolic_name_to_rid(zName, "ci");
1079 if( rid==0 ){
1080 fossil_fatal("not a valid check-in: %s", zName);
1081 }
1082 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1083 isBranchCI = branch_includes_uuid(zName,zUuid);
1084 baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
1085 zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
1086 " WHERE objid=%d", rid);
1087 style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
1088 style_header("File Ages");
1089 zGlob = P("glob");
1090 compute_fileage(rid,zGlob);
1091 db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
1092
1093 if( fossil_strcmp(zName,"tip")==0 ){
1094 @ <h1>Files in the %z(href("%R/info?name=tip"))latest check-in</a>
1095 }else if( isBranchCI ){
1096 @ <h1>Files in the %z(href("%R/info?name=%T",zName))latest check-in</a>
1097 @ of branch %z(href("%R/timeline?r=%T",zName))%h(zName)</a>
1098 }else{
1099 @ <h1>Files in check-in %z(href("%R/info?name=%T",zName))%h(zName)</a>
1100 }
1101 if( zGlob && zGlob[0] ){
1102 @ that match "%h(zGlob)"
1103 }
1104 @ ordered by age</h1>
1105 @
1106 @ <p>File ages are expressed relative to the check-in time of
 
1107 @ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
1108 @
1109 @ <div class='fileage'><table>
1110 @ <tr><th>Age</th><th>Files</th><th>Check-in</th></tr>
1111 db_prepare(&q1,
@@ -1050,14 +1120,13 @@
1120 " AND blob.rid=event.objid\n"
1121 " ORDER BY event.mtime DESC;",
1122 TAG_BRANCH
1123 );
1124 db_prepare(&q2,
1125 "SELECT filename.name, fileage.fid\n"
1126 " FROM fileage, filename\n"
1127 " WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
 
1128 );
1129 while( db_step(&q1)==SQLITE_ROW ){
1130 double age = baseTime - db_column_double(&q1, 0);
1131 int mid = db_column_int(&q1, 1);
1132 const char *zUuid = db_column_text(&q1, 2);
@@ -1067,24 +1136,24 @@
1136 char *zAge = human_readable_age(age);
1137 @ <tr><td>%s(zAge)</td>
1138 @ <td>
1139 db_bind_int(&q2, ":mid", mid);
1140 while( db_step(&q2)==SQLITE_ROW ){
1141 const char *zFile = db_column_text(&q2,0);
1142 @ %z(href("%R/file?name=%T&ci=%!S",zFile,zUuid))%h(zFile)</a> \
 
1143 if( showId ){
1144 int fid = db_column_int(&q2,1);
1145 @ (%d(fid))<br />
1146 }else{
1147 @ </a><br />
1148 }
1149 }
1150 db_reset(&q2);
1151 @ </td>
1152 @ <td>
1153 @ %W(zComment)
1154 @ (check-in:&nbsp;%z(href("%R/info/%!S",zUuid))%S(zUuid)</a>,
1155 if( showId ){
1156 @ id: %d(mid)
1157 }
1158 @ user:&nbsp;%z(href("%R/timeline?u=%t&c=%!S&nd",zUser,zUuid))%h(zUser)</a>,
1159 @ branch:&nbsp;\
1160
+10 -2
--- src/builtin.c
+++ src/builtin.c
@@ -55,17 +55,25 @@
5555
return (char*)builtin_file(zFilename, 0);
5656
}
5757
5858
/*
5959
** COMMAND: test-builtin-list
60
+**
61
+** If -verbose is used, it outputs a line at the end
62
+** with the total item count and size.
6063
**
6164
** List the names and sizes of all built-in resources.
6265
*/
6366
void test_builtin_list(void){
64
- int i;
67
+ int i, size = 0;;
6568
for(i=0; i<count(aBuiltinFiles); i++){
66
- fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,aBuiltinFiles[i].nByte);
69
+ const int n = aBuiltinFiles[i].nByte;
70
+ fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,n);
71
+ size += n;
72
+ }
73
+ if(find_option("verbose","v",0)!=0){
74
+ fossil_print("%d entries totaling %d bytes\n", i, size);
6775
}
6876
}
6977
7078
/*
7179
** WEBPAGE: test-builtin-files
7280
--- src/builtin.c
+++ src/builtin.c
@@ -55,17 +55,25 @@
55 return (char*)builtin_file(zFilename, 0);
56 }
57
58 /*
59 ** COMMAND: test-builtin-list
 
 
 
60 **
61 ** List the names and sizes of all built-in resources.
62 */
63 void test_builtin_list(void){
64 int i;
65 for(i=0; i<count(aBuiltinFiles); i++){
66 fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,aBuiltinFiles[i].nByte);
 
 
 
 
 
67 }
68 }
69
70 /*
71 ** WEBPAGE: test-builtin-files
72
--- src/builtin.c
+++ src/builtin.c
@@ -55,17 +55,25 @@
55 return (char*)builtin_file(zFilename, 0);
56 }
57
58 /*
59 ** COMMAND: test-builtin-list
60 **
61 ** If -verbose is used, it outputs a line at the end
62 ** with the total item count and size.
63 **
64 ** List the names and sizes of all built-in resources.
65 */
66 void test_builtin_list(void){
67 int i, size = 0;;
68 for(i=0; i<count(aBuiltinFiles); i++){
69 const int n = aBuiltinFiles[i].nByte;
70 fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,n);
71 size += n;
72 }
73 if(find_option("verbose","v",0)!=0){
74 fossil_print("%d entries totaling %d bytes\n", i, size);
75 }
76 }
77
78 /*
79 ** WEBPAGE: test-builtin-files
80
+11 -10
--- src/cgi.c
+++ src/cgi.c
@@ -174,12 +174,12 @@
174174
}
175175
176176
/*
177177
** Additional information used to form the HTTP reply
178178
*/
179
-static const char *zContentType = "text/html"; /* Content type of the reply */
180
-static const char *zReplyStatus = "OK"; /* Reply status description */
179
+static const char *zContentType = "text/html"; /* Content type of the reply */
180
+static const char *zReplyStatus = "OK"; /* Reply status description */
181181
static int iReplyStatus = 200; /* Reply status code */
182182
static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
183183
static int rangeStart = 0; /* Start of Range: */
184184
static int rangeEnd = 0; /* End of Range: plus 1 */
185185
@@ -293,11 +293,11 @@
293293
}
294294
if( g.isConst ){
295295
/* isConst means that the reply is guaranteed to be invariant, even
296296
** after configuration changes and/or Fossil binary recompiles. */
297297
fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
298
- }else if( etag_tag()!=0 ){
298
+ }else if( etag_tag()[0]!=0 ){
299299
fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
300300
fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
301301
}else{
302302
fprintf(g.httpOut, "Cache-control: no-cache\r\n");
303303
}
@@ -329,17 +329,17 @@
329329
*/
330330
331331
/* Content intended for logged in users should only be cached in
332332
** the browser, not some shared location.
333333
*/
334
- fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
335
- if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
336
- cgi_combine_header_and_body();
337
- blob_compress(&cgiContent[0], &cgiContent[0]);
338
- }
339
-
340334
if( iReplyStatus!=304 ) {
335
+ fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
336
+ if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
337
+ cgi_combine_header_and_body();
338
+ blob_compress(&cgiContent[0], &cgiContent[0]);
339
+ }
340
+
341341
if( is_gzippable() && iReplyStatus!=206 ){
342342
int i;
343343
gzip_begin(0);
344344
for( i=0; i<2; i++ ){
345345
int size = blob_size(&cgiContent[i]);
@@ -359,11 +359,12 @@
359359
fprintf(g.httpOut, "Content-Length: %d\r\n", total_size);
360360
}else{
361361
total_size = 0;
362362
}
363363
fprintf(g.httpOut, "\r\n");
364
- if( total_size>0 && iReplyStatus != 304
364
+ if( total_size>0
365
+ && iReplyStatus!=304
365366
&& fossil_strcmp(P("REQUEST_METHOD"),"HEAD")!=0
366367
){
367368
int i, size;
368369
for(i=0; i<2; i++){
369370
size = blob_size(&cgiContent[i]);
370371
--- src/cgi.c
+++ src/cgi.c
@@ -174,12 +174,12 @@
174 }
175
176 /*
177 ** Additional information used to form the HTTP reply
178 */
179 static const char *zContentType = "text/html"; /* Content type of the reply */
180 static const char *zReplyStatus = "OK"; /* Reply status description */
181 static int iReplyStatus = 200; /* Reply status code */
182 static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
183 static int rangeStart = 0; /* Start of Range: */
184 static int rangeEnd = 0; /* End of Range: plus 1 */
185
@@ -293,11 +293,11 @@
293 }
294 if( g.isConst ){
295 /* isConst means that the reply is guaranteed to be invariant, even
296 ** after configuration changes and/or Fossil binary recompiles. */
297 fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
298 }else if( etag_tag()!=0 ){
299 fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
300 fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
301 }else{
302 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
303 }
@@ -329,17 +329,17 @@
329 */
330
331 /* Content intended for logged in users should only be cached in
332 ** the browser, not some shared location.
333 */
334 fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
335 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
336 cgi_combine_header_and_body();
337 blob_compress(&cgiContent[0], &cgiContent[0]);
338 }
339
340 if( iReplyStatus!=304 ) {
 
 
 
 
 
 
341 if( is_gzippable() && iReplyStatus!=206 ){
342 int i;
343 gzip_begin(0);
344 for( i=0; i<2; i++ ){
345 int size = blob_size(&cgiContent[i]);
@@ -359,11 +359,12 @@
359 fprintf(g.httpOut, "Content-Length: %d\r\n", total_size);
360 }else{
361 total_size = 0;
362 }
363 fprintf(g.httpOut, "\r\n");
364 if( total_size>0 && iReplyStatus != 304
 
365 && fossil_strcmp(P("REQUEST_METHOD"),"HEAD")!=0
366 ){
367 int i, size;
368 for(i=0; i<2; i++){
369 size = blob_size(&cgiContent[i]);
370
--- src/cgi.c
+++ src/cgi.c
@@ -174,12 +174,12 @@
174 }
175
176 /*
177 ** Additional information used to form the HTTP reply
178 */
179 static const char *zContentType = "text/html"; /* Content type of the reply */
180 static const char *zReplyStatus = "OK"; /* Reply status description */
181 static int iReplyStatus = 200; /* Reply status code */
182 static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
183 static int rangeStart = 0; /* Start of Range: */
184 static int rangeEnd = 0; /* End of Range: plus 1 */
185
@@ -293,11 +293,11 @@
293 }
294 if( g.isConst ){
295 /* isConst means that the reply is guaranteed to be invariant, even
296 ** after configuration changes and/or Fossil binary recompiles. */
297 fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
298 }else if( etag_tag()[0]!=0 ){
299 fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
300 fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
301 }else{
302 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
303 }
@@ -329,17 +329,17 @@
329 */
330
331 /* Content intended for logged in users should only be cached in
332 ** the browser, not some shared location.
333 */
 
 
 
 
 
 
334 if( iReplyStatus!=304 ) {
335 fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
336 if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
337 cgi_combine_header_and_body();
338 blob_compress(&cgiContent[0], &cgiContent[0]);
339 }
340
341 if( is_gzippable() && iReplyStatus!=206 ){
342 int i;
343 gzip_begin(0);
344 for( i=0; i<2; i++ ){
345 int size = blob_size(&cgiContent[i]);
@@ -359,11 +359,12 @@
359 fprintf(g.httpOut, "Content-Length: %d\r\n", total_size);
360 }else{
361 total_size = 0;
362 }
363 fprintf(g.httpOut, "\r\n");
364 if( total_size>0
365 && iReplyStatus!=304
366 && fossil_strcmp(P("REQUEST_METHOD"),"HEAD")!=0
367 ){
368 int i, size;
369 for(i=0; i<2; i++){
370 size = blob_size(&cgiContent[i]);
371
+17 -31
--- src/comformat.c
+++ src/comformat.c
@@ -19,16 +19,10 @@
1919
** text on a TTY.
2020
*/
2121
#include "config.h"
2222
#include "comformat.h"
2323
#include <assert.h>
24
-#ifdef _WIN32
25
-# include <windows.h>
26
-#else
27
-# include <termios.h>
28
-# include <sys/ioctl.h>
29
-#endif
3024
3125
#if INTERFACE
3226
#define COMMENT_PRINT_NONE ((u32)0x00000000) /* No flags = non-legacy. */
3327
#define COMMENT_PRINT_LEGACY ((u32)0x00000001) /* Use legacy algorithm. */
3428
#define COMMENT_PRINT_TRIM_CRLF ((u32)0x00000002) /* Trim leading CR/LF. */
@@ -67,35 +61,27 @@
6761
*/
6862
static int comment_set_maxchars(
6963
int indent,
7064
int *pMaxChars
7165
){
72
-#if defined(_WIN32)
73
- CONSOLE_SCREEN_BUFFER_INFO csbi;
74
- memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
75
- if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){
76
- *pMaxChars = csbi.srWindow.Right - csbi.srWindow.Left - indent;
77
- return 1;
78
- }
79
- return 0;
80
-#elif defined(TIOCGWINSZ)
81
- struct winsize w;
82
- memset(&w, 0, sizeof(struct winsize));
83
- if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){
84
- *pMaxChars = w.ws_col - indent;
85
- return 1;
86
- }
87
- return 0;
88
-#else
89
- /*
90
- ** Fallback to using more-or-less the "legacy semantics" of hard-coding
91
- ** the maximum line length to a value reasonable for the vast majority
92
- ** of supported systems.
93
- */
94
- *pMaxChars = COMMENT_LEGACY_LINE_LENGTH - indent;
95
- return -1;
96
-#endif
66
+ struct TerminalSize ts;
67
+ if ( !terminal_get_size(&ts) ){
68
+ return 0;
69
+ }
70
+
71
+ if( ts.nColumns ){
72
+ *pMaxChars = ts.nColumns - indent;
73
+ return 1;
74
+ }else{
75
+ /*
76
+ ** Fallback to using more-or-less the "legacy semantics" of hard-coding
77
+ ** the maximum line length to a value reasonable for the vast majority
78
+ ** of supported systems.
79
+ */
80
+ *pMaxChars = COMMENT_LEGACY_LINE_LENGTH - indent;
81
+ return -1;
82
+ }
9783
}
9884
9985
/*
10086
** This function checks the current line being printed against the original
10187
** comment text. Upon matching, it updates the provided character and line
10288
--- src/comformat.c
+++ src/comformat.c
@@ -19,16 +19,10 @@
19 ** text on a TTY.
20 */
21 #include "config.h"
22 #include "comformat.h"
23 #include <assert.h>
24 #ifdef _WIN32
25 # include <windows.h>
26 #else
27 # include <termios.h>
28 # include <sys/ioctl.h>
29 #endif
30
31 #if INTERFACE
32 #define COMMENT_PRINT_NONE ((u32)0x00000000) /* No flags = non-legacy. */
33 #define COMMENT_PRINT_LEGACY ((u32)0x00000001) /* Use legacy algorithm. */
34 #define COMMENT_PRINT_TRIM_CRLF ((u32)0x00000002) /* Trim leading CR/LF. */
@@ -67,35 +61,27 @@
67 */
68 static int comment_set_maxchars(
69 int indent,
70 int *pMaxChars
71 ){
72 #if defined(_WIN32)
73 CONSOLE_SCREEN_BUFFER_INFO csbi;
74 memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
75 if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){
76 *pMaxChars = csbi.srWindow.Right - csbi.srWindow.Left - indent;
77 return 1;
78 }
79 return 0;
80 #elif defined(TIOCGWINSZ)
81 struct winsize w;
82 memset(&w, 0, sizeof(struct winsize));
83 if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){
84 *pMaxChars = w.ws_col - indent;
85 return 1;
86 }
87 return 0;
88 #else
89 /*
90 ** Fallback to using more-or-less the "legacy semantics" of hard-coding
91 ** the maximum line length to a value reasonable for the vast majority
92 ** of supported systems.
93 */
94 *pMaxChars = COMMENT_LEGACY_LINE_LENGTH - indent;
95 return -1;
96 #endif
97 }
98
99 /*
100 ** This function checks the current line being printed against the original
101 ** comment text. Upon matching, it updates the provided character and line
102
--- src/comformat.c
+++ src/comformat.c
@@ -19,16 +19,10 @@
19 ** text on a TTY.
20 */
21 #include "config.h"
22 #include "comformat.h"
23 #include <assert.h>
 
 
 
 
 
 
24
25 #if INTERFACE
26 #define COMMENT_PRINT_NONE ((u32)0x00000000) /* No flags = non-legacy. */
27 #define COMMENT_PRINT_LEGACY ((u32)0x00000001) /* Use legacy algorithm. */
28 #define COMMENT_PRINT_TRIM_CRLF ((u32)0x00000002) /* Trim leading CR/LF. */
@@ -67,35 +61,27 @@
61 */
62 static int comment_set_maxchars(
63 int indent,
64 int *pMaxChars
65 ){
66 struct TerminalSize ts;
67 if ( !terminal_get_size(&ts) ){
68 return 0;
69 }
70
71 if( ts.nColumns ){
72 *pMaxChars = ts.nColumns - indent;
73 return 1;
74 }else{
75 /*
76 ** Fallback to using more-or-less the "legacy semantics" of hard-coding
77 ** the maximum line length to a value reasonable for the vast majority
78 ** of supported systems.
79 */
80 *pMaxChars = COMMENT_LEGACY_LINE_LENGTH - indent;
81 return -1;
82 }
 
 
 
 
 
 
 
 
83 }
84
85 /*
86 ** This function checks the current line being printed against the original
87 ** comment text. Upon matching, it updates the provided character and line
88
+26 -1
--- src/diff.c
+++ src/diff.c
@@ -1826,14 +1826,39 @@
18261826
}
18271827
18281828
/*
18291829
** Extract the width of columns for side-by-side diff. Supply an
18301830
** appropriate default if no width is given.
1831
+**
1832
+** Calculate the default automatically, based on terminal's current width:
1833
+** term-width = 2*diff-col + diff-marker + 1
1834
+** diff-col = lineno + lmargin + text-width + rmargin
1835
+**
1836
+** text-width = (term-width - diff-marker - 1)/2 - lineno - lmargin - rmargin
18311837
*/
18321838
int diff_width(u64 diffFlags){
18331839
int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
1834
- if( w==0 ) w = 80;
1840
+ if( w==0 ){
1841
+ static struct {
1842
+ unsigned int lineno, lmargin, text, rmargin, marker;
1843
+ } sbsW = { 5, 2, 0, 0, 3 };
1844
+ const unsigned int wMin = 24, wMax = 132;
1845
+ unsigned int tw = terminal_get_width(80);
1846
+ unsigned int twMin =
1847
+ (wMin + sbsW.lineno + sbsW.lmargin + sbsW.rmargin)*2 + sbsW.marker + 1;
1848
+ unsigned int twMax =
1849
+ (wMax + sbsW.lineno + sbsW.lmargin + sbsW.rmargin)*2 + sbsW.marker + 1;
1850
+
1851
+ if( tw<twMin ){
1852
+ tw = twMin;
1853
+ }else if( tw>twMax ){
1854
+ tw = twMax;
1855
+ }
1856
+ sbsW.text =
1857
+ (tw - sbsW.marker - 1)/2 - sbsW.lineno - sbsW.lmargin - sbsW.rmargin;
1858
+ w = sbsW.text;
1859
+ }
18351860
return w;
18361861
}
18371862
18381863
/*
18391864
** Append the error message to pOut.
18401865
--- src/diff.c
+++ src/diff.c
@@ -1826,14 +1826,39 @@
1826 }
1827
1828 /*
1829 ** Extract the width of columns for side-by-side diff. Supply an
1830 ** appropriate default if no width is given.
 
 
 
 
 
 
1831 */
1832 int diff_width(u64 diffFlags){
1833 int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
1834 if( w==0 ) w = 80;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1835 return w;
1836 }
1837
1838 /*
1839 ** Append the error message to pOut.
1840
--- src/diff.c
+++ src/diff.c
@@ -1826,14 +1826,39 @@
1826 }
1827
1828 /*
1829 ** Extract the width of columns for side-by-side diff. Supply an
1830 ** appropriate default if no width is given.
1831 **
1832 ** Calculate the default automatically, based on terminal's current width:
1833 ** term-width = 2*diff-col + diff-marker + 1
1834 ** diff-col = lineno + lmargin + text-width + rmargin
1835 **
1836 ** text-width = (term-width - diff-marker - 1)/2 - lineno - lmargin - rmargin
1837 */
1838 int diff_width(u64 diffFlags){
1839 int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
1840 if( w==0 ){
1841 static struct {
1842 unsigned int lineno, lmargin, text, rmargin, marker;
1843 } sbsW = { 5, 2, 0, 0, 3 };
1844 const unsigned int wMin = 24, wMax = 132;
1845 unsigned int tw = terminal_get_width(80);
1846 unsigned int twMin =
1847 (wMin + sbsW.lineno + sbsW.lmargin + sbsW.rmargin)*2 + sbsW.marker + 1;
1848 unsigned int twMax =
1849 (wMax + sbsW.lineno + sbsW.lmargin + sbsW.rmargin)*2 + sbsW.marker + 1;
1850
1851 if( tw<twMin ){
1852 tw = twMin;
1853 }else if( tw>twMax ){
1854 tw = twMax;
1855 }
1856 sbsW.text =
1857 (tw - sbsW.marker - 1)/2 - sbsW.lineno - sbsW.lmargin - sbsW.rmargin;
1858 w = sbsW.text;
1859 }
1860 return w;
1861 }
1862
1863 /*
1864 ** Append the error message to pOut.
1865
+43 -6
--- src/etag.c
+++ src/etag.c
@@ -24,10 +24,12 @@
2424
** (1) The mtime on the Fossil executable
2525
** (2) The last change to the CONFIG table
2626
** (3) The last change to the EVENT table
2727
** (4) The value of the display cookie
2828
** (5) A hash value supplied by the page generator
29
+** (6) The details of the request URI
30
+** (7) The name user as determined by the login cookie
2931
**
3032
** Item (1) is always included in the ETag. The other elements are
3133
** optional. Because (1) is always included as part of the ETag, all
3234
** outstanding ETags can be invalidated by touching the fossil executable.
3335
**
@@ -60,32 +62,50 @@
6062
*/
6163
#define ETAG_CONFIG 0x01 /* Output depends on the CONFIG table */
6264
#define ETAG_DATA 0x02 /* Output depends on the EVENT table */
6365
#define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
6466
#define ETAG_HASH 0x08 /* Output depends on a hash */
67
+#define ETAG_QUERY 0x10 /* Output depends on PATH_INFO and QUERY_STRING */
68
+ /* and the g.zLogin value */
6569
#endif
6670
6771
static char zETag[33]; /* The generated ETag */
6872
static int iMaxAge = 0; /* The max-age parameter in the reply */
6973
static sqlite3_int64 iEtagMtime = 0; /* Last-Modified time */
74
+
75
+/*
76
+** Return a hash that changes every time the Fossil source code is
77
+** rebuilt.
78
+**
79
+** The FOSSIL_BUILD_HASH string that is returned here gets computed by
80
+** the mkversion utility program. The result is a hash of MANIFEST_UUID
81
+** and the unix timestamp for when the mkversion utility program is run.
82
+**
83
+** During development rebuilds, if you need the source code id to change
84
+** in order to invalidate caches, simply "touch" the "manifest" file in
85
+** the top of the source directory prior to running "make" and a new
86
+** FOSSIL_BUILD_HASH will be generated automatically.
87
+*/
88
+const char *fossil_exe_id(void){
89
+ return FOSSIL_BUILD_HASH;
90
+}
7091
7192
/*
7293
** Generate an ETag
7394
*/
7495
void etag_check(unsigned eFlags, const char *zHash){
75
- sqlite3_int64 mtime;
7696
const char *zIfNoneMatch;
7797
char zBuf[50];
7898
assert( zETag[0]==0 ); /* Only call this routine once! */
7999
80100
iMaxAge = 86400;
81101
md5sum_init();
82102
83
- /* Always include the mtime of the executable as part of the hash */
84
- mtime = file_mtime(g.nameOfExe, ExtFILE);
85
- sqlite3_snprintf(sizeof(zBuf),zBuf,"mtime: %lld\n", mtime);
86
- md5sum_step_text(zBuf, -1);
103
+ /* Always include the executable ID as part of the hash */
104
+ md5sum_step_text("exe-id: ", -1);
105
+ md5sum_step_text(fossil_exe_id(), -1);
106
+ md5sum_step_text("\n", 1);
87107
88108
if( (eFlags & ETAG_HASH)!=0 && zHash ){
89109
md5sum_step_text("hash: ", -1);
90110
md5sum_step_text(zHash, -1);
91111
md5sum_step_text("\n", 1);
@@ -98,11 +118,11 @@
98118
md5sum_step_text("\n", 1);
99119
iMaxAge = 60;
100120
}else if( eFlags & ETAG_CONFIG ){
101121
int iKey = db_int(0, "SELECT value FROM config WHERE name='cfgcnt'");
102122
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",iKey);
103
- md5sum_step_text("data: ", -1);
123
+ md5sum_step_text("config: ", -1);
104124
md5sum_step_text(zBuf, -1);
105125
md5sum_step_text("\n", 1);
106126
iMaxAge = 3600;
107127
}
108128
@@ -111,10 +131,27 @@
111131
md5sum_step_text("display-cookie: ", -1);
112132
md5sum_step_text(PD(DISPLAY_SETTINGS_COOKIE,""), -1);
113133
md5sum_step_text("\n", 1);
114134
iMaxAge = 0;
115135
}
136
+
137
+ /* Output depends on PATH_INFO and QUERY_STRING */
138
+ if( eFlags & ETAG_QUERY ){
139
+ const char *zQS = P("QUERY_STRING");
140
+ md5sum_step_text("query: ", -1);
141
+ md5sum_step_text(PD("PATH_INFO",""), -1);
142
+ if( zQS ){
143
+ md5sum_step_text("?", 1);
144
+ md5sum_step_text(zQS, -1);
145
+ }
146
+ md5sum_step_text("\n",1);
147
+ if( g.zLogin ){
148
+ md5sum_step_text("login: ", -1);
149
+ md5sum_step_text(g.zLogin, -1);
150
+ md5sum_step_text("\n", 1);
151
+ }
152
+ }
116153
117154
/* Generate the ETag */
118155
memcpy(zETag, md5sum_finish(0), 33);
119156
120157
/* Check to see if the generated ETag matches If-None-Match and
121158
--- src/etag.c
+++ src/etag.c
@@ -24,10 +24,12 @@
24 ** (1) The mtime on the Fossil executable
25 ** (2) The last change to the CONFIG table
26 ** (3) The last change to the EVENT table
27 ** (4) The value of the display cookie
28 ** (5) A hash value supplied by the page generator
 
 
29 **
30 ** Item (1) is always included in the ETag. The other elements are
31 ** optional. Because (1) is always included as part of the ETag, all
32 ** outstanding ETags can be invalidated by touching the fossil executable.
33 **
@@ -60,32 +62,50 @@
60 */
61 #define ETAG_CONFIG 0x01 /* Output depends on the CONFIG table */
62 #define ETAG_DATA 0x02 /* Output depends on the EVENT table */
63 #define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
64 #define ETAG_HASH 0x08 /* Output depends on a hash */
 
 
65 #endif
66
67 static char zETag[33]; /* The generated ETag */
68 static int iMaxAge = 0; /* The max-age parameter in the reply */
69 static sqlite3_int64 iEtagMtime = 0; /* Last-Modified time */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
71 /*
72 ** Generate an ETag
73 */
74 void etag_check(unsigned eFlags, const char *zHash){
75 sqlite3_int64 mtime;
76 const char *zIfNoneMatch;
77 char zBuf[50];
78 assert( zETag[0]==0 ); /* Only call this routine once! */
79
80 iMaxAge = 86400;
81 md5sum_init();
82
83 /* Always include the mtime of the executable as part of the hash */
84 mtime = file_mtime(g.nameOfExe, ExtFILE);
85 sqlite3_snprintf(sizeof(zBuf),zBuf,"mtime: %lld\n", mtime);
86 md5sum_step_text(zBuf, -1);
87
88 if( (eFlags & ETAG_HASH)!=0 && zHash ){
89 md5sum_step_text("hash: ", -1);
90 md5sum_step_text(zHash, -1);
91 md5sum_step_text("\n", 1);
@@ -98,11 +118,11 @@
98 md5sum_step_text("\n", 1);
99 iMaxAge = 60;
100 }else if( eFlags & ETAG_CONFIG ){
101 int iKey = db_int(0, "SELECT value FROM config WHERE name='cfgcnt'");
102 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",iKey);
103 md5sum_step_text("data: ", -1);
104 md5sum_step_text(zBuf, -1);
105 md5sum_step_text("\n", 1);
106 iMaxAge = 3600;
107 }
108
@@ -111,10 +131,27 @@
111 md5sum_step_text("display-cookie: ", -1);
112 md5sum_step_text(PD(DISPLAY_SETTINGS_COOKIE,""), -1);
113 md5sum_step_text("\n", 1);
114 iMaxAge = 0;
115 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
117 /* Generate the ETag */
118 memcpy(zETag, md5sum_finish(0), 33);
119
120 /* Check to see if the generated ETag matches If-None-Match and
121
--- src/etag.c
+++ src/etag.c
@@ -24,10 +24,12 @@
24 ** (1) The mtime on the Fossil executable
25 ** (2) The last change to the CONFIG table
26 ** (3) The last change to the EVENT table
27 ** (4) The value of the display cookie
28 ** (5) A hash value supplied by the page generator
29 ** (6) The details of the request URI
30 ** (7) The name user as determined by the login cookie
31 **
32 ** Item (1) is always included in the ETag. The other elements are
33 ** optional. Because (1) is always included as part of the ETag, all
34 ** outstanding ETags can be invalidated by touching the fossil executable.
35 **
@@ -60,32 +62,50 @@
62 */
63 #define ETAG_CONFIG 0x01 /* Output depends on the CONFIG table */
64 #define ETAG_DATA 0x02 /* Output depends on the EVENT table */
65 #define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
66 #define ETAG_HASH 0x08 /* Output depends on a hash */
67 #define ETAG_QUERY 0x10 /* Output depends on PATH_INFO and QUERY_STRING */
68 /* and the g.zLogin value */
69 #endif
70
71 static char zETag[33]; /* The generated ETag */
72 static int iMaxAge = 0; /* The max-age parameter in the reply */
73 static sqlite3_int64 iEtagMtime = 0; /* Last-Modified time */
74
75 /*
76 ** Return a hash that changes every time the Fossil source code is
77 ** rebuilt.
78 **
79 ** The FOSSIL_BUILD_HASH string that is returned here gets computed by
80 ** the mkversion utility program. The result is a hash of MANIFEST_UUID
81 ** and the unix timestamp for when the mkversion utility program is run.
82 **
83 ** During development rebuilds, if you need the source code id to change
84 ** in order to invalidate caches, simply "touch" the "manifest" file in
85 ** the top of the source directory prior to running "make" and a new
86 ** FOSSIL_BUILD_HASH will be generated automatically.
87 */
88 const char *fossil_exe_id(void){
89 return FOSSIL_BUILD_HASH;
90 }
91
92 /*
93 ** Generate an ETag
94 */
95 void etag_check(unsigned eFlags, const char *zHash){
 
96 const char *zIfNoneMatch;
97 char zBuf[50];
98 assert( zETag[0]==0 ); /* Only call this routine once! */
99
100 iMaxAge = 86400;
101 md5sum_init();
102
103 /* Always include the executable ID as part of the hash */
104 md5sum_step_text("exe-id: ", -1);
105 md5sum_step_text(fossil_exe_id(), -1);
106 md5sum_step_text("\n", 1);
107
108 if( (eFlags & ETAG_HASH)!=0 && zHash ){
109 md5sum_step_text("hash: ", -1);
110 md5sum_step_text(zHash, -1);
111 md5sum_step_text("\n", 1);
@@ -98,11 +118,11 @@
118 md5sum_step_text("\n", 1);
119 iMaxAge = 60;
120 }else if( eFlags & ETAG_CONFIG ){
121 int iKey = db_int(0, "SELECT value FROM config WHERE name='cfgcnt'");
122 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",iKey);
123 md5sum_step_text("config: ", -1);
124 md5sum_step_text(zBuf, -1);
125 md5sum_step_text("\n", 1);
126 iMaxAge = 3600;
127 }
128
@@ -111,10 +131,27 @@
131 md5sum_step_text("display-cookie: ", -1);
132 md5sum_step_text(PD(DISPLAY_SETTINGS_COOKIE,""), -1);
133 md5sum_step_text("\n", 1);
134 iMaxAge = 0;
135 }
136
137 /* Output depends on PATH_INFO and QUERY_STRING */
138 if( eFlags & ETAG_QUERY ){
139 const char *zQS = P("QUERY_STRING");
140 md5sum_step_text("query: ", -1);
141 md5sum_step_text(PD("PATH_INFO",""), -1);
142 if( zQS ){
143 md5sum_step_text("?", 1);
144 md5sum_step_text(zQS, -1);
145 }
146 md5sum_step_text("\n",1);
147 if( g.zLogin ){
148 md5sum_step_text("login: ", -1);
149 md5sum_step_text(g.zLogin, -1);
150 md5sum_step_text("\n", 1);
151 }
152 }
153
154 /* Generate the ETag */
155 memcpy(zETag, md5sum_finish(0), 33);
156
157 /* Check to see if the generated ETag matches If-None-Match and
158
+15 -11
--- src/finfo.c
+++ src/finfo.c
@@ -199,11 +199,11 @@
199199
TAG_BRANCH, zFilename, filename_collation(),
200200
iLimit, iOffset
201201
);
202202
blob_zero(&line);
203203
if( iBrief ){
204
- fossil_print("History of %s\n", blob_str(&fname));
204
+ fossil_print("History for %s\n", blob_str(&fname));
205205
}
206206
while( db_step(&q)==SQLITE_ROW ){
207207
const char *zFileUuid = db_column_text(&q, 0);
208208
const char *zCiUuid = db_column_text(&q,1);
209209
const char *zDate = db_column_text(&q, 2);
@@ -296,11 +296,11 @@
296296
** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM"
297297
** (eastward). Either no timezone suffix or "Z" means UTC.
298298
*/
299299
void finfo_page(void){
300300
Stmt q;
301
- const char *zFilename;
301
+ const char *zFilename = PD("name","");
302302
char zPrevDate[20];
303303
const char *zA;
304304
const char *zB;
305305
int n;
306306
int baseCheckin;
@@ -321,11 +321,16 @@
321321
const char *zMark; /* Mark this version of the file */
322322
int selRid = 0; /* RID of the marked file version */
323323
324324
login_check_credentials();
325325
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
326
- style_header("File History");
326
+ fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
327
+ if( fnid==0 ){
328
+ style_header("No such file");
329
+ }else{
330
+ style_header("History for %s", zFilename);
331
+ }
327332
login_anonymous_available();
328333
tmFlags = timeline_ss_submenu();
329334
if( tmFlags & TIMELINE_COLUMNAR ){
330335
zStyle = "Columnar";
331336
}else if( tmFlags & TIMELINE_COMPACT ){
@@ -340,13 +345,11 @@
340345
url_initialize(&url, "finfo");
341346
if( brBg ) url_add_parameter(&url, "brbg", 0);
342347
if( uBg ) url_add_parameter(&url, "ubg", 0);
343348
baseCheckin = name_to_rid_www("ci");
344349
zPrevDate[0] = 0;
345
- zFilename = PD("name","");
346350
cookie_render();
347
- fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
348351
if( fnid==0 ){
349352
@ No such file: %h(zFilename)
350353
style_footer();
351354
return;
352355
}
@@ -435,12 +438,13 @@
435438
}else if( n>0 ){
436439
blob_appendf(&title, "First %d ancestors of file ", n);
437440
}else{
438441
blob_appendf(&title, "Ancestors of file ");
439442
}
440
- blob_appendf(&title,"<a href='%R/finfo?name=%T'>%h</a>",
441
- zFilename, zFilename);
443
+ blob_appendf(&title,"%z%h</a>",
444
+ href("%R/file?name=%T&ci=%!S", zFilename, zUuid),
445
+ zFilename);
442446
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
443447
blob_append(&title, origCheckin ? " between " : " from ", -1);
444448
blob_appendf(&title, "check-in %z%S</a>", zLink, zUuid);
445449
if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin);
446450
fossil_free(zUuid);
@@ -449,12 +453,12 @@
449453
zLink = href("%R/info/%!S", zUuid);
450454
blob_appendf(&title, " and check-in %z%S</a>", zLink, zUuid);
451455
fossil_free(zUuid);
452456
}
453457
}else{
454
- blob_appendf(&title, "History of ");
455
- hyperlinked_path(zFilename, &title, 0, "tree", "");
458
+ blob_appendf(&title, "History for ");
459
+ hyperlinked_path(zFilename, &title, 0, "tree", "", LINKPATH_FILE);
456460
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
457461
}
458462
if( uBg ){
459463
blob_append(&title, " (color-coded by user)", -1);
460464
}
@@ -524,11 +528,11 @@
524528
@ <tr class='timelineSelected'>
525529
}else{
526530
@ <tr>
527531
}
528532
@ <td class="timelineTime">\
529
- @ %z(href("%R/artifact/%!S",zUuid))%s(zTime)</a></td>
533
+ @ %z(href("%R/file?name=%T&ci=%!S",zFilename,zCkin))%s(zTime)</a></td>
530534
@ <td class="timelineGraph"><div id="m%d(gidx)" class="tl-nodemark"></div>
531535
@ </td>
532536
if( zBgClr && zBgClr[0] ){
533537
@ <td class="timeline%s(zStyle)Cell" id='mc%d(gidx)'>
534538
}else{
@@ -561,11 +565,11 @@
561565
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
562566
}
563567
cgi_printf("<span class='timeline%sDetail'>", zStyle);
564568
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
565569
if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
566
- @ file:&nbsp;%z(href("%R/artifact/%!S",zUuid))[%S(zUuid)]</a>
570
+ @ file:&nbsp;%z(href("%R/file?name=%T&ci=%!S",zFilename,zCkin))[%S(zUuid)]</a>
567571
if( fShowId ){
568572
int srcId = delta_source_rid(frid);
569573
if( srcId>0 ){
570574
@ id:&nbsp;%d(frid)&larr;%d(srcId)
571575
}else{
572576
--- src/finfo.c
+++ src/finfo.c
@@ -199,11 +199,11 @@
199 TAG_BRANCH, zFilename, filename_collation(),
200 iLimit, iOffset
201 );
202 blob_zero(&line);
203 if( iBrief ){
204 fossil_print("History of %s\n", blob_str(&fname));
205 }
206 while( db_step(&q)==SQLITE_ROW ){
207 const char *zFileUuid = db_column_text(&q, 0);
208 const char *zCiUuid = db_column_text(&q,1);
209 const char *zDate = db_column_text(&q, 2);
@@ -296,11 +296,11 @@
296 ** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM"
297 ** (eastward). Either no timezone suffix or "Z" means UTC.
298 */
299 void finfo_page(void){
300 Stmt q;
301 const char *zFilename;
302 char zPrevDate[20];
303 const char *zA;
304 const char *zB;
305 int n;
306 int baseCheckin;
@@ -321,11 +321,16 @@
321 const char *zMark; /* Mark this version of the file */
322 int selRid = 0; /* RID of the marked file version */
323
324 login_check_credentials();
325 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
326 style_header("File History");
 
 
 
 
 
327 login_anonymous_available();
328 tmFlags = timeline_ss_submenu();
329 if( tmFlags & TIMELINE_COLUMNAR ){
330 zStyle = "Columnar";
331 }else if( tmFlags & TIMELINE_COMPACT ){
@@ -340,13 +345,11 @@
340 url_initialize(&url, "finfo");
341 if( brBg ) url_add_parameter(&url, "brbg", 0);
342 if( uBg ) url_add_parameter(&url, "ubg", 0);
343 baseCheckin = name_to_rid_www("ci");
344 zPrevDate[0] = 0;
345 zFilename = PD("name","");
346 cookie_render();
347 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
348 if( fnid==0 ){
349 @ No such file: %h(zFilename)
350 style_footer();
351 return;
352 }
@@ -435,12 +438,13 @@
435 }else if( n>0 ){
436 blob_appendf(&title, "First %d ancestors of file ", n);
437 }else{
438 blob_appendf(&title, "Ancestors of file ");
439 }
440 blob_appendf(&title,"<a href='%R/finfo?name=%T'>%h</a>",
441 zFilename, zFilename);
 
442 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
443 blob_append(&title, origCheckin ? " between " : " from ", -1);
444 blob_appendf(&title, "check-in %z%S</a>", zLink, zUuid);
445 if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin);
446 fossil_free(zUuid);
@@ -449,12 +453,12 @@
449 zLink = href("%R/info/%!S", zUuid);
450 blob_appendf(&title, " and check-in %z%S</a>", zLink, zUuid);
451 fossil_free(zUuid);
452 }
453 }else{
454 blob_appendf(&title, "History of ");
455 hyperlinked_path(zFilename, &title, 0, "tree", "");
456 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
457 }
458 if( uBg ){
459 blob_append(&title, " (color-coded by user)", -1);
460 }
@@ -524,11 +528,11 @@
524 @ <tr class='timelineSelected'>
525 }else{
526 @ <tr>
527 }
528 @ <td class="timelineTime">\
529 @ %z(href("%R/artifact/%!S",zUuid))%s(zTime)</a></td>
530 @ <td class="timelineGraph"><div id="m%d(gidx)" class="tl-nodemark"></div>
531 @ </td>
532 if( zBgClr && zBgClr[0] ){
533 @ <td class="timeline%s(zStyle)Cell" id='mc%d(gidx)'>
534 }else{
@@ -561,11 +565,11 @@
561 cgi_printf("<span class='clutter' id='detail-%d'>",frid);
562 }
563 cgi_printf("<span class='timeline%sDetail'>", zStyle);
564 if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
565 if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
566 @ file:&nbsp;%z(href("%R/artifact/%!S",zUuid))[%S(zUuid)]</a>
567 if( fShowId ){
568 int srcId = delta_source_rid(frid);
569 if( srcId>0 ){
570 @ id:&nbsp;%d(frid)&larr;%d(srcId)
571 }else{
572
--- src/finfo.c
+++ src/finfo.c
@@ -199,11 +199,11 @@
199 TAG_BRANCH, zFilename, filename_collation(),
200 iLimit, iOffset
201 );
202 blob_zero(&line);
203 if( iBrief ){
204 fossil_print("History for %s\n", blob_str(&fname));
205 }
206 while( db_step(&q)==SQLITE_ROW ){
207 const char *zFileUuid = db_column_text(&q, 0);
208 const char *zCiUuid = db_column_text(&q,1);
209 const char *zDate = db_column_text(&q, 2);
@@ -296,11 +296,11 @@
296 ** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM"
297 ** (eastward). Either no timezone suffix or "Z" means UTC.
298 */
299 void finfo_page(void){
300 Stmt q;
301 const char *zFilename = PD("name","");
302 char zPrevDate[20];
303 const char *zA;
304 const char *zB;
305 int n;
306 int baseCheckin;
@@ -321,11 +321,16 @@
321 const char *zMark; /* Mark this version of the file */
322 int selRid = 0; /* RID of the marked file version */
323
324 login_check_credentials();
325 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
326 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
327 if( fnid==0 ){
328 style_header("No such file");
329 }else{
330 style_header("History for %s", zFilename);
331 }
332 login_anonymous_available();
333 tmFlags = timeline_ss_submenu();
334 if( tmFlags & TIMELINE_COLUMNAR ){
335 zStyle = "Columnar";
336 }else if( tmFlags & TIMELINE_COMPACT ){
@@ -340,13 +345,11 @@
345 url_initialize(&url, "finfo");
346 if( brBg ) url_add_parameter(&url, "brbg", 0);
347 if( uBg ) url_add_parameter(&url, "ubg", 0);
348 baseCheckin = name_to_rid_www("ci");
349 zPrevDate[0] = 0;
 
350 cookie_render();
 
351 if( fnid==0 ){
352 @ No such file: %h(zFilename)
353 style_footer();
354 return;
355 }
@@ -435,12 +438,13 @@
438 }else if( n>0 ){
439 blob_appendf(&title, "First %d ancestors of file ", n);
440 }else{
441 blob_appendf(&title, "Ancestors of file ");
442 }
443 blob_appendf(&title,"%z%h</a>",
444 href("%R/file?name=%T&ci=%!S", zFilename, zUuid),
445 zFilename);
446 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
447 blob_append(&title, origCheckin ? " between " : " from ", -1);
448 blob_appendf(&title, "check-in %z%S</a>", zLink, zUuid);
449 if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin);
450 fossil_free(zUuid);
@@ -449,12 +453,12 @@
453 zLink = href("%R/info/%!S", zUuid);
454 blob_appendf(&title, " and check-in %z%S</a>", zLink, zUuid);
455 fossil_free(zUuid);
456 }
457 }else{
458 blob_appendf(&title, "History for ");
459 hyperlinked_path(zFilename, &title, 0, "tree", "", LINKPATH_FILE);
460 if( fShowId ) blob_appendf(&title, " (%d)", fnid);
461 }
462 if( uBg ){
463 blob_append(&title, " (color-coded by user)", -1);
464 }
@@ -524,11 +528,11 @@
528 @ <tr class='timelineSelected'>
529 }else{
530 @ <tr>
531 }
532 @ <td class="timelineTime">\
533 @ %z(href("%R/file?name=%T&ci=%!S",zFilename,zCkin))%s(zTime)</a></td>
534 @ <td class="timelineGraph"><div id="m%d(gidx)" class="tl-nodemark"></div>
535 @ </td>
536 if( zBgClr && zBgClr[0] ){
537 @ <td class="timeline%s(zStyle)Cell" id='mc%d(gidx)'>
538 }else{
@@ -561,11 +565,11 @@
565 cgi_printf("<span class='clutter' id='detail-%d'>",frid);
566 }
567 cgi_printf("<span class='timeline%sDetail'>", zStyle);
568 if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
569 if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
570 @ file:&nbsp;%z(href("%R/file?name=%T&ci=%!S",zFilename,zCkin))[%S(zUuid)]</a>
571 if( fShowId ){
572 int srcId = delta_source_rid(frid);
573 if( srcId>0 ){
574 @ id:&nbsp;%d(frid)&larr;%d(srcId)
575 }else{
576
+181 -121
--- src/info.c
+++ src/info.c
@@ -1340,33 +1340,22 @@
13401340
13411341
/*
13421342
** Possible flags for the second parameter to
13431343
** object_description()
13441344
*/
1345
-#define OBJDESC_DETAIL 0x0001 /* more detail */
1345
+#define OBJDESC_DETAIL 0x0001 /* Show more detail */
13461346
#define OBJDESC_BASE 0x0002 /* Set <base> using this object */
13471347
#endif
13481348
13491349
/*
13501350
** Write a description of an object to the www reply.
1351
-**
1352
-** If the object is a file then mention:
1353
-**
1354
-** * It's artifact ID
1355
-** * All its filenames
1356
-** * The check-in it was part of, with times and users
1357
-**
1358
-** If the object is a manifest, then mention:
1359
-**
1360
-** * It's artifact ID
1361
-** * date of check-in
1362
-** * Comment & user
13631351
*/
13641352
int object_description(
1365
- int rid, /* The artifact ID */
1353
+ int rid, /* The artifact ID for the object to describe */
13661354
u32 objdescFlags, /* Flags to control display */
1367
- Blob *pDownloadName /* Fill with an appropriate download name */
1355
+ const char *zFileName, /* For file objects, use this name. Can be NULL */
1356
+ Blob *pDownloadName /* Fill with a good download name. Can be NULL */
13681357
){
13691358
Stmt q;
13701359
int cnt = 0;
13711360
int nWiki = 0;
13721361
int objType = 0;
@@ -1401,10 +1390,11 @@
14011390
const char *zVers = db_column_text(&q, 4);
14021391
int mPerm = db_column_int(&q, 5);
14031392
const char *zBr = db_column_text(&q, 6);
14041393
int szFile = db_column_int(&q,7);
14051394
int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0;
1395
+ if( zFileName && fossil_strcmp(zName,zFileName)!=0 ) continue;
14061396
if( sameFilename && !showDetail ){
14071397
if( cnt==1 ){
14081398
@ %z(href("%R/whatis/%!S",zUuid))[more...]</a>
14091399
}
14101400
cnt++;
@@ -1671,12 +1661,12 @@
16711661
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
16721662
cookie_link_parameter("diff","diff","2");
16731663
diffType = atoi(PD("diff","2"));
16741664
cookie_render();
16751665
if( P("from") && P("to") ){
1676
- v1 = artifact_from_ci_and_filename(0, "from");
1677
- v2 = artifact_from_ci_and_filename(0, "to");
1666
+ v1 = artifact_from_ci_and_filename("from");
1667
+ v2 = artifact_from_ci_and_filename("to");
16781668
}else{
16791669
Stmt q;
16801670
v1 = name_to_rid_www("v1");
16811671
v2 = name_to_rid_www("v2");
16821672
@@ -1747,13 +1737,13 @@
17471737
@ %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a> To
17481738
@ %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>.</h2>
17491739
}else{
17501740
@ <h2>Differences From
17511741
@ Artifact %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a>:</h2>
1752
- object_description(v1, objdescFlags, 0);
1742
+ object_description(v1, objdescFlags,0, 0);
17531743
@ <h2>To Artifact %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>:</h2>
1754
- object_description(v2, objdescFlags, 0);
1744
+ object_description(v2, objdescFlags,0, 0);
17551745
}
17561746
if( pRe ){
17571747
@ <b>Only differences that match regular expression "%h(zRe)"
17581748
@ are shown.</b>
17591749
}
@@ -1773,12 +1763,12 @@
17731763
*/
17741764
void rawartifact_page(void){
17751765
int rid = 0;
17761766
char *zUuid;
17771767
1778
- if( P("ci") && P("filename") ){
1779
- rid = artifact_from_ci_and_filename(0, 0);
1768
+ if( P("ci") ){
1769
+ rid = artifact_from_ci_and_filename(0);
17801770
}
17811771
if( rid==0 ){
17821772
rid = name_to_rid_www("name");
17831773
}
17841774
login_check_credentials();
@@ -1937,11 +1927,11 @@
19371927
}else{
19381928
@ :</h2>
19391929
}
19401930
blob_zero(&downloadName);
19411931
if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1942
- object_description(rid, objdescFlags, &downloadName);
1932
+ object_description(rid, objdescFlags, 0, &downloadName);
19431933
style_submenu_element("Download", "%s/raw/%T?name=%s",
19441934
g.zTop, blob_str(&downloadName), zUuid);
19451935
@ <hr />
19461936
content_get(rid, &content);
19471937
@ <blockquote><pre>
@@ -1952,59 +1942,53 @@
19521942
19531943
/*
19541944
** Look for "ci" and "filename" query parameters. If found, try to
19551945
** use them to extract the record ID of an artifact for the file.
19561946
**
1957
-** Also look for "fn" as an alias for "filename". If either "filename"
1958
-** or "fn" is present but "ci" is missing, use "tip" as a default value
1959
-** for "ci".
1960
-**
1961
-** If zNameParam is not NULL, this use that parameter as the filename
1962
-** rather than "fn" or "filename".
1963
-**
1964
-** If pUrl is not NULL, then record the "ci" and "filename" values in
1965
-** pUrl.
1966
-**
1967
-** At least one of pUrl or zNameParam must be NULL.
1947
+** Also look for "fn" and "name" as an aliases for "filename". If any
1948
+** "filename" or "fn" or "name" are present but "ci" is missing, then
1949
+** use "tip" as the default value for "ci".
1950
+**
1951
+** If zNameParam is not NULL, then use that parameter as the filename
1952
+** rather than "fn" or "filename" or "name". the zNameParam is used
1953
+** for the from= and to= query parameters of /fdiff.
19681954
*/
1969
-int artifact_from_ci_and_filename(HQuery *pUrl, const char *zNameParam){
1955
+int artifact_from_ci_and_filename(const char *zNameParam){
19701956
const char *zFilename;
19711957
const char *zCI;
19721958
int cirid;
19731959
Manifest *pManifest;
19741960
ManifestFile *pFile;
1961
+ int rid = 0;
19751962
19761963
if( zNameParam ){
19771964
zFilename = P(zNameParam);
19781965
}else{
19791966
zFilename = P("filename");
19801967
if( zFilename==0 ){
19811968
zFilename = P("fn");
19821969
}
1970
+ if( zFilename==0 ){
1971
+ zFilename = P("name");
1972
+ }
19831973
}
19841974
if( zFilename==0 ) return 0;
19851975
1986
- zCI = P("ci");
1987
- cirid = name_to_typed_rid(zCI ? zCI : "tip", "ci");
1976
+ zCI = PD("ci", "tip");
1977
+ cirid = name_to_typed_rid(zCI, "ci");
19881978
if( cirid<=0 ) return 0;
19891979
pManifest = manifest_get(cirid, CFTYPE_MANIFEST, 0);
19901980
if( pManifest==0 ) return 0;
19911981
manifest_file_rewind(pManifest);
19921982
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
19931983
if( fossil_strcmp(zFilename, pFile->zName)==0 ){
1994
- int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid);
1995
- manifest_destroy(pManifest);
1996
- if( pUrl ){
1997
- assert( zNameParam==0 );
1998
- url_add_parameter(pUrl, "fn", zFilename);
1999
- if( zCI ) url_add_parameter(pUrl, "ci", zCI);
2000
- }
2001
- return rid;
1984
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid);
1985
+ break;
20021986
}
20031987
}
20041988
manifest_destroy(pManifest);
2005
- return 0;
1989
+ return rid;
20061990
}
20071991
20081992
/*
20091993
** The "z" argument is a string that contains the text of a source code
20101994
** file. This routine appends that text to the HTTP reply with line numbering.
@@ -2106,21 +2090,31 @@
21062090
** ln=N - highlight line number N
21072091
** ln=M-N - highlight lines M through N inclusive
21082092
** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive)
21092093
** verbose - show more detail in the description
21102094
** download - redirect to the download (artifact page only)
2111
-** name=SHA1HASH - Provide the SHA1HASH as a query parameter
2112
-** filename=NAME - Show information for content file NAME
2113
-** fn=NAME - "fn" is shorthand for "filename"
2114
-** ci=VERSION - The specific check-in to use for "filename=".
2095
+** name=NAME - filename or hash as a query parameter
2096
+** filename=NAME - alternative spelling for "name="
2097
+** fn=NAME - alternative spelling for "name="
2098
+** ci=VERSION - The specific check-in to use with "name=" to
2099
+** identify the file.
21152100
**
21162101
** The /artifact page show the complete content of a file
2117
-** identified by HASH as preformatted text. The
2118
-** /whatis page shows only a description of the file. The /file
2119
-** page shows the most recent version of the file or directory
2120
-** called NAME, or a list of the top-level directory if NAME is
2121
-** omitted.
2102
+** identified by HASH. The /whatis page shows only a description
2103
+** of how the artifact is used. The /file page shows the most recent
2104
+** version of the file or directory called NAME, or a list of the
2105
+** top-level directory if NAME is omitted.
2106
+**
2107
+** For /artifact and /whatis, the name= query parameter can refer to
2108
+** either the name of a file, or an artifact hash. If the ci= query
2109
+** parameter is also present, then name= must refer to a file name.
2110
+** If ci= is omitted, then the hash interpretation is preferred but
2111
+** if name= cannot be understood as a hash, a default "tip" value is
2112
+** used for ci=.
2113
+**
2114
+** For /file, name= can only be interpreted as a filename. As before,
2115
+** a default value of "tip" is used for ci= if ci= is omitted.
21222116
*/
21232117
void artifact_page(void){
21242118
int rid = 0;
21252119
Blob content;
21262120
const char *zMime;
@@ -2127,95 +2121,146 @@
21272121
Blob downloadName;
21282122
int renderAsWiki = 0;
21292123
int renderAsHtml = 0;
21302124
int objType;
21312125
int asText;
2132
- const char *zUuid;
2126
+ const char *zUuid = 0;
21332127
u32 objdescFlags = OBJDESC_BASE;
21342128
int descOnly = fossil_strcmp(g.zPath,"whatis")==0;
21352129
int isFile = fossil_strcmp(g.zPath,"file")==0;
21362130
const char *zLn = P("ln");
21372131
const char *zName = P("name");
2138
- HQuery url;
2139
-
2140
- url_initialize(&url, g.zPath);
2141
- rid = artifact_from_ci_and_filename(&url, 0);
2142
- if( rid==0 ){
2143
- url_add_parameter(&url, "name", zName);
2144
- if( isFile ){
2145
- /* Do a top-level directory listing in /file mode if no argument
2146
- ** specified */
2147
- if( zName==0 || zName[0]==0 ){
2148
- if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2149
- page_tree();
2150
- return;
2151
- }
2152
- /* Look for a single file with the given name */
2153
- rid = db_int(0,
2154
- "SELECT fid FROM filename, mlink, event"
2155
- " WHERE name=%Q"
2156
- " AND mlink.fnid=filename.fnid"
2157
- " AND event.objid=mlink.mid"
2158
- " ORDER BY event.mtime DESC LIMIT 1",
2159
- zName
2160
- );
2161
- /* If no file called NAME exists, instead look for a directory
2162
- ** with that name, and do a directory listing */
2163
- if( rid==0 ){
2164
- int nName = (int)strlen(zName);
2165
- if( nName && zName[nName-1]=='/' ) nName--;
2166
- if( db_exists(
2167
- "SELECT 1 FROM filename"
2168
- " WHERE name GLOB '%.*q/*' AND substr(name,1,%d)=='%.*q/';",
2169
- nName, zName, nName+1, nName, zName
2170
- ) ){
2171
- if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2172
- page_tree();
2173
- return;
2174
- }
2175
- }
2176
- /* If no file or directory called NAME: issue an error */
2177
- if( rid==0 ){
2178
- style_header("No such file");
2179
- @ File '%h(zName)' does not exist in this repository.
2180
- style_footer();
2181
- return;
2182
- }
2183
- }else{
2184
- rid = name_to_rid_www("name");
2185
- }
2186
- }
2187
-
2188
- login_check_credentials();
2189
- if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2190
- if( rid==0 ){
2191
- style_header("No such artifact");
2192
- @ Artifact '%h(zName)' does not exist in this repository.
2193
- style_footer();
2194
- return;
2195
- }
2132
+ const char *zCI = P("ci");
2133
+ HQuery url;
2134
+ char *zCIUuid = 0;
2135
+ int isSymbolicCI = 0; /* ci= exists and is a symbolic name, not a hash */
2136
+ int isBranchCI = 0; /* ci= refers to a branch name */
2137
+ char *zHeader = 0;
2138
+
2139
+ login_check_credentials();
2140
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2141
+
2142
+ /* Capture and normalize the name= and ci= query parameters */
2143
+ if( zName==0 ){
2144
+ zName = P("filename");
2145
+ if( zName==0 ){
2146
+ zName = P("fn");
2147
+ }
2148
+ }
2149
+ if( zCI && strlen(zCI)==0 ){ zCI = 0; }
2150
+ if( zCI
2151
+ && name_to_uuid2(zCI, "ci", &zCIUuid)
2152
+ && sqlite3_strnicmp(zCIUuid, zCI, strlen(zCI))!=0
2153
+ ){
2154
+ isSymbolicCI = 1;
2155
+ isBranchCI = branch_includes_uuid(zCI, zCIUuid);
2156
+ }
2157
+
2158
+ /* The name= query parameter (or at least one of its alternative
2159
+ ** spellings) is required. Except for /file, show a top-level
2160
+ ** directory listing if name= is omitted.
2161
+ */
2162
+ if( zName==0 ){
2163
+ if( isFile ){
2164
+ if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2165
+ page_tree();
2166
+ return;
2167
+ }
2168
+ style_header("Missing name= query parameter");
2169
+ @ The name= query parameter is missing
2170
+ style_footer();
2171
+ return;
2172
+ }
2173
+
2174
+ url_initialize(&url, g.zPath);
2175
+ url_add_parameter(&url, "name", zName);
2176
+ url_add_parameter(&url, "ci", zCI);
2177
+
2178
+ if( zCI==0 && !isFile ){
2179
+ /* If there is no ci= query parameter, then prefer to interpret
2180
+ ** name= as a hash for /artifact and /whatis. But for not for /file.
2181
+ ** For /file, a name= without a ci= while prefer to use the default
2182
+ ** "tip" value for ci=. */
2183
+ rid = name_to_rid(zName);
2184
+ }
2185
+ if( rid==0 ){
2186
+ rid = artifact_from_ci_and_filename(0);
2187
+ }
2188
+
2189
+ if( rid==0 ){ /* Artifact not found */
2190
+ if( isFile ){
2191
+ /* For /file, also check to see if name= refers to a directory,
2192
+ ** and if so, do a listing for that directory */
2193
+ int nName = (int)strlen(zName);
2194
+ if( nName && zName[nName-1]=='/' ) nName--;
2195
+ if( db_exists(
2196
+ "SELECT 1 FROM filename"
2197
+ " WHERE name GLOB '%.*q/*' AND substr(name,1,%d)=='%.*q/';",
2198
+ nName, zName, nName+1, nName, zName
2199
+ ) ){
2200
+ if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2201
+ page_tree();
2202
+ return;
2203
+ }
2204
+ style_header("No such file");
2205
+ @ File '%h(zName)' does not exist in this repository.
2206
+ }else{
2207
+ style_header("No such artifact");
2208
+ @ Artifact '%h(zName)' does not exist in this repository.
2209
+ }
2210
+ style_footer();
2211
+ return;
2212
+ }
2213
+
21962214
if( descOnly || P("verbose")!=0 ){
21972215
url_add_parameter(&url, "verbose", "1");
21982216
objdescFlags |= OBJDESC_DETAIL;
21992217
}
22002218
zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
2219
+
2220
+ asText = P("txt")!=0;
22012221
if( isFile ){
2202
- @ <h2>Latest version of file '%h(zName)':</h2>
2222
+ if( zCI==0 || fossil_strcmp(zCI,"tip")==0 ){
2223
+ zCI = "tip";
2224
+ @ <h2>File %z(href("%R/finfo?name=%T&m=tip",zName))%h(zName)</a>
2225
+ @ from the %z(href("%R/info/tip"))latest check-in</a></h2>
2226
+ }else{
2227
+ const char *zPath;
2228
+ Blob path;
2229
+ blob_zero(&path);
2230
+ hyperlinked_path(zName, &path, zCI, "dir", "", LINKPATH_FINFO);
2231
+ zPath = blob_str(&path);
2232
+ @ <h2>File %s(zPath) \
2233
+ if( isBranchCI ){
2234
+ @ on branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
2235
+ }else if( isSymbolicCI ){
2236
+ @ as of check-in %z(href("%R/info/%!S",zCIUuid))%s(zCI)</a></h2>
2237
+ }else{
2238
+ @ as of check-in [%z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a>]</h2>
2239
+ }
2240
+ blob_reset(&path);
2241
+ }
22032242
style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
2243
+ style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2244
+ zName, zCI);
2245
+ style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2246
+ zName, zCI);
2247
+ blob_init(&downloadName, zName, -1);
2248
+ objType = OBJTYPE_CONTENT;
22042249
}else{
22052250
@ <h2>Artifact
22062251
style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
22072252
if( g.perm.Setup ){
22082253
@ (%d(rid)):</h2>
22092254
}else{
22102255
@ :</h2>
22112256
}
2257
+ blob_zero(&downloadName);
2258
+ if( asText ) objdescFlags &= ~OBJDESC_BASE;
2259
+ objType = object_description(rid, objdescFlags,
2260
+ (isFile?zName:0), &downloadName);
22122261
}
2213
- blob_zero(&downloadName);
2214
- asText = P("txt")!=0;
2215
- if( asText ) objdescFlags &= ~OBJDESC_BASE;
2216
- objType = object_description(rid, objdescFlags, &downloadName);
22172262
if( !descOnly && P("download")!=0 ){
22182263
cgi_redirectf("%R/raw/%T?name=%s", blob_str(&downloadName),
22192264
db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid));
22202265
/*NOTREACHED*/
22212266
}
@@ -2226,13 +2271,28 @@
22262271
g.zTop, zUuid);
22272272
}else{
22282273
style_submenu_element("Shun", "%s/shun?shun=%s#addshun", g.zTop, zUuid);
22292274
}
22302275
}
2231
- style_header("%s", isFile ? "File Content" :
2232
- descOnly ? "Artifact Description" : "Artifact Content");
2233
- if( g.perm.Admin ){
2276
+
2277
+ if( isFile ){
2278
+ if( isSymbolicCI ){
2279
+ zHeader = mprintf("%s at %s", file_tail(zName), zCI);
2280
+ }else if( zCI ){
2281
+ zHeader = mprintf("%s at [%S]", file_tail(zName), zCIUuid);
2282
+ }else{
2283
+ zHeader = mprintf("%s", file_tail(zName));
2284
+ }
2285
+ }else if( descOnly ){
2286
+ zHeader = mprintf("Artifact Description [%S]", zUuid);
2287
+ }else{
2288
+ zHeader = mprintf("Artifact [%S]", zUuid);
2289
+ }
2290
+ style_header("%s", zHeader);
2291
+ fossil_free(zCIUuid);
2292
+ fossil_free(zHeader);
2293
+ if( !isFile && g.perm.Admin ){
22342294
Stmt q;
22352295
db_prepare(&q,
22362296
"SELECT coalesce(user.login,rcvfrom.uid),"
22372297
" datetime(rcvfrom.mtime,toLocal()), rcvfrom.ipaddr"
22382298
" FROM blob, rcvfrom LEFT JOIN user ON user.uid=rcvfrom.uid"
22392299
--- src/info.c
+++ src/info.c
@@ -1340,33 +1340,22 @@
1340
1341 /*
1342 ** Possible flags for the second parameter to
1343 ** object_description()
1344 */
1345 #define OBJDESC_DETAIL 0x0001 /* more detail */
1346 #define OBJDESC_BASE 0x0002 /* Set <base> using this object */
1347 #endif
1348
1349 /*
1350 ** Write a description of an object to the www reply.
1351 **
1352 ** If the object is a file then mention:
1353 **
1354 ** * It's artifact ID
1355 ** * All its filenames
1356 ** * The check-in it was part of, with times and users
1357 **
1358 ** If the object is a manifest, then mention:
1359 **
1360 ** * It's artifact ID
1361 ** * date of check-in
1362 ** * Comment & user
1363 */
1364 int object_description(
1365 int rid, /* The artifact ID */
1366 u32 objdescFlags, /* Flags to control display */
1367 Blob *pDownloadName /* Fill with an appropriate download name */
 
1368 ){
1369 Stmt q;
1370 int cnt = 0;
1371 int nWiki = 0;
1372 int objType = 0;
@@ -1401,10 +1390,11 @@
1401 const char *zVers = db_column_text(&q, 4);
1402 int mPerm = db_column_int(&q, 5);
1403 const char *zBr = db_column_text(&q, 6);
1404 int szFile = db_column_int(&q,7);
1405 int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0;
 
1406 if( sameFilename && !showDetail ){
1407 if( cnt==1 ){
1408 @ %z(href("%R/whatis/%!S",zUuid))[more...]</a>
1409 }
1410 cnt++;
@@ -1671,12 +1661,12 @@
1671 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1672 cookie_link_parameter("diff","diff","2");
1673 diffType = atoi(PD("diff","2"));
1674 cookie_render();
1675 if( P("from") && P("to") ){
1676 v1 = artifact_from_ci_and_filename(0, "from");
1677 v2 = artifact_from_ci_and_filename(0, "to");
1678 }else{
1679 Stmt q;
1680 v1 = name_to_rid_www("v1");
1681 v2 = name_to_rid_www("v2");
1682
@@ -1747,13 +1737,13 @@
1747 @ %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a> To
1748 @ %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>.</h2>
1749 }else{
1750 @ <h2>Differences From
1751 @ Artifact %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a>:</h2>
1752 object_description(v1, objdescFlags, 0);
1753 @ <h2>To Artifact %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>:</h2>
1754 object_description(v2, objdescFlags, 0);
1755 }
1756 if( pRe ){
1757 @ <b>Only differences that match regular expression "%h(zRe)"
1758 @ are shown.</b>
1759 }
@@ -1773,12 +1763,12 @@
1773 */
1774 void rawartifact_page(void){
1775 int rid = 0;
1776 char *zUuid;
1777
1778 if( P("ci") && P("filename") ){
1779 rid = artifact_from_ci_and_filename(0, 0);
1780 }
1781 if( rid==0 ){
1782 rid = name_to_rid_www("name");
1783 }
1784 login_check_credentials();
@@ -1937,11 +1927,11 @@
1937 }else{
1938 @ :</h2>
1939 }
1940 blob_zero(&downloadName);
1941 if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1942 object_description(rid, objdescFlags, &downloadName);
1943 style_submenu_element("Download", "%s/raw/%T?name=%s",
1944 g.zTop, blob_str(&downloadName), zUuid);
1945 @ <hr />
1946 content_get(rid, &content);
1947 @ <blockquote><pre>
@@ -1952,59 +1942,53 @@
1952
1953 /*
1954 ** Look for "ci" and "filename" query parameters. If found, try to
1955 ** use them to extract the record ID of an artifact for the file.
1956 **
1957 ** Also look for "fn" as an alias for "filename". If either "filename"
1958 ** or "fn" is present but "ci" is missing, use "tip" as a default value
1959 ** for "ci".
1960 **
1961 ** If zNameParam is not NULL, this use that parameter as the filename
1962 ** rather than "fn" or "filename".
1963 **
1964 ** If pUrl is not NULL, then record the "ci" and "filename" values in
1965 ** pUrl.
1966 **
1967 ** At least one of pUrl or zNameParam must be NULL.
1968 */
1969 int artifact_from_ci_and_filename(HQuery *pUrl, const char *zNameParam){
1970 const char *zFilename;
1971 const char *zCI;
1972 int cirid;
1973 Manifest *pManifest;
1974 ManifestFile *pFile;
 
1975
1976 if( zNameParam ){
1977 zFilename = P(zNameParam);
1978 }else{
1979 zFilename = P("filename");
1980 if( zFilename==0 ){
1981 zFilename = P("fn");
1982 }
 
 
 
1983 }
1984 if( zFilename==0 ) return 0;
1985
1986 zCI = P("ci");
1987 cirid = name_to_typed_rid(zCI ? zCI : "tip", "ci");
1988 if( cirid<=0 ) return 0;
1989 pManifest = manifest_get(cirid, CFTYPE_MANIFEST, 0);
1990 if( pManifest==0 ) return 0;
1991 manifest_file_rewind(pManifest);
1992 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
1993 if( fossil_strcmp(zFilename, pFile->zName)==0 ){
1994 int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid);
1995 manifest_destroy(pManifest);
1996 if( pUrl ){
1997 assert( zNameParam==0 );
1998 url_add_parameter(pUrl, "fn", zFilename);
1999 if( zCI ) url_add_parameter(pUrl, "ci", zCI);
2000 }
2001 return rid;
2002 }
2003 }
2004 manifest_destroy(pManifest);
2005 return 0;
2006 }
2007
2008 /*
2009 ** The "z" argument is a string that contains the text of a source code
2010 ** file. This routine appends that text to the HTTP reply with line numbering.
@@ -2106,21 +2090,31 @@
2106 ** ln=N - highlight line number N
2107 ** ln=M-N - highlight lines M through N inclusive
2108 ** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive)
2109 ** verbose - show more detail in the description
2110 ** download - redirect to the download (artifact page only)
2111 ** name=SHA1HASH - Provide the SHA1HASH as a query parameter
2112 ** filename=NAME - Show information for content file NAME
2113 ** fn=NAME - "fn" is shorthand for "filename"
2114 ** ci=VERSION - The specific check-in to use for "filename=".
 
2115 **
2116 ** The /artifact page show the complete content of a file
2117 ** identified by HASH as preformatted text. The
2118 ** /whatis page shows only a description of the file. The /file
2119 ** page shows the most recent version of the file or directory
2120 ** called NAME, or a list of the top-level directory if NAME is
2121 ** omitted.
 
 
 
 
 
 
 
 
 
2122 */
2123 void artifact_page(void){
2124 int rid = 0;
2125 Blob content;
2126 const char *zMime;
@@ -2127,95 +2121,146 @@
2127 Blob downloadName;
2128 int renderAsWiki = 0;
2129 int renderAsHtml = 0;
2130 int objType;
2131 int asText;
2132 const char *zUuid;
2133 u32 objdescFlags = OBJDESC_BASE;
2134 int descOnly = fossil_strcmp(g.zPath,"whatis")==0;
2135 int isFile = fossil_strcmp(g.zPath,"file")==0;
2136 const char *zLn = P("ln");
2137 const char *zName = P("name");
2138 HQuery url;
2139
2140 url_initialize(&url, g.zPath);
2141 rid = artifact_from_ci_and_filename(&url, 0);
2142 if( rid==0 ){
2143 url_add_parameter(&url, "name", zName);
2144 if( isFile ){
2145 /* Do a top-level directory listing in /file mode if no argument
2146 ** specified */
2147 if( zName==0 || zName[0]==0 ){
2148 if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2149 page_tree();
2150 return;
2151 }
2152 /* Look for a single file with the given name */
2153 rid = db_int(0,
2154 "SELECT fid FROM filename, mlink, event"
2155 " WHERE name=%Q"
2156 " AND mlink.fnid=filename.fnid"
2157 " AND event.objid=mlink.mid"
2158 " ORDER BY event.mtime DESC LIMIT 1",
2159 zName
2160 );
2161 /* If no file called NAME exists, instead look for a directory
2162 ** with that name, and do a directory listing */
2163 if( rid==0 ){
2164 int nName = (int)strlen(zName);
2165 if( nName && zName[nName-1]=='/' ) nName--;
2166 if( db_exists(
2167 "SELECT 1 FROM filename"
2168 " WHERE name GLOB '%.*q/*' AND substr(name,1,%d)=='%.*q/';",
2169 nName, zName, nName+1, nName, zName
2170 ) ){
2171 if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2172 page_tree();
2173 return;
2174 }
2175 }
2176 /* If no file or directory called NAME: issue an error */
2177 if( rid==0 ){
2178 style_header("No such file");
2179 @ File '%h(zName)' does not exist in this repository.
2180 style_footer();
2181 return;
2182 }
2183 }else{
2184 rid = name_to_rid_www("name");
2185 }
2186 }
2187
2188 login_check_credentials();
2189 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2190 if( rid==0 ){
2191 style_header("No such artifact");
2192 @ Artifact '%h(zName)' does not exist in this repository.
2193 style_footer();
2194 return;
2195 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2196 if( descOnly || P("verbose")!=0 ){
2197 url_add_parameter(&url, "verbose", "1");
2198 objdescFlags |= OBJDESC_DETAIL;
2199 }
2200 zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
 
 
2201 if( isFile ){
2202 @ <h2>Latest version of file '%h(zName)':</h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2203 style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
 
 
 
 
 
 
2204 }else{
2205 @ <h2>Artifact
2206 style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
2207 if( g.perm.Setup ){
2208 @ (%d(rid)):</h2>
2209 }else{
2210 @ :</h2>
2211 }
 
 
 
 
2212 }
2213 blob_zero(&downloadName);
2214 asText = P("txt")!=0;
2215 if( asText ) objdescFlags &= ~OBJDESC_BASE;
2216 objType = object_description(rid, objdescFlags, &downloadName);
2217 if( !descOnly && P("download")!=0 ){
2218 cgi_redirectf("%R/raw/%T?name=%s", blob_str(&downloadName),
2219 db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid));
2220 /*NOTREACHED*/
2221 }
@@ -2226,13 +2271,28 @@
2226 g.zTop, zUuid);
2227 }else{
2228 style_submenu_element("Shun", "%s/shun?shun=%s#addshun", g.zTop, zUuid);
2229 }
2230 }
2231 style_header("%s", isFile ? "File Content" :
2232 descOnly ? "Artifact Description" : "Artifact Content");
2233 if( g.perm.Admin ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2234 Stmt q;
2235 db_prepare(&q,
2236 "SELECT coalesce(user.login,rcvfrom.uid),"
2237 " datetime(rcvfrom.mtime,toLocal()), rcvfrom.ipaddr"
2238 " FROM blob, rcvfrom LEFT JOIN user ON user.uid=rcvfrom.uid"
2239
--- src/info.c
+++ src/info.c
@@ -1340,33 +1340,22 @@
1340
1341 /*
1342 ** Possible flags for the second parameter to
1343 ** object_description()
1344 */
1345 #define OBJDESC_DETAIL 0x0001 /* Show more detail */
1346 #define OBJDESC_BASE 0x0002 /* Set <base> using this object */
1347 #endif
1348
1349 /*
1350 ** Write a description of an object to the www reply.
 
 
 
 
 
 
 
 
 
 
 
 
1351 */
1352 int object_description(
1353 int rid, /* The artifact ID for the object to describe */
1354 u32 objdescFlags, /* Flags to control display */
1355 const char *zFileName, /* For file objects, use this name. Can be NULL */
1356 Blob *pDownloadName /* Fill with a good download name. Can be NULL */
1357 ){
1358 Stmt q;
1359 int cnt = 0;
1360 int nWiki = 0;
1361 int objType = 0;
@@ -1401,10 +1390,11 @@
1390 const char *zVers = db_column_text(&q, 4);
1391 int mPerm = db_column_int(&q, 5);
1392 const char *zBr = db_column_text(&q, 6);
1393 int szFile = db_column_int(&q,7);
1394 int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0;
1395 if( zFileName && fossil_strcmp(zName,zFileName)!=0 ) continue;
1396 if( sameFilename && !showDetail ){
1397 if( cnt==1 ){
1398 @ %z(href("%R/whatis/%!S",zUuid))[more...]</a>
1399 }
1400 cnt++;
@@ -1671,12 +1661,12 @@
1661 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1662 cookie_link_parameter("diff","diff","2");
1663 diffType = atoi(PD("diff","2"));
1664 cookie_render();
1665 if( P("from") && P("to") ){
1666 v1 = artifact_from_ci_and_filename("from");
1667 v2 = artifact_from_ci_and_filename("to");
1668 }else{
1669 Stmt q;
1670 v1 = name_to_rid_www("v1");
1671 v2 = name_to_rid_www("v2");
1672
@@ -1747,13 +1737,13 @@
1737 @ %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a> To
1738 @ %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>.</h2>
1739 }else{
1740 @ <h2>Differences From
1741 @ Artifact %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a>:</h2>
1742 object_description(v1, objdescFlags,0, 0);
1743 @ <h2>To Artifact %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>:</h2>
1744 object_description(v2, objdescFlags,0, 0);
1745 }
1746 if( pRe ){
1747 @ <b>Only differences that match regular expression "%h(zRe)"
1748 @ are shown.</b>
1749 }
@@ -1773,12 +1763,12 @@
1763 */
1764 void rawartifact_page(void){
1765 int rid = 0;
1766 char *zUuid;
1767
1768 if( P("ci") ){
1769 rid = artifact_from_ci_and_filename(0);
1770 }
1771 if( rid==0 ){
1772 rid = name_to_rid_www("name");
1773 }
1774 login_check_credentials();
@@ -1937,11 +1927,11 @@
1927 }else{
1928 @ :</h2>
1929 }
1930 blob_zero(&downloadName);
1931 if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1932 object_description(rid, objdescFlags, 0, &downloadName);
1933 style_submenu_element("Download", "%s/raw/%T?name=%s",
1934 g.zTop, blob_str(&downloadName), zUuid);
1935 @ <hr />
1936 content_get(rid, &content);
1937 @ <blockquote><pre>
@@ -1952,59 +1942,53 @@
1942
1943 /*
1944 ** Look for "ci" and "filename" query parameters. If found, try to
1945 ** use them to extract the record ID of an artifact for the file.
1946 **
1947 ** Also look for "fn" and "name" as an aliases for "filename". If any
1948 ** "filename" or "fn" or "name" are present but "ci" is missing, then
1949 ** use "tip" as the default value for "ci".
1950 **
1951 ** If zNameParam is not NULL, then use that parameter as the filename
1952 ** rather than "fn" or "filename" or "name". the zNameParam is used
1953 ** for the from= and to= query parameters of /fdiff.
 
 
 
 
1954 */
1955 int artifact_from_ci_and_filename(const char *zNameParam){
1956 const char *zFilename;
1957 const char *zCI;
1958 int cirid;
1959 Manifest *pManifest;
1960 ManifestFile *pFile;
1961 int rid = 0;
1962
1963 if( zNameParam ){
1964 zFilename = P(zNameParam);
1965 }else{
1966 zFilename = P("filename");
1967 if( zFilename==0 ){
1968 zFilename = P("fn");
1969 }
1970 if( zFilename==0 ){
1971 zFilename = P("name");
1972 }
1973 }
1974 if( zFilename==0 ) return 0;
1975
1976 zCI = PD("ci", "tip");
1977 cirid = name_to_typed_rid(zCI, "ci");
1978 if( cirid<=0 ) return 0;
1979 pManifest = manifest_get(cirid, CFTYPE_MANIFEST, 0);
1980 if( pManifest==0 ) return 0;
1981 manifest_file_rewind(pManifest);
1982 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
1983 if( fossil_strcmp(zFilename, pFile->zName)==0 ){
1984 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid);
1985 break;
 
 
 
 
 
 
1986 }
1987 }
1988 manifest_destroy(pManifest);
1989 return rid;
1990 }
1991
1992 /*
1993 ** The "z" argument is a string that contains the text of a source code
1994 ** file. This routine appends that text to the HTTP reply with line numbering.
@@ -2106,21 +2090,31 @@
2090 ** ln=N - highlight line number N
2091 ** ln=M-N - highlight lines M through N inclusive
2092 ** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive)
2093 ** verbose - show more detail in the description
2094 ** download - redirect to the download (artifact page only)
2095 ** name=NAME - filename or hash as a query parameter
2096 ** filename=NAME - alternative spelling for "name="
2097 ** fn=NAME - alternative spelling for "name="
2098 ** ci=VERSION - The specific check-in to use with "name=" to
2099 ** identify the file.
2100 **
2101 ** The /artifact page show the complete content of a file
2102 ** identified by HASH. The /whatis page shows only a description
2103 ** of how the artifact is used. The /file page shows the most recent
2104 ** version of the file or directory called NAME, or a list of the
2105 ** top-level directory if NAME is omitted.
2106 **
2107 ** For /artifact and /whatis, the name= query parameter can refer to
2108 ** either the name of a file, or an artifact hash. If the ci= query
2109 ** parameter is also present, then name= must refer to a file name.
2110 ** If ci= is omitted, then the hash interpretation is preferred but
2111 ** if name= cannot be understood as a hash, a default "tip" value is
2112 ** used for ci=.
2113 **
2114 ** For /file, name= can only be interpreted as a filename. As before,
2115 ** a default value of "tip" is used for ci= if ci= is omitted.
2116 */
2117 void artifact_page(void){
2118 int rid = 0;
2119 Blob content;
2120 const char *zMime;
@@ -2127,95 +2121,146 @@
2121 Blob downloadName;
2122 int renderAsWiki = 0;
2123 int renderAsHtml = 0;
2124 int objType;
2125 int asText;
2126 const char *zUuid = 0;
2127 u32 objdescFlags = OBJDESC_BASE;
2128 int descOnly = fossil_strcmp(g.zPath,"whatis")==0;
2129 int isFile = fossil_strcmp(g.zPath,"file")==0;
2130 const char *zLn = P("ln");
2131 const char *zName = P("name");
2132 const char *zCI = P("ci");
2133 HQuery url;
2134 char *zCIUuid = 0;
2135 int isSymbolicCI = 0; /* ci= exists and is a symbolic name, not a hash */
2136 int isBranchCI = 0; /* ci= refers to a branch name */
2137 char *zHeader = 0;
2138
2139 login_check_credentials();
2140 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2141
2142 /* Capture and normalize the name= and ci= query parameters */
2143 if( zName==0 ){
2144 zName = P("filename");
2145 if( zName==0 ){
2146 zName = P("fn");
2147 }
2148 }
2149 if( zCI && strlen(zCI)==0 ){ zCI = 0; }
2150 if( zCI
2151 && name_to_uuid2(zCI, "ci", &zCIUuid)
2152 && sqlite3_strnicmp(zCIUuid, zCI, strlen(zCI))!=0
2153 ){
2154 isSymbolicCI = 1;
2155 isBranchCI = branch_includes_uuid(zCI, zCIUuid);
2156 }
2157
2158 /* The name= query parameter (or at least one of its alternative
2159 ** spellings) is required. Except for /file, show a top-level
2160 ** directory listing if name= is omitted.
2161 */
2162 if( zName==0 ){
2163 if( isFile ){
2164 if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2165 page_tree();
2166 return;
2167 }
2168 style_header("Missing name= query parameter");
2169 @ The name= query parameter is missing
2170 style_footer();
2171 return;
2172 }
2173
2174 url_initialize(&url, g.zPath);
2175 url_add_parameter(&url, "name", zName);
2176 url_add_parameter(&url, "ci", zCI);
2177
2178 if( zCI==0 && !isFile ){
2179 /* If there is no ci= query parameter, then prefer to interpret
2180 ** name= as a hash for /artifact and /whatis. But for not for /file.
2181 ** For /file, a name= without a ci= while prefer to use the default
2182 ** "tip" value for ci=. */
2183 rid = name_to_rid(zName);
2184 }
2185 if( rid==0 ){
2186 rid = artifact_from_ci_and_filename(0);
2187 }
2188
2189 if( rid==0 ){ /* Artifact not found */
2190 if( isFile ){
2191 /* For /file, also check to see if name= refers to a directory,
2192 ** and if so, do a listing for that directory */
2193 int nName = (int)strlen(zName);
2194 if( nName && zName[nName-1]=='/' ) nName--;
2195 if( db_exists(
2196 "SELECT 1 FROM filename"
2197 " WHERE name GLOB '%.*q/*' AND substr(name,1,%d)=='%.*q/';",
2198 nName, zName, nName+1, nName, zName
2199 ) ){
2200 if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
2201 page_tree();
2202 return;
2203 }
2204 style_header("No such file");
2205 @ File '%h(zName)' does not exist in this repository.
2206 }else{
2207 style_header("No such artifact");
2208 @ Artifact '%h(zName)' does not exist in this repository.
2209 }
2210 style_footer();
2211 return;
2212 }
2213
2214 if( descOnly || P("verbose")!=0 ){
2215 url_add_parameter(&url, "verbose", "1");
2216 objdescFlags |= OBJDESC_DETAIL;
2217 }
2218 zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
2219
2220 asText = P("txt")!=0;
2221 if( isFile ){
2222 if( zCI==0 || fossil_strcmp(zCI,"tip")==0 ){
2223 zCI = "tip";
2224 @ <h2>File %z(href("%R/finfo?name=%T&m=tip",zName))%h(zName)</a>
2225 @ from the %z(href("%R/info/tip"))latest check-in</a></h2>
2226 }else{
2227 const char *zPath;
2228 Blob path;
2229 blob_zero(&path);
2230 hyperlinked_path(zName, &path, zCI, "dir", "", LINKPATH_FINFO);
2231 zPath = blob_str(&path);
2232 @ <h2>File %s(zPath) \
2233 if( isBranchCI ){
2234 @ on branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
2235 }else if( isSymbolicCI ){
2236 @ as of check-in %z(href("%R/info/%!S",zCIUuid))%s(zCI)</a></h2>
2237 }else{
2238 @ as of check-in [%z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a>]</h2>
2239 }
2240 blob_reset(&path);
2241 }
2242 style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
2243 style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2244 zName, zCI);
2245 style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2246 zName, zCI);
2247 blob_init(&downloadName, zName, -1);
2248 objType = OBJTYPE_CONTENT;
2249 }else{
2250 @ <h2>Artifact
2251 style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
2252 if( g.perm.Setup ){
2253 @ (%d(rid)):</h2>
2254 }else{
2255 @ :</h2>
2256 }
2257 blob_zero(&downloadName);
2258 if( asText ) objdescFlags &= ~OBJDESC_BASE;
2259 objType = object_description(rid, objdescFlags,
2260 (isFile?zName:0), &downloadName);
2261 }
 
 
 
 
2262 if( !descOnly && P("download")!=0 ){
2263 cgi_redirectf("%R/raw/%T?name=%s", blob_str(&downloadName),
2264 db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid));
2265 /*NOTREACHED*/
2266 }
@@ -2226,13 +2271,28 @@
2271 g.zTop, zUuid);
2272 }else{
2273 style_submenu_element("Shun", "%s/shun?shun=%s#addshun", g.zTop, zUuid);
2274 }
2275 }
2276
2277 if( isFile ){
2278 if( isSymbolicCI ){
2279 zHeader = mprintf("%s at %s", file_tail(zName), zCI);
2280 }else if( zCI ){
2281 zHeader = mprintf("%s at [%S]", file_tail(zName), zCIUuid);
2282 }else{
2283 zHeader = mprintf("%s", file_tail(zName));
2284 }
2285 }else if( descOnly ){
2286 zHeader = mprintf("Artifact Description [%S]", zUuid);
2287 }else{
2288 zHeader = mprintf("Artifact [%S]", zUuid);
2289 }
2290 style_header("%s", zHeader);
2291 fossil_free(zCIUuid);
2292 fossil_free(zHeader);
2293 if( !isFile && g.perm.Admin ){
2294 Stmt q;
2295 db_prepare(&q,
2296 "SELECT coalesce(user.login,rcvfrom.uid),"
2297 " datetime(rcvfrom.mtime,toLocal()), rcvfrom.ipaddr"
2298 " FROM blob, rcvfrom LEFT JOIN user ON user.uid=rcvfrom.uid"
2299
+1 -1
--- src/login.c
+++ src/login.c
@@ -1736,11 +1736,11 @@
17361736
if( iErrLine==5 ){
17371737
@ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
17381738
}
17391739
@ <tr>
17401740
@ <td class="form_label" align="right">Captcha:</td>
1741
- @ <td><input type="text" name="captcha" size="30"\
1741
+ @ <td><input type="text" name="captcha" \
17421742
@ value="%h(captchaIsCorrect?zDecoded:"")" size="30">
17431743
captcha_speakit_button(uSeed, "Speak the captcha text");
17441744
@ </td>
17451745
@ </tr>
17461746
if( iErrLine==6 ){
17471747
--- src/login.c
+++ src/login.c
@@ -1736,11 +1736,11 @@
1736 if( iErrLine==5 ){
1737 @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
1738 }
1739 @ <tr>
1740 @ <td class="form_label" align="right">Captcha:</td>
1741 @ <td><input type="text" name="captcha" size="30"\
1742 @ value="%h(captchaIsCorrect?zDecoded:"")" size="30">
1743 captcha_speakit_button(uSeed, "Speak the captcha text");
1744 @ </td>
1745 @ </tr>
1746 if( iErrLine==6 ){
1747
--- src/login.c
+++ src/login.c
@@ -1736,11 +1736,11 @@
1736 if( iErrLine==5 ){
1737 @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
1738 }
1739 @ <tr>
1740 @ <td class="form_label" align="right">Captcha:</td>
1741 @ <td><input type="text" name="captcha" \
1742 @ value="%h(captchaIsCorrect?zDecoded:"")" size="30">
1743 captcha_speakit_button(uSeed, "Speak the captcha text");
1744 @ </td>
1745 @ </tr>
1746 if( iErrLine==6 ){
1747
+12
--- src/main.mk
+++ src/main.mk
@@ -131,10 +131,11 @@
131131
$(SRCDIR)/statrep.c \
132132
$(SRCDIR)/style.c \
133133
$(SRCDIR)/sync.c \
134134
$(SRCDIR)/tag.c \
135135
$(SRCDIR)/tar.c \
136
+ $(SRCDIR)/terminal.c \
136137
$(SRCDIR)/th_main.c \
137138
$(SRCDIR)/timeline.c \
138139
$(SRCDIR)/tkt.c \
139140
$(SRCDIR)/tktsetup.c \
140141
$(SRCDIR)/undo.c \
@@ -364,10 +365,11 @@
364365
$(OBJDIR)/statrep_.c \
365366
$(OBJDIR)/style_.c \
366367
$(OBJDIR)/sync_.c \
367368
$(OBJDIR)/tag_.c \
368369
$(OBJDIR)/tar_.c \
370
+ $(OBJDIR)/terminal_.c \
369371
$(OBJDIR)/th_main_.c \
370372
$(OBJDIR)/timeline_.c \
371373
$(OBJDIR)/tkt_.c \
372374
$(OBJDIR)/tktsetup_.c \
373375
$(OBJDIR)/undo_.c \
@@ -506,10 +508,11 @@
506508
$(OBJDIR)/statrep.o \
507509
$(OBJDIR)/style.o \
508510
$(OBJDIR)/sync.o \
509511
$(OBJDIR)/tag.o \
510512
$(OBJDIR)/tar.o \
513
+ $(OBJDIR)/terminal.o \
511514
$(OBJDIR)/th_main.o \
512515
$(OBJDIR)/timeline.o \
513516
$(OBJDIR)/tkt.o \
514517
$(OBJDIR)/tktsetup.o \
515518
$(OBJDIR)/undo.o \
@@ -843,10 +846,11 @@
843846
$(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
844847
$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
845848
$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
846849
$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
847850
$(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
851
+ $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \
848852
$(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
849853
$(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
850854
$(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
851855
$(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
852856
$(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -1808,10 +1812,18 @@
18081812
18091813
$(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
18101814
$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
18111815
18121816
$(OBJDIR)/tar.h: $(OBJDIR)/headers
1817
+
1818
+$(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(OBJDIR)/translate
1819
+ $(OBJDIR)/translate $(SRCDIR)/terminal.c >$@
1820
+
1821
+$(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h
1822
+ $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c
1823
+
1824
+$(OBJDIR)/terminal.h: $(OBJDIR)/headers
18131825
18141826
$(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(OBJDIR)/translate
18151827
$(OBJDIR)/translate $(SRCDIR)/th_main.c >$@
18161828
18171829
$(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
18181830
--- src/main.mk
+++ src/main.mk
@@ -131,10 +131,11 @@
131 $(SRCDIR)/statrep.c \
132 $(SRCDIR)/style.c \
133 $(SRCDIR)/sync.c \
134 $(SRCDIR)/tag.c \
135 $(SRCDIR)/tar.c \
 
136 $(SRCDIR)/th_main.c \
137 $(SRCDIR)/timeline.c \
138 $(SRCDIR)/tkt.c \
139 $(SRCDIR)/tktsetup.c \
140 $(SRCDIR)/undo.c \
@@ -364,10 +365,11 @@
364 $(OBJDIR)/statrep_.c \
365 $(OBJDIR)/style_.c \
366 $(OBJDIR)/sync_.c \
367 $(OBJDIR)/tag_.c \
368 $(OBJDIR)/tar_.c \
 
369 $(OBJDIR)/th_main_.c \
370 $(OBJDIR)/timeline_.c \
371 $(OBJDIR)/tkt_.c \
372 $(OBJDIR)/tktsetup_.c \
373 $(OBJDIR)/undo_.c \
@@ -506,10 +508,11 @@
506 $(OBJDIR)/statrep.o \
507 $(OBJDIR)/style.o \
508 $(OBJDIR)/sync.o \
509 $(OBJDIR)/tag.o \
510 $(OBJDIR)/tar.o \
 
511 $(OBJDIR)/th_main.o \
512 $(OBJDIR)/timeline.o \
513 $(OBJDIR)/tkt.o \
514 $(OBJDIR)/tktsetup.o \
515 $(OBJDIR)/undo.o \
@@ -843,10 +846,11 @@
843 $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
844 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
845 $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
846 $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
847 $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
 
848 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
849 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
850 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
851 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
852 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -1808,10 +1812,18 @@
1808
1809 $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
1810 $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
1811
1812 $(OBJDIR)/tar.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1813
1814 $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(OBJDIR)/translate
1815 $(OBJDIR)/translate $(SRCDIR)/th_main.c >$@
1816
1817 $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
1818
--- src/main.mk
+++ src/main.mk
@@ -131,10 +131,11 @@
131 $(SRCDIR)/statrep.c \
132 $(SRCDIR)/style.c \
133 $(SRCDIR)/sync.c \
134 $(SRCDIR)/tag.c \
135 $(SRCDIR)/tar.c \
136 $(SRCDIR)/terminal.c \
137 $(SRCDIR)/th_main.c \
138 $(SRCDIR)/timeline.c \
139 $(SRCDIR)/tkt.c \
140 $(SRCDIR)/tktsetup.c \
141 $(SRCDIR)/undo.c \
@@ -364,10 +365,11 @@
365 $(OBJDIR)/statrep_.c \
366 $(OBJDIR)/style_.c \
367 $(OBJDIR)/sync_.c \
368 $(OBJDIR)/tag_.c \
369 $(OBJDIR)/tar_.c \
370 $(OBJDIR)/terminal_.c \
371 $(OBJDIR)/th_main_.c \
372 $(OBJDIR)/timeline_.c \
373 $(OBJDIR)/tkt_.c \
374 $(OBJDIR)/tktsetup_.c \
375 $(OBJDIR)/undo_.c \
@@ -506,10 +508,11 @@
508 $(OBJDIR)/statrep.o \
509 $(OBJDIR)/style.o \
510 $(OBJDIR)/sync.o \
511 $(OBJDIR)/tag.o \
512 $(OBJDIR)/tar.o \
513 $(OBJDIR)/terminal.o \
514 $(OBJDIR)/th_main.o \
515 $(OBJDIR)/timeline.o \
516 $(OBJDIR)/tkt.o \
517 $(OBJDIR)/tktsetup.o \
518 $(OBJDIR)/undo.o \
@@ -843,10 +846,11 @@
846 $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
847 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
848 $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
849 $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
850 $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
851 $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \
852 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
853 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
854 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
855 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
856 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -1808,10 +1812,18 @@
1812
1813 $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
1814 $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
1815
1816 $(OBJDIR)/tar.h: $(OBJDIR)/headers
1817
1818 $(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(OBJDIR)/translate
1819 $(OBJDIR)/translate $(SRCDIR)/terminal.c >$@
1820
1821 $(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h
1822 $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c
1823
1824 $(OBJDIR)/terminal.h: $(OBJDIR)/headers
1825
1826 $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(OBJDIR)/translate
1827 $(OBJDIR)/translate $(SRCDIR)/th_main.c >$@
1828
1829 $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
1830
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -141,10 +141,11 @@
141141
statrep
142142
style
143143
sync
144144
tag
145145
tar
146
+ terminal
146147
th_main
147148
timeline
148149
tkt
149150
tktsetup
150151
undo
151152
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -141,10 +141,11 @@
141 statrep
142 style
143 sync
144 tag
145 tar
 
146 th_main
147 timeline
148 tkt
149 tktsetup
150 undo
151
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -141,10 +141,11 @@
141 statrep
142 style
143 sync
144 tag
145 tar
146 terminal
147 th_main
148 timeline
149 tkt
150 tktsetup
151 undo
152
+1 -1
--- src/merge3.c
+++ src/merge3.c
@@ -139,11 +139,11 @@
139139
** Text of boundary markers for merge conflicts.
140140
*/
141141
static const char *const mergeMarker[] = {
142142
/*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
143143
"<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<\n",
144
- "======= COMMON ANCESTOR content follows ============================\n",
144
+ "||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||||||\n",
145145
"======= MERGED IN content follows ==================================\n",
146146
">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
147147
};
148148
149149
150150
--- src/merge3.c
+++ src/merge3.c
@@ -139,11 +139,11 @@
139 ** Text of boundary markers for merge conflicts.
140 */
141 static const char *const mergeMarker[] = {
142 /*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
143 "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<\n",
144 "======= COMMON ANCESTOR content follows ============================\n",
145 "======= MERGED IN content follows ==================================\n",
146 ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
147 };
148
149
150
--- src/merge3.c
+++ src/merge3.c
@@ -139,11 +139,11 @@
139 ** Text of boundary markers for merge conflicts.
140 */
141 static const char *const mergeMarker[] = {
142 /*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
143 "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<\n",
144 "||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||||||\n",
145 "======= MERGED IN content follows ==================================\n",
146 ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
147 };
148
149
150
--- src/mkversion.c
+++ src/mkversion.c
@@ -9,27 +9,59 @@
99
*/
1010
#include <stdio.h>
1111
#include <string.h>
1212
#include <stdlib.h>
1313
#include <ctype.h>
14
+#include <time.h>
1415
1516
static FILE *open_for_reading(const char *zFilename){
1617
FILE *f = fopen(zFilename, "r");
1718
if( f==0 ){
1819
fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename);
1920
exit(1);
2021
}
2122
return f;
2223
}
24
+
25
+/*
26
+** Given an arbitrary-length input string key zIn, generate
27
+** an N-byte hexadecimal hash of that string into zOut.
28
+*/
29
+static void hash(const char *zIn, int N, char *zOut){
30
+ unsigned char i, j, t;
31
+ int m, n;
32
+ unsigned char s[256];
33
+ for(m=0; m<256; m++){ s[m] = m; }
34
+ for(j=0, m=n=0; m<256; m++, n++){
35
+ j += s[m] + zIn[n];
36
+ if( zIn[n]==0 ){ n = -1; }
37
+ t = s[j];
38
+ s[j] = s[m];
39
+ s[m] = t;
40
+ }
41
+ i = j = 0;
42
+ for(n=0; n<N-2; n+=2){
43
+ i++;
44
+ t = s[i];
45
+ j += t;
46
+ s[i] = s[j];
47
+ s[j] = t;
48
+ t += s[i];
49
+ zOut[n] = "0123456789abcdef"[(t>>4)&0xf];
50
+ zOut[n+1] = "0123456789abcdef"[t&0xf];
51
+ }
52
+ zOut[n] = 0;
53
+}
2354
2455
int main(int argc, char *argv[]){
2556
FILE *m,*u,*v;
2657
char *z;
2758
#if defined(__DMC__) /* e.g. 0x857 */
2859
int i = 0;
2960
#endif
3061
int j = 0, x = 0, d = 0;
62
+ size_t n;
3163
int vn[3];
3264
char b[1000];
3365
char vx[1000];
3466
if( argc!=4 ){
3567
fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]);
@@ -45,10 +77,16 @@
4577
fclose(u);
4678
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
4779
*z = 0;
4880
printf("#define MANIFEST_UUID \"%s\"\n",b);
4981
printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
82
+ n = strlen(b);
83
+ if( n + 50 < sizeof(b) ){
84
+ sprintf(b+n, "%d", (int)time(0));
85
+ hash(b,33,vx);
86
+ printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx);
87
+ }
5088
m = open_for_reading(argv[2]);
5189
while(b == fgets(b, sizeof(b)-1,m)){
5290
if(0 == strncmp("D ",b,2)){
5391
int k, n;
5492
char zDateNum[30];
5593
--- src/mkversion.c
+++ src/mkversion.c
@@ -9,27 +9,59 @@
9 */
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <ctype.h>
 
14
15 static FILE *open_for_reading(const char *zFilename){
16 FILE *f = fopen(zFilename, "r");
17 if( f==0 ){
18 fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename);
19 exit(1);
20 }
21 return f;
22 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24 int main(int argc, char *argv[]){
25 FILE *m,*u,*v;
26 char *z;
27 #if defined(__DMC__) /* e.g. 0x857 */
28 int i = 0;
29 #endif
30 int j = 0, x = 0, d = 0;
 
31 int vn[3];
32 char b[1000];
33 char vx[1000];
34 if( argc!=4 ){
35 fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]);
@@ -45,10 +77,16 @@
45 fclose(u);
46 for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
47 *z = 0;
48 printf("#define MANIFEST_UUID \"%s\"\n",b);
49 printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
 
 
 
 
 
 
50 m = open_for_reading(argv[2]);
51 while(b == fgets(b, sizeof(b)-1,m)){
52 if(0 == strncmp("D ",b,2)){
53 int k, n;
54 char zDateNum[30];
55
--- src/mkversion.c
+++ src/mkversion.c
@@ -9,27 +9,59 @@
9 */
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <ctype.h>
14 #include <time.h>
15
16 static FILE *open_for_reading(const char *zFilename){
17 FILE *f = fopen(zFilename, "r");
18 if( f==0 ){
19 fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename);
20 exit(1);
21 }
22 return f;
23 }
24
25 /*
26 ** Given an arbitrary-length input string key zIn, generate
27 ** an N-byte hexadecimal hash of that string into zOut.
28 */
29 static void hash(const char *zIn, int N, char *zOut){
30 unsigned char i, j, t;
31 int m, n;
32 unsigned char s[256];
33 for(m=0; m<256; m++){ s[m] = m; }
34 for(j=0, m=n=0; m<256; m++, n++){
35 j += s[m] + zIn[n];
36 if( zIn[n]==0 ){ n = -1; }
37 t = s[j];
38 s[j] = s[m];
39 s[m] = t;
40 }
41 i = j = 0;
42 for(n=0; n<N-2; n+=2){
43 i++;
44 t = s[i];
45 j += t;
46 s[i] = s[j];
47 s[j] = t;
48 t += s[i];
49 zOut[n] = "0123456789abcdef"[(t>>4)&0xf];
50 zOut[n+1] = "0123456789abcdef"[t&0xf];
51 }
52 zOut[n] = 0;
53 }
54
55 int main(int argc, char *argv[]){
56 FILE *m,*u,*v;
57 char *z;
58 #if defined(__DMC__) /* e.g. 0x857 */
59 int i = 0;
60 #endif
61 int j = 0, x = 0, d = 0;
62 size_t n;
63 int vn[3];
64 char b[1000];
65 char vx[1000];
66 if( argc!=4 ){
67 fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]);
@@ -45,10 +77,16 @@
77 fclose(u);
78 for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
79 *z = 0;
80 printf("#define MANIFEST_UUID \"%s\"\n",b);
81 printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
82 n = strlen(b);
83 if( n + 50 < sizeof(b) ){
84 sprintf(b+n, "%d", (int)time(0));
85 hash(b,33,vx);
86 printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx);
87 }
88 m = open_for_reading(argv[2]);
89 while(b == fgets(b, sizeof(b)-1,m)){
90 if(0 == strncmp("D ",b,2)){
91 int k, n;
92 char zDateNum[30];
93
+3 -3
--- src/name.c
+++ src/name.c
@@ -614,11 +614,11 @@
614614
while( db_step(&q)==SQLITE_ROW ){
615615
const char *zUuid = db_column_text(&q, 0);
616616
int rid = db_column_int(&q, 1);
617617
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
618618
@ %s(zUuid)</a> -
619
- object_description(rid, 0, 0);
619
+ object_description(rid, 0, 0, 0);
620620
@ </p></li>
621621
}
622622
db_finalize(&q);
623623
db_prepare(&q,
624624
" SELECT tkt_rid, tkt_uuid, title"
@@ -636,11 +636,11 @@
636636
@ <ul></ul>
637637
@ Ticket
638638
hyperlink_to_uuid(zUuid);
639639
@ - %h(zTitle).
640640
@ <ul><li>
641
- object_description(rid, 0, 0);
641
+ object_description(rid, 0, 0, 0);
642642
@ </li></ul>
643643
@ </p></li>
644644
}
645645
db_finalize(&q);
646646
db_prepare(&q,
@@ -652,11 +652,11 @@
652652
int rid = db_column_int(&q, 0);
653653
const char* zUuid = db_column_text(&q, 1);
654654
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
655655
@ %s(zUuid)</a> -
656656
@ <ul><li>
657
- object_description(rid, 0, 0);
657
+ object_description(rid, 0, 0, 0);
658658
@ </li></ul>
659659
@ </p></li>
660660
}
661661
@ </ol>
662662
db_finalize(&q);
663663
--- src/name.c
+++ src/name.c
@@ -614,11 +614,11 @@
614 while( db_step(&q)==SQLITE_ROW ){
615 const char *zUuid = db_column_text(&q, 0);
616 int rid = db_column_int(&q, 1);
617 @ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
618 @ %s(zUuid)</a> -
619 object_description(rid, 0, 0);
620 @ </p></li>
621 }
622 db_finalize(&q);
623 db_prepare(&q,
624 " SELECT tkt_rid, tkt_uuid, title"
@@ -636,11 +636,11 @@
636 @ <ul></ul>
637 @ Ticket
638 hyperlink_to_uuid(zUuid);
639 @ - %h(zTitle).
640 @ <ul><li>
641 object_description(rid, 0, 0);
642 @ </li></ul>
643 @ </p></li>
644 }
645 db_finalize(&q);
646 db_prepare(&q,
@@ -652,11 +652,11 @@
652 int rid = db_column_int(&q, 0);
653 const char* zUuid = db_column_text(&q, 1);
654 @ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
655 @ %s(zUuid)</a> -
656 @ <ul><li>
657 object_description(rid, 0, 0);
658 @ </li></ul>
659 @ </p></li>
660 }
661 @ </ol>
662 db_finalize(&q);
663
--- src/name.c
+++ src/name.c
@@ -614,11 +614,11 @@
614 while( db_step(&q)==SQLITE_ROW ){
615 const char *zUuid = db_column_text(&q, 0);
616 int rid = db_column_int(&q, 1);
617 @ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
618 @ %s(zUuid)</a> -
619 object_description(rid, 0, 0, 0);
620 @ </p></li>
621 }
622 db_finalize(&q);
623 db_prepare(&q,
624 " SELECT tkt_rid, tkt_uuid, title"
@@ -636,11 +636,11 @@
636 @ <ul></ul>
637 @ Ticket
638 hyperlink_to_uuid(zUuid);
639 @ - %h(zTitle).
640 @ <ul><li>
641 object_description(rid, 0, 0, 0);
642 @ </li></ul>
643 @ </p></li>
644 }
645 db_finalize(&q);
646 db_prepare(&q,
@@ -652,11 +652,11 @@
652 int rid = db_column_int(&q, 0);
653 const char* zUuid = db_column_text(&q, 1);
654 @ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
655 @ %s(zUuid)</a> -
656 @ <ul><li>
657 object_description(rid, 0, 0, 0);
658 @ </li></ul>
659 @ </p></li>
660 }
661 @ </ol>
662 db_finalize(&q);
663
+11 -6
--- src/setup.c
+++ src/setup.c
@@ -876,25 +876,30 @@
876876
}
877877
}
878878
}
879879
@ <br /><input type="submit" name="submit" value="Apply Changes" />
880880
@ </td><td style="width:50px;"></td><td valign="top">
881
+ @ <table>
881882
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
882883
if( pSet->width>0 && !pSet->forceTextArea ){
883884
int hasVersionableValue = pSet->versionable &&
884885
(db_get_versioned(pSet->name, NULL)!=0);
886
+ @ <tr><td>
887
+ @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
888
+ if( pSet->versionable ){
889
+ @ (v)
890
+ } else {
891
+ @
892
+ }
893
+ @</td><td>
885894
entry_attribute("", /*pSet->width*/ 25, pSet->name,
886895
pSet->var!=0 ? pSet->var : pSet->name,
887896
(char*)pSet->def, hasVersionableValue);
888
- @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
889
- if( pSet->versionable ){
890
- @ (v)<br />
891
- } else {
892
- @ <br />
893
- }
897
+ @</td></tr>
894898
}
895899
}
900
+ @</table>
896901
@ </td><td style="width:50px;"></td><td valign="top">
897902
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
898903
if( pSet->width>0 && pSet->forceTextArea ){
899904
int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0;
900905
@ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a>
901906
--- src/setup.c
+++ src/setup.c
@@ -876,25 +876,30 @@
876 }
877 }
878 }
879 @ <br /><input type="submit" name="submit" value="Apply Changes" />
880 @ </td><td style="width:50px;"></td><td valign="top">
 
881 for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
882 if( pSet->width>0 && !pSet->forceTextArea ){
883 int hasVersionableValue = pSet->versionable &&
884 (db_get_versioned(pSet->name, NULL)!=0);
 
 
 
 
 
 
 
 
885 entry_attribute("", /*pSet->width*/ 25, pSet->name,
886 pSet->var!=0 ? pSet->var : pSet->name,
887 (char*)pSet->def, hasVersionableValue);
888 @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
889 if( pSet->versionable ){
890 @ (v)<br />
891 } else {
892 @ <br />
893 }
894 }
895 }
 
896 @ </td><td style="width:50px;"></td><td valign="top">
897 for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
898 if( pSet->width>0 && pSet->forceTextArea ){
899 int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0;
900 @ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a>
901
--- src/setup.c
+++ src/setup.c
@@ -876,25 +876,30 @@
876 }
877 }
878 }
879 @ <br /><input type="submit" name="submit" value="Apply Changes" />
880 @ </td><td style="width:50px;"></td><td valign="top">
881 @ <table>
882 for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
883 if( pSet->width>0 && !pSet->forceTextArea ){
884 int hasVersionableValue = pSet->versionable &&
885 (db_get_versioned(pSet->name, NULL)!=0);
886 @ <tr><td>
887 @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
888 if( pSet->versionable ){
889 @ (v)
890 } else {
891 @
892 }
893 @</td><td>
894 entry_attribute("", /*pSet->width*/ 25, pSet->name,
895 pSet->var!=0 ? pSet->var : pSet->name,
896 (char*)pSet->def, hasVersionableValue);
897 @</td></tr>
 
 
 
 
 
898 }
899 }
900 @</table>
901 @ </td><td style="width:50px;"></td><td valign="top">
902 for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
903 if( pSet->width>0 && pSet->forceTextArea ){
904 int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0;
905 @ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a>
906
+4 -7
--- src/shell.c
+++ src/shell.c
@@ -4330,10 +4330,11 @@
43304330
int nKey2, const void *pKey2
43314331
){
43324332
const unsigned char *zA = (const unsigned char*)pKey1;
43334333
const unsigned char *zB = (const unsigned char*)pKey2;
43344334
int i=0, j=0, x;
4335
+ (void)notUsed;
43354336
while( i<nKey1 && j<nKey2 ){
43364337
x = zA[i] - zB[j];
43374338
if( isdigit(zA[i]) ){
43384339
int k;
43394340
if( !isdigit(zB[j]) ) return x;
@@ -11816,10 +11817,11 @@
1181611817
if( rc==SQLITE_OK ){
1181711818
while( sqlite3_step(pExplain)==SQLITE_ROW ){
1181811819
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
1181911820
int iEqpId = sqlite3_column_int(pExplain, 0);
1182011821
int iParentId = sqlite3_column_int(pExplain, 1);
11822
+ if( zEQPLine==0 ) zEQPLine = "";
1182111823
if( zEQPLine[0]=='-' ) eqp_render(pArg);
1182211824
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
1182311825
}
1182411826
eqp_render(pArg);
1182511827
}
@@ -13725,16 +13727,11 @@
1372513727
if( p->db==0 ) return 1;
1372613728
rc = sqlite3_prepare_v2(p->db,
1372713729
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
1372813730
-1, &pStmt, 0);
1372913731
if( rc ){
13730
- if( !sqlite3_compileoption_used("ENABLE_DBPAGE_VTAB") ){
13731
- utf8_printf(stderr, "the \".dbinfo\" command requires the "
13732
- "-DSQLITE_ENABLE_DBPAGE_VTAB compile-time options\n");
13733
- }else{
13734
- utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
13735
- }
13732
+ utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
1373613733
sqlite3_finalize(pStmt);
1373713734
return 1;
1373813735
}
1373913736
sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
1374013737
if( sqlite3_step(pStmt)==SQLITE_ROW
@@ -17004,11 +17001,11 @@
1700417001
const char *zFile = 0;
1700517002
int bTxtMode = 0;
1700617003
int i;
1700717004
int eMode = 0;
1700817005
int bBOM = 0;
17009
- int bOnce;
17006
+ int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
1701017007
1701117008
if( c=='e' ){
1701217009
eMode = 'x';
1701317010
bOnce = 2;
1701417011
}else if( strncmp(azArg[0],"once",n)==0 ){
1701517012
--- src/shell.c
+++ src/shell.c
@@ -4330,10 +4330,11 @@
4330 int nKey2, const void *pKey2
4331 ){
4332 const unsigned char *zA = (const unsigned char*)pKey1;
4333 const unsigned char *zB = (const unsigned char*)pKey2;
4334 int i=0, j=0, x;
 
4335 while( i<nKey1 && j<nKey2 ){
4336 x = zA[i] - zB[j];
4337 if( isdigit(zA[i]) ){
4338 int k;
4339 if( !isdigit(zB[j]) ) return x;
@@ -11816,10 +11817,11 @@
11816 if( rc==SQLITE_OK ){
11817 while( sqlite3_step(pExplain)==SQLITE_ROW ){
11818 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
11819 int iEqpId = sqlite3_column_int(pExplain, 0);
11820 int iParentId = sqlite3_column_int(pExplain, 1);
 
11821 if( zEQPLine[0]=='-' ) eqp_render(pArg);
11822 eqp_append(pArg, iEqpId, iParentId, zEQPLine);
11823 }
11824 eqp_render(pArg);
11825 }
@@ -13725,16 +13727,11 @@
13725 if( p->db==0 ) return 1;
13726 rc = sqlite3_prepare_v2(p->db,
13727 "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
13728 -1, &pStmt, 0);
13729 if( rc ){
13730 if( !sqlite3_compileoption_used("ENABLE_DBPAGE_VTAB") ){
13731 utf8_printf(stderr, "the \".dbinfo\" command requires the "
13732 "-DSQLITE_ENABLE_DBPAGE_VTAB compile-time options\n");
13733 }else{
13734 utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
13735 }
13736 sqlite3_finalize(pStmt);
13737 return 1;
13738 }
13739 sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
13740 if( sqlite3_step(pStmt)==SQLITE_ROW
@@ -17004,11 +17001,11 @@
17004 const char *zFile = 0;
17005 int bTxtMode = 0;
17006 int i;
17007 int eMode = 0;
17008 int bBOM = 0;
17009 int bOnce;
17010
17011 if( c=='e' ){
17012 eMode = 'x';
17013 bOnce = 2;
17014 }else if( strncmp(azArg[0],"once",n)==0 ){
17015
--- src/shell.c
+++ src/shell.c
@@ -4330,10 +4330,11 @@
4330 int nKey2, const void *pKey2
4331 ){
4332 const unsigned char *zA = (const unsigned char*)pKey1;
4333 const unsigned char *zB = (const unsigned char*)pKey2;
4334 int i=0, j=0, x;
4335 (void)notUsed;
4336 while( i<nKey1 && j<nKey2 ){
4337 x = zA[i] - zB[j];
4338 if( isdigit(zA[i]) ){
4339 int k;
4340 if( !isdigit(zB[j]) ) return x;
@@ -11816,10 +11817,11 @@
11817 if( rc==SQLITE_OK ){
11818 while( sqlite3_step(pExplain)==SQLITE_ROW ){
11819 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
11820 int iEqpId = sqlite3_column_int(pExplain, 0);
11821 int iParentId = sqlite3_column_int(pExplain, 1);
11822 if( zEQPLine==0 ) zEQPLine = "";
11823 if( zEQPLine[0]=='-' ) eqp_render(pArg);
11824 eqp_append(pArg, iEqpId, iParentId, zEQPLine);
11825 }
11826 eqp_render(pArg);
11827 }
@@ -13725,16 +13727,11 @@
13727 if( p->db==0 ) return 1;
13728 rc = sqlite3_prepare_v2(p->db,
13729 "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
13730 -1, &pStmt, 0);
13731 if( rc ){
13732 utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
 
 
 
 
 
13733 sqlite3_finalize(pStmt);
13734 return 1;
13735 }
13736 sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
13737 if( sqlite3_step(pStmt)==SQLITE_ROW
@@ -17004,11 +17001,11 @@
17001 const char *zFile = 0;
17002 int bTxtMode = 0;
17003 int i;
17004 int eMode = 0;
17005 int bBOM = 0;
17006 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
17007
17008 if( c=='e' ){
17009 eMode = 'x';
17010 bOnce = 2;
17011 }else if( strncmp(azArg[0],"once",n)==0 ){
17012
+2 -2
--- src/shun.c
+++ src/shun.c
@@ -187,11 +187,11 @@
187187
@ sight - set the "hidden" tag on such artifacts instead.</p>
188188
@
189189
@ <blockquote>
190190
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
191191
login_insert_csrf_secret();
192
- @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
192
+ @ <textarea class="fullsize-text" cols="70" rows="%d(numRows)" name="uuid">
193193
if( zShun ){
194194
if( strlen(zShun) ){
195195
@ %h(zShun)
196196
}else if( nRcvid ){
197197
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
@@ -214,11 +214,11 @@
214214
@ operations.</p>
215215
@
216216
@ <blockquote>
217217
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
218218
login_insert_csrf_secret();
219
- @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
219
+ @ <textarea class="fullsize-text" cols="70" rows="%d(numRows)" name="uuid">
220220
if( zAccept ){
221221
if( strlen(zAccept) ){
222222
@ %h(zAccept)
223223
}else if( nRcvid ){
224224
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
225225
--- src/shun.c
+++ src/shun.c
@@ -187,11 +187,11 @@
187 @ sight - set the "hidden" tag on such artifacts instead.</p>
188 @
189 @ <blockquote>
190 @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
191 login_insert_csrf_secret();
192 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
193 if( zShun ){
194 if( strlen(zShun) ){
195 @ %h(zShun)
196 }else if( nRcvid ){
197 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
@@ -214,11 +214,11 @@
214 @ operations.</p>
215 @
216 @ <blockquote>
217 @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
218 login_insert_csrf_secret();
219 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
220 if( zAccept ){
221 if( strlen(zAccept) ){
222 @ %h(zAccept)
223 }else if( nRcvid ){
224 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
225
--- src/shun.c
+++ src/shun.c
@@ -187,11 +187,11 @@
187 @ sight - set the "hidden" tag on such artifacts instead.</p>
188 @
189 @ <blockquote>
190 @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
191 login_insert_csrf_secret();
192 @ <textarea class="fullsize-text" cols="70" rows="%d(numRows)" name="uuid">
193 if( zShun ){
194 if( strlen(zShun) ){
195 @ %h(zShun)
196 }else if( nRcvid ){
197 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
@@ -214,11 +214,11 @@
214 @ operations.</p>
215 @
216 @ <blockquote>
217 @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
218 login_insert_csrf_secret();
219 @ <textarea class="fullsize-text" cols="70" rows="%d(numRows)" name="uuid">
220 if( zAccept ){
221 if( strlen(zAccept) ){
222 @ %h(zAccept)
223 }else if( nRcvid ){
224 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
225
+1462 -698
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -216,10 +216,13 @@
216216
"ENABLE_ATOMIC_WRITE",
217217
#endif
218218
#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
219219
"ENABLE_BATCH_ATOMIC_WRITE",
220220
#endif
221
+#if SQLITE_ENABLE_BYTECODE_VTAB
222
+ "ENABLE_BYTECODE_VTAB",
223
+#endif
221224
#if SQLITE_ENABLE_CEROD
222225
"ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
223226
#endif
224227
#if SQLITE_ENABLE_COLUMN_METADATA
225228
"ENABLE_COLUMN_METADATA",
@@ -534,13 +537,10 @@
534537
"OMIT_BETWEEN_OPTIMIZATION",
535538
#endif
536539
#if SQLITE_OMIT_BLOB_LITERAL
537540
"OMIT_BLOB_LITERAL",
538541
#endif
539
-#if SQLITE_OMIT_BTREECOUNT
540
- "OMIT_BTREECOUNT",
541
-#endif
542542
#if SQLITE_OMIT_CAST
543543
"OMIT_CAST",
544544
#endif
545545
#if SQLITE_OMIT_CHECK
546546
"OMIT_CHECK",
@@ -1162,11 +1162,11 @@
11621162
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
11631163
** [sqlite_version()] and [sqlite_source_id()].
11641164
*/
11651165
#define SQLITE_VERSION "3.32.0"
11661166
#define SQLITE_VERSION_NUMBER 3032000
1167
-#define SQLITE_SOURCE_ID "2020-04-20 17:35:32 2fc80ef16ce5878311ab88a0c64631813572ffbb71f75363b4619c9667e0926b"
1167
+#define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff"
11681168
11691169
/*
11701170
** CAPI3REF: Run-Time Library Version Numbers
11711171
** KEYWORDS: sqlite3_version sqlite3_sourceid
11721172
**
@@ -1336,30 +1336,26 @@
13361336
** for the [sqlite3] object.
13371337
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
13381338
** the [sqlite3] object is successfully destroyed and all associated
13391339
** resources are deallocated.
13401340
**
1341
+** Ideally, applications should [sqlite3_finalize | finalize] all
1342
+** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
1343
+** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
1344
+** with the [sqlite3] object prior to attempting to close the object.
13411345
** ^If the database connection is associated with unfinalized prepared
1342
-** statements or unfinished sqlite3_backup objects then sqlite3_close()
1343
-** will leave the database connection open and return [SQLITE_BUSY].
1344
-** ^If sqlite3_close_v2() is called with unfinalized prepared statements
1345
-** and/or unfinished sqlite3_backups, then the database connection becomes
1346
-** an unusable "zombie" which will automatically be deallocated when the
1347
-** last prepared statement is finalized or the last sqlite3_backup is
1348
-** finished. The sqlite3_close_v2() interface is intended for use with
1349
-** host languages that are garbage collected, and where the order in which
1350
-** destructors are called is arbitrary.
1351
-**
1352
-** Applications should [sqlite3_finalize | finalize] all [prepared statements],
1353
-** [sqlite3_blob_close | close] all [BLOB handles], and
1354
-** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
1355
-** with the [sqlite3] object prior to attempting to close the object. ^If
1356
-** sqlite3_close_v2() is called on a [database connection] that still has
1357
-** outstanding [prepared statements], [BLOB handles], and/or
1358
-** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
1359
-** of resources is deferred until all [prepared statements], [BLOB handles],
1360
-** and [sqlite3_backup] objects are also destroyed.
1346
+** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
1347
+** sqlite3_close() will leave the database connection open and return
1348
+** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
1349
+** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
1350
+** it returns [SQLITE_OK] regardless, but instead of deallocating the database
1351
+** connection immediately, it marks the database connection as an unusable
1352
+** "zombie" and makes arrangements to automatically deallocate the database
1353
+** connection after all prepared statements are finalized, all BLOB handles
1354
+** are closed, and all backups have finished. The sqlite3_close_v2() interface
1355
+** is intended for use with host languages that are garbage collected, and
1356
+** where the order in which destructors are called is arbitrary.
13611357
**
13621358
** ^If an [sqlite3] object is destroyed while a transaction is open,
13631359
** the transaction is automatically rolled back.
13641360
**
13651361
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
@@ -1544,22 +1540,25 @@
15441540
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
15451541
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
15461542
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
15471543
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
15481544
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
1545
+#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
15491546
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
15501547
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
15511548
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
15521549
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
1550
+#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
15531551
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
15541552
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
15551553
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
15561554
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
15571555
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
15581556
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
15591557
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
15601558
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
1559
+#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
15611560
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
15621561
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
15631562
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
15641563
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
15651564
#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
@@ -2150,10 +2149,15 @@
21502149
** a single attached database that occur due to other database connections,
21512150
** but omits changes implemented by the database connection on which it is
21522151
** called. This file control is the only mechanism to detect changes that
21532152
** happen either internally or externally and that are associated with
21542153
** a particular attached database.
2154
+**
2155
+** <li>[[SQLITE_FCNTL_CKPT_START]]
2156
+** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
2157
+** in wal mode before the client starts to copy pages from the wal
2158
+** file to the database file.
21552159
**
21562160
** <li>[[SQLITE_FCNTL_CKPT_DONE]]
21572161
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
21582162
** in wal mode after the client has finished copying pages from the wal
21592163
** file to the database file, but before the *-shm file is updated to
@@ -2195,10 +2199,11 @@
21952199
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
21962200
#define SQLITE_FCNTL_DATA_VERSION 35
21972201
#define SQLITE_FCNTL_SIZE_LIMIT 36
21982202
#define SQLITE_FCNTL_CKPT_DONE 37
21992203
#define SQLITE_FCNTL_RESERVE_BYTES 38
2204
+#define SQLITE_FCNTL_CKPT_START 39
22002205
22012206
/* deprecated names */
22022207
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
22032208
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
22042209
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -4573,12 +4578,23 @@
45734578
**
45744579
** These are utility routines, useful to [VFS|custom VFS implementations],
45754580
** that check if a database file was a URI that contained a specific query
45764581
** parameter, and if so obtains the value of that query parameter.
45774582
**
4578
-** If F is the database filename pointer passed into the xOpen() method of
4579
-** a VFS implementation or it is the return value of [sqlite3_db_filename()]
4583
+** The first parameter to these interfaces (hereafter referred to
4584
+** as F) must be one of:
4585
+** <ul>
4586
+** <li> A database filename pointer created by the SQLite core and
4587
+** passed into the xOpen() method of a VFS implemention, or
4588
+** <li> A filename obtained from [sqlite3_db_filename()], or
4589
+** <li> A new filename constructed using [sqlite3_create_filename()].
4590
+** </ul>
4591
+** If the F parameter is not one of the above, then the behavior is
4592
+** undefined and probably undesirable. Older versions of SQLite were
4593
+** more tolerant of invalid F parameters than newer versions.
4594
+**
4595
+** If F is a suitable filename (as described in the previous paragraph)
45804596
** and if P is the name of the query parameter, then
45814597
** sqlite3_uri_parameter(F,P) returns the value of the P
45824598
** parameter if it exists or a NULL pointer if P does not appear as a
45834599
** query parameter on F. If P is a query parameter of F and it
45844600
** has no explicit value, then sqlite3_uri_parameter(F,P) returns
@@ -4657,10 +4673,29 @@
46574673
*/
46584674
SQLITE_API const char *sqlite3_filename_database(const char*);
46594675
SQLITE_API const char *sqlite3_filename_journal(const char*);
46604676
SQLITE_API const char *sqlite3_filename_wal(const char*);
46614677
4678
+/*
4679
+** CAPI3REF: Database File Corresponding To A Journal
4680
+**
4681
+** ^If X is the name of a rollback or WAL-mode journal file that is
4682
+** passed into the xOpen method of [sqlite3_vfs], then
4683
+** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
4684
+** object that represents the main database file.
4685
+**
4686
+** This routine is intended for use in custom [VFS] implementations
4687
+** only. It is not a general-purpose interface.
4688
+** The argument sqlite3_file_object(X) must be a filename pointer that
4689
+** has been passed into [sqlite3_vfs].xOpen method where the
4690
+** flags parameter to xOpen contains one of the bits
4691
+** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
4692
+** of this routine results in undefined and probably undesirable
4693
+** behavior.
4694
+*/
4695
+SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
4696
+
46624697
/*
46634698
** CAPI3REF: Create and Destroy VFS Filenames
46644699
**
46654700
** These interfces are provided for use by [VFS shim] implementations and
46664701
** are not useful outside of that context.
@@ -4691,11 +4726,11 @@
46914726
** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
46924727
** be NULL pointers, though they can be empty strings.
46934728
**
46944729
** The sqlite3_free_filename(Y) routine releases a memory allocation
46954730
** previously obtained from sqlite3_create_filename(). Invoking
4696
-** sqlite3_free_filename(Y) is a NULL pointer is a harmless no-op.
4731
+** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
46974732
**
46984733
** If the Y parameter to sqlite3_free_filename(Y) is anything other
46994734
** than a NULL pointer or a pointer previously acquired from
47004735
** sqlite3_create_filename(), then bad things such as heap
47014736
** corruption or segfaults may occur. The value Y should be
@@ -14502,11 +14537,10 @@
1450214537
typedef struct BusyHandler BusyHandler;
1450314538
struct BusyHandler {
1450414539
int (*xBusyHandler)(void *,int); /* The busy callback */
1450514540
void *pBusyArg; /* First arg to busy callback */
1450614541
int nBusy; /* Incremented with each busy call */
14507
- u8 bExtraFileArg; /* Include sqlite3_file as callback arg */
1450814542
};
1450914543
1451014544
/*
1451114545
** Name of the master database table. The master database table
1451214546
** is a special table that holds the names and attributes of all
@@ -15022,13 +15056,11 @@
1502215056
#ifndef NDEBUG
1502315057
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
1502415058
#endif
1502515059
SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
1502615060
15027
-#ifndef SQLITE_OMIT_BTREECOUNT
1502815061
SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
15029
-#endif
1503015062
1503115063
#ifdef SQLITE_TEST
1503215064
SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
1503315065
SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
1503415066
#endif
@@ -15599,10 +15631,13 @@
1559915631
1560015632
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
1560115633
SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
1560215634
1560315635
SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
15636
+#ifdef SQLITE_ENABLE_BYTECODE_VTAB
15637
+SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*);
15638
+#endif
1560415639
1560515640
/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
1560615641
** each VDBE opcode.
1560715642
**
1560815643
** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
@@ -15884,17 +15919,25 @@
1588415919
SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
1588515920
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
1588615921
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
1588715922
SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
1588815923
# ifdef SQLITE_ENABLE_SNAPSHOT
15889
-SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
15890
-SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
15924
+SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot);
15925
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot);
1589115926
SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
1589215927
SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
1589315928
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
1589415929
# endif
1589515930
#endif
15931
+
15932
+#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT)
15933
+SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager*, int);
15934
+SQLITE_PRIVATE void sqlite3PagerWalDb(Pager*, sqlite3*);
15935
+#else
15936
+# define sqlite3PagerWalWriteLock(y,z) SQLITE_OK
15937
+# define sqlite3PagerWalDb(x,y)
15938
+#endif
1589615939
1589715940
#ifdef SQLITE_DIRECT_OVERFLOW_READ
1589815941
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
1589915942
#endif
1590015943
@@ -15917,15 +15960,10 @@
1591715960
SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
1591815961
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
1591915962
SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
1592015963
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
1592115964
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
15922
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
15923
-SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager);
15924
-#else
15925
-# define sqlite3PagerResetLockTimeout(X)
15926
-#endif
1592715965
1592815966
/* Functions used to truncate the database file. */
1592915967
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
1593015968
1593115969
SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
@@ -16855,10 +16893,11 @@
1685516893
Hash aFunc; /* Hash table of connection functions */
1685616894
Hash aCollSeq; /* All collating sequences */
1685716895
BusyHandler busyHandler; /* Busy callback */
1685816896
Db aDbStatic[2]; /* Static space for the 2 default backends */
1685916897
Savepoint *pSavepoint; /* List of active savepoints */
16898
+ int nAnalysisLimit; /* Number of index rows to ANALYZE */
1686016899
int busyTimeout; /* Busy handler timeout, in msec */
1686116900
int nSavepoint; /* Number of non-transaction savepoints */
1686216901
int nStatement; /* Number of nested statement-transactions */
1686316902
i64 nDeferredCons; /* Net deferred constraints this transaction. */
1686416903
i64 nDeferredImmCons; /* Net deferred immediate constraints */
@@ -19900,11 +19939,11 @@
1990019939
SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*);
1990119940
SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
1990219941
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
1990319942
SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
1990419943
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
19905
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
19944
+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
1990619945
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
1990719946
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
1990819947
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
1990919948
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
1991019949
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
@@ -20636,11 +20675,12 @@
2063620675
/*
2063720676
** VDBE_DISPLAY_P4 is true or false depending on whether or not the
2063820677
** "explain" P4 display logic is enabled.
2063920678
*/
2064020679
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
20641
- || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
20680
+ || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
20681
+ || defined(SQLITE_ENABLE_BYTECODE_VTAB)
2064220682
# define VDBE_DISPLAY_P4 1
2064320683
#else
2064420684
# define VDBE_DISPLAY_P4 0
2064520685
#endif
2064620686
@@ -21101,11 +21141,18 @@
2110121141
2110221142
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
2110321143
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
2110421144
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
2110521145
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
21106
-#ifndef SQLITE_OMIT_EXPLAIN
21146
+#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
21147
+SQLITE_PRIVATE int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**);
21148
+SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3*,Op*);
21149
+#endif
21150
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
21151
+SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*);
21152
+#endif
21153
+#if !defined(SQLITE_OMIT_EXPLAIN)
2110721154
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
2110821155
#endif
2110921156
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
2111021157
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
2111121158
SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -21143,11 +21190,11 @@
2114321190
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
2114421191
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
2114521192
#ifndef SQLITE_OMIT_WINDOWFUNC
2114621193
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
2114721194
#endif
21148
-#ifndef SQLITE_OMIT_EXPLAIN
21195
+#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
2114921196
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
2115021197
#endif
2115121198
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
2115221199
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
2115321200
SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
@@ -27316,11 +27363,11 @@
2731627363
if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
2731727364
n = mem0.hardLimit;
2731827365
}
2731927366
mem0.alarmThreshold = n;
2732027367
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
27321
- mem0.nearlyFull = (n>0 && n<=nUsed);
27368
+ AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
2732227369
sqlite3_mutex_leave(mem0.mutex);
2732327370
excess = sqlite3_memory_used() - n;
2732427371
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
2732527372
return priorLimit;
2732627373
}
@@ -27384,11 +27431,11 @@
2738427431
** Return true if the heap is currently under memory pressure - in other
2738527432
** words if the amount of heap used is close to the limit set by
2738627433
** sqlite3_soft_heap_limit().
2738727434
*/
2738827435
SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
27389
- return mem0.nearlyFull;
27436
+ return AtomicLoad(&mem0.nearlyFull);
2739027437
}
2739127438
2739227439
/*
2739327440
** Deinitialize the memory allocation subsystem.
2739427441
*/
@@ -27448,21 +27495,21 @@
2744827495
2744927496
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
2745027497
if( mem0.alarmThreshold>0 ){
2745127498
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
2745227499
if( nUsed >= mem0.alarmThreshold - nFull ){
27453
- mem0.nearlyFull = 1;
27500
+ AtomicStore(&mem0.nearlyFull, 1);
2745427501
sqlite3MallocAlarm(nFull);
2745527502
if( mem0.hardLimit ){
2745627503
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
2745727504
if( nUsed >= mem0.hardLimit - nFull ){
2745827505
*pp = 0;
2745927506
return;
2746027507
}
2746127508
}
2746227509
}else{
27463
- mem0.nearlyFull = 0;
27510
+ AtomicStore(&mem0.nearlyFull, 0);
2746427511
}
2746527512
}
2746627513
p = sqlite3GlobalConfig.m.xMalloc(nFull);
2746727514
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
2746827515
if( p==0 && mem0.alarmThreshold>0 ){
@@ -27687,14 +27734,16 @@
2768727734
if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
2768827735
mem0.alarmThreshold-nDiff ){
2768927736
sqlite3MallocAlarm(nDiff);
2769027737
}
2769127738
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
27739
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
2769227740
if( pNew==0 && mem0.alarmThreshold>0 ){
2769327741
sqlite3MallocAlarm((int)nBytes);
2769427742
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
2769527743
}
27744
+#endif
2769627745
if( pNew ){
2769727746
nNew = sqlite3MallocSize(pNew);
2769827747
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
2769927748
}
2770027749
sqlite3_mutex_leave(mem0.mutex);
@@ -34928,20 +34977,21 @@
3492834977
static int osSetPosixAdvisoryLock(
3492934978
int h, /* The file descriptor on which to take the lock */
3493034979
struct flock *pLock, /* The description of the lock */
3493134980
unixFile *pFile /* Structure holding timeout value */
3493234981
){
34982
+ int tm = pFile->iBusyTimeout;
3493334983
int rc = osFcntl(h,F_SETLK,pLock);
34934
- while( rc<0 && pFile->iBusyTimeout>0 ){
34984
+ while( rc<0 && tm>0 ){
3493534985
/* On systems that support some kind of blocking file lock with a timeout,
3493634986
** make appropriate changes here to invoke that blocking file lock. On
3493734987
** generic posix, however, there is no such API. So we simply try the
3493834988
** lock once every millisecond until either the timeout expires, or until
3493934989
** the lock is obtained. */
3494034990
usleep(1000);
3494134991
rc = osFcntl(h,F_SETLK,pLock);
34942
- pFile->iBusyTimeout--;
34992
+ tm--;
3494334993
}
3494434994
return rc;
3494534995
}
3494634996
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
3494734997
@@ -37679,17 +37729,24 @@
3767937729
3768037730
/* Locks are within range */
3768137731
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
3768237732
3768337733
if( pShmNode->hShm>=0 ){
37734
+ int res;
3768437735
/* Initialize the locking parameters */
3768537736
f.l_type = lockType;
3768637737
f.l_whence = SEEK_SET;
3768737738
f.l_start = ofst;
3768837739
f.l_len = n;
37689
- rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
37690
- rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
37740
+ res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
37741
+ if( res==-1 ){
37742
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
37743
+ rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
37744
+#else
37745
+ rc = SQLITE_BUSY;
37746
+#endif
37747
+ }
3769137748
}
3769237749
3769337750
/* Update the global lock state and do debug tracing */
3769437751
#ifdef SQLITE_DEBUG
3769537752
{ u16 mask;
@@ -38182,26 +38239,27 @@
3818238239
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
3818338240
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
3818438241
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
3818538242
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
3818638243
38187
- /* Check that, if this to be a blocking lock, that locks have been
38188
- ** obtained in the following order.
38244
+ /* Check that, if this to be a blocking lock, no locks that occur later
38245
+ ** in the following list than the lock being obtained are already held:
3818938246
**
3819038247
** 1. Checkpointer lock (ofst==1).
38191
- ** 2. Recover lock (ofst==2).
38248
+ ** 2. Write lock (ofst==0).
3819238249
** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
38193
- ** 4. Write lock (ofst==0).
3819438250
**
3819538251
** In other words, if this is a blocking lock, none of the locks that
3819638252
** occur later in the above list than the lock being obtained may be
3819738253
** held. */
3819838254
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
38199
- assert( pDbFd->iBusyTimeout==0
38200
- || (flags & SQLITE_SHM_UNLOCK) || ofst==0
38201
- || ((p->exclMask|p->sharedMask)&~((1<<ofst)-2))==0
38202
- );
38255
+ assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
38256
+ (ofst!=2) /* not RECOVER */
38257
+ && (ofst!=1 || (p->exclMask|p->sharedMask)==0)
38258
+ && (ofst!=0 || (p->exclMask|p->sharedMask)<3)
38259
+ && (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
38260
+ ));
3820338261
#endif
3820438262
3820538263
mask = (1<<(ofst+n)) - (1<<ofst);
3820638264
assert( n>1 || mask==(1<<ofst) );
3820738265
sqlite3_mutex_enter(pShmNode->pShmMutex);
@@ -51505,10 +51563,15 @@
5150551563
SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
5150651564
#endif
5150751565
5150851566
/* Return the sqlite3_file object for the WAL file */
5150951567
SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
51568
+
51569
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
51570
+SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock);
51571
+SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db);
51572
+#endif
5151051573
5151151574
#endif /* ifndef SQLITE_OMIT_WAL */
5151251575
#endif /* SQLITE_WAL_H */
5151351576
5151451577
/************** End of wal.h *************************************************/
@@ -54026,13 +54089,16 @@
5402654089
}
5402754090
if( exists ){
5402854091
/* One of the journals pointed to by the master journal exists.
5402954092
** Open it and check if it points at the master journal. If
5403054093
** so, return without deleting the master journal file.
54094
+ ** NB: zJournal is really a MAIN_JOURNAL. But call it a
54095
+ ** MASTER_JOURNAL here so that the VFS will not send the zJournal
54096
+ ** name into sqlite3_database_file_object().
5403154097
*/
5403254098
int c;
54033
- int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
54099
+ int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
5403454100
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
5403554101
if( rc!=SQLITE_OK ){
5403654102
goto delmaster_out;
5403754103
}
5403854104
@@ -56232,10 +56298,11 @@
5623256298
** Pager object (sizeof(Pager) bytes)
5623356299
** PCache object (sqlite3PcacheSize() bytes)
5623456300
** Database file handle (pVfs->szOsFile bytes)
5623556301
** Sub-journal file handle (journalFileSize bytes)
5623656302
** Main journal file handle (journalFileSize bytes)
56303
+ ** Ptr back to the Pager (sizeof(Pager*) bytes)
5623756304
** \0\0\0\0 database prefix (4 bytes)
5623856305
** Database file name (nPathname+1 bytes)
5623956306
** URI query parameters (nUriByte bytes)
5624056307
** Journal filename (nPathname+8+1 bytes)
5624156308
** WAL filename (nPathname+4+1 bytes)
@@ -56271,10 +56338,11 @@
5627156338
pPtr = (u8 *)sqlite3MallocZero(
5627256339
ROUND8(sizeof(*pPager)) + /* Pager structure */
5627356340
ROUND8(pcacheSize) + /* PCache object */
5627456341
ROUND8(pVfs->szOsFile) + /* The main db file */
5627556342
journalFileSize * 2 + /* The two journal files */
56343
+ sizeof(pPager) + /* Space to hold a pointer */
5627656344
4 + /* Database prefix */
5627756345
nPathname + 1 + /* database filename */
5627856346
nUriByte + /* query parameters */
5627956347
nPathname + 8 + 1 + /* Journal filename */
5628056348
#ifndef SQLITE_OMIT_WAL
@@ -56291,10 +56359,11 @@
5629156359
pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
5629256360
pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
5629356361
pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
5629456362
pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
5629556363
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
56364
+ memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
5629656365
5629756366
/* Fill in the Pager.zFilename and pPager.zQueryParam fields */
5629856367
pPtr += 4; /* Skip zero prefix */
5629956368
pPager->zFilename = (char*)pPtr;
5630056369
if( nPathname>0 ){
@@ -56491,10 +56560,23 @@
5649156560
5649256561
*ppPager = pPager;
5649356562
return SQLITE_OK;
5649456563
}
5649556564
56565
+/*
56566
+** Return the sqlite3_file for the main database given the name
56567
+** of the corresonding WAL or Journal name as passed into
56568
+** xOpen.
56569
+*/
56570
+SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){
56571
+ Pager *pPager;
56572
+ while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
56573
+ zName--;
56574
+ }
56575
+ pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
56576
+ return pPager->fd;
56577
+}
5649656578
5649756579
5649856580
/*
5649956581
** This function is called after transitioning from PAGER_UNLOCK to
5650056582
** PAGER_SHARED state. It tests if there is a hot journal present in
@@ -57176,11 +57258,10 @@
5717657258
Pager *pPager;
5717757259
assert( pPg!=0 );
5717857260
assert( pPg->pgno==1 );
5717957261
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
5718057262
pPager = pPg->pPager;
57181
- sqlite3PagerResetLockTimeout(pPager);
5718257263
sqlite3PcacheRelease(pPg);
5718357264
pagerUnlockIfUnused(pPager);
5718457265
}
5718557266
5718657267
/*
@@ -58469,20 +58550,10 @@
5846958550
*/
5847058551
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
5847158552
return pPager->fd;
5847258553
}
5847358554
58474
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
58475
-/*
58476
-** Reset the lock timeout for pager.
58477
-*/
58478
-SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){
58479
- int x = 0;
58480
- sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
58481
-}
58482
-#endif
58483
-
5848458555
/*
5848558556
** Return the file handle for the journal file (if it exists).
5848658557
** This will be either the rollback journal or the WAL file.
5848758558
*/
5848858559
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
@@ -58892,11 +58963,10 @@
5889258963
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
5889358964
pPager->pBusyHandlerArg,
5889458965
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
5889558966
pnLog, pnCkpt
5889658967
);
58897
- sqlite3PagerResetLockTimeout(pPager);
5889858968
}
5889958969
return rc;
5890058970
}
5890158971
5890258972
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
@@ -59057,11 +59127,35 @@
5905759127
}
5905859128
}
5905959129
return rc;
5906059130
}
5906159131
59132
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
59133
+/*
59134
+** If pager pPager is a wal-mode database not in exclusive locking mode,
59135
+** invoke the sqlite3WalWriteLock() function on the associated Wal object
59136
+** with the same db and bLock parameters as were passed to this function.
59137
+** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
59138
+*/
59139
+SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){
59140
+ int rc = SQLITE_OK;
59141
+ if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){
59142
+ rc = sqlite3WalWriteLock(pPager->pWal, bLock);
59143
+ }
59144
+ return rc;
59145
+}
5906259146
59147
+/*
59148
+** Set the database handle used by the wal layer to determine if
59149
+** blocking locks are required.
59150
+*/
59151
+SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
59152
+ if( pagerUseWal(pPager) ){
59153
+ sqlite3WalDb(pPager->pWal, db);
59154
+ }
59155
+}
59156
+#endif
5906359157
5906459158
#ifdef SQLITE_ENABLE_SNAPSHOT
5906559159
/*
5906659160
** If this is a WAL database, obtain a snapshot handle for the snapshot
5906759161
** currently open. Otherwise, return an error.
@@ -59077,11 +59171,14 @@
5907759171
/*
5907859172
** If this is a WAL database, store a pointer to pSnapshot. Next time a
5907959173
** read transaction is opened, attempt to read from the snapshot it
5908059174
** identifies. If this is not a WAL database, return an error.
5908159175
*/
59082
-SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
59176
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(
59177
+ Pager *pPager,
59178
+ sqlite3_snapshot *pSnapshot
59179
+){
5908359180
int rc = SQLITE_OK;
5908459181
if( pPager->pWal ){
5908559182
sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
5908659183
}else{
5908759184
rc = SQLITE_ERROR;
@@ -59622,10 +59719,13 @@
5962259719
u8 lockError; /* True if a locking error has occurred */
5962359720
#endif
5962459721
#ifdef SQLITE_ENABLE_SNAPSHOT
5962559722
WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
5962659723
#endif
59724
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
59725
+ sqlite3 *db;
59726
+#endif
5962759727
};
5962859728
5962959729
/*
5963059730
** Candidate values for Wal.exclusiveMode.
5963159731
*/
@@ -59995,11 +60095,11 @@
5999560095
if( pWal->exclusiveMode ) return SQLITE_OK;
5999660096
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
5999760097
SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
5999860098
WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
5999960099
walLockName(lockIdx), rc ? "failed" : "ok"));
60000
- VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
60100
+ VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
6000160101
return rc;
6000260102
}
6000360103
static void walUnlockShared(Wal *pWal, int lockIdx){
6000460104
if( pWal->exclusiveMode ) return;
6000560105
(void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
@@ -60011,11 +60111,11 @@
6001160111
if( pWal->exclusiveMode ) return SQLITE_OK;
6001260112
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
6001360113
SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
6001460114
WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
6001560115
walLockName(lockIdx), n, rc ? "failed" : "ok"));
60016
- VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
60116
+ VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
6001760117
return rc;
6001860118
}
6001960119
static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
6002060120
if( pWal->exclusiveMode ) return;
6002160121
(void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
@@ -60283,15 +60383,10 @@
6028360383
int rc; /* Return Code */
6028460384
i64 nSize; /* Size of log file */
6028560385
u32 aFrameCksum[2] = {0, 0};
6028660386
int iLock; /* Lock offset to lock for checkpoint */
6028760387
60288
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
60289
- int tmout = 0;
60290
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
60291
-#endif
60292
-
6029360388
/* Obtain an exclusive lock on all byte in the locking range not already
6029460389
** locked by the caller. The caller is guaranteed to have locked the
6029560390
** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
6029660391
** If successful, the same bytes that are locked here are unlocked before
6029760392
** this function returns.
@@ -60835,10 +60930,93 @@
6083560930
p = 0;
6083660931
}
6083760932
*pp = p;
6083860933
return rc;
6083960934
}
60935
+
60936
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
60937
+/*
60938
+** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
60939
+** they are supported by the VFS, and (b) the database handle is configured
60940
+** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
60941
+** or 0 otherwise.
60942
+*/
60943
+static int walEnableBlocking(Wal *pWal){
60944
+ int res = 0;
60945
+ if( pWal->db ){
60946
+ int tmout = pWal->db->busyTimeout;
60947
+ if( tmout ){
60948
+ int rc;
60949
+ rc = sqlite3OsFileControl(
60950
+ pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
60951
+ );
60952
+ res = (rc==SQLITE_OK);
60953
+ }
60954
+ }
60955
+ return res;
60956
+}
60957
+
60958
+/*
60959
+** Disable blocking locks.
60960
+*/
60961
+static void walDisableBlocking(Wal *pWal){
60962
+ int tmout = 0;
60963
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
60964
+}
60965
+
60966
+/*
60967
+** If parameter bLock is true, attempt to enable blocking locks, take
60968
+** the WRITER lock, and then disable blocking locks. If blocking locks
60969
+** cannot be enabled, no attempt to obtain the WRITER lock is made. Return
60970
+** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not
60971
+** an error if blocking locks can not be enabled.
60972
+**
60973
+** If the bLock parameter is false and the WRITER lock is held, release it.
60974
+*/
60975
+SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){
60976
+ int rc = SQLITE_OK;
60977
+ assert( pWal->readLock<0 || bLock==0 );
60978
+ if( bLock ){
60979
+ assert( pWal->db );
60980
+ if( walEnableBlocking(pWal) ){
60981
+ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
60982
+ if( rc==SQLITE_OK ){
60983
+ pWal->writeLock = 1;
60984
+ }
60985
+ walDisableBlocking(pWal);
60986
+ }
60987
+ }else if( pWal->writeLock ){
60988
+ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
60989
+ pWal->writeLock = 0;
60990
+ }
60991
+ return rc;
60992
+}
60993
+
60994
+/*
60995
+** Set the database handle used to determine if blocking locks are required.
60996
+*/
60997
+SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
60998
+ pWal->db = db;
60999
+}
61000
+
61001
+/*
61002
+** Take an exclusive WRITE lock. Blocking if so configured.
61003
+*/
61004
+static int walLockWriter(Wal *pWal){
61005
+ int rc;
61006
+ walEnableBlocking(pWal);
61007
+ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
61008
+ walDisableBlocking(pWal);
61009
+ return rc;
61010
+}
61011
+#else
61012
+# define walEnableBlocking(x) 0
61013
+# define walDisableBlocking(x)
61014
+# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
61015
+# define sqlite3WalDb(pWal, db)
61016
+#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
61017
+
6084061018
6084161019
/*
6084261020
** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
6084361021
** n. If the attempt fails and parameter xBusy is not NULL, then it is a
6084461022
** busy-handler function. Invoke it and retry the lock until either the
@@ -60853,10 +61031,16 @@
6085361031
){
6085461032
int rc;
6085561033
do {
6085661034
rc = walLockExclusive(pWal, lockIdx, n);
6085761035
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
61036
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61037
+ if( rc==SQLITE_BUSY_TIMEOUT ){
61038
+ walDisableBlocking(pWal);
61039
+ rc = SQLITE_BUSY;
61040
+ }
61041
+#endif
6085861042
return rc;
6085961043
}
6086061044
6086161045
/*
6086261046
** The cache of the wal-index header must be valid to call this function.
@@ -61023,10 +61207,11 @@
6102361207
** about the eventual size of the db file to the VFS layer.
6102461208
*/
6102561209
if( rc==SQLITE_OK ){
6102661210
i64 nReq = ((i64)mxPage * szPage);
6102761211
i64 nSize; /* Current size of database file */
61212
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
6102861213
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
6102961214
if( rc==SQLITE_OK && nSize<nReq ){
6103061215
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
6103161216
}
6103261217
}
@@ -61050,10 +61235,11 @@
6105061235
iOffset = (iDbpage-1)*(i64)szPage;
6105161236
testcase( IS_BIG_INT(iOffset) );
6105261237
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
6105361238
if( rc!=SQLITE_OK ) break;
6105461239
}
61240
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
6105561241
6105661242
/* If work was actually accomplished... */
6105761243
if( rc==SQLITE_OK ){
6105861244
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
6105961245
i64 szDb = pWal->hdr.nPage*(i64)szPage;
@@ -61061,14 +61247,10 @@
6106161247
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
6106261248
if( rc==SQLITE_OK ){
6106361249
rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
6106461250
}
6106561251
}
61066
- if( rc==SQLITE_OK ){
61067
- rc = sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
61068
- if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
61069
- }
6107061252
if( rc==SQLITE_OK ){
6107161253
pInfo->nBackfill = mxSafeFrame;
6107261254
}
6107361255
}
6107461256
@@ -61334,32 +61516,36 @@
6133461516
badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
6133561517
6133661518
/* If the first attempt failed, it might have been due to a race
6133761519
** with a writer. So get a WRITE lock and try again.
6133861520
*/
61339
- assert( badHdr==0 || pWal->writeLock==0 );
6134061521
if( badHdr ){
6134161522
if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
6134261523
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
6134361524
walUnlockShared(pWal, WAL_WRITE_LOCK);
6134461525
rc = SQLITE_READONLY_RECOVERY;
6134561526
}
61346
- }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
61347
- pWal->writeLock = 1;
61348
- if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
61349
- badHdr = walIndexTryHdr(pWal, pChanged);
61350
- if( badHdr ){
61351
- /* If the wal-index header is still malformed even while holding
61352
- ** a WRITE lock, it can only mean that the header is corrupted and
61353
- ** needs to be reconstructed. So run recovery to do exactly that.
61354
- */
61355
- rc = walIndexRecover(pWal);
61356
- *pChanged = 1;
61357
- }
61358
- }
61359
- pWal->writeLock = 0;
61360
- walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
61527
+ }else{
61528
+ int bWriteLock = pWal->writeLock;
61529
+ if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
61530
+ pWal->writeLock = 1;
61531
+ if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
61532
+ badHdr = walIndexTryHdr(pWal, pChanged);
61533
+ if( badHdr ){
61534
+ /* If the wal-index header is still malformed even while holding
61535
+ ** a WRITE lock, it can only mean that the header is corrupted and
61536
+ ** needs to be reconstructed. So run recovery to do exactly that.
61537
+ */
61538
+ rc = walIndexRecover(pWal);
61539
+ *pChanged = 1;
61540
+ }
61541
+ }
61542
+ if( bWriteLock==0 ){
61543
+ pWal->writeLock = 0;
61544
+ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
61545
+ }
61546
+ }
6136161547
}
6136261548
}
6136361549
6136461550
/* If the header is read successfully, check the version number to make
6136561551
** sure the wal-index was not constructed with some future format that
@@ -61907,26 +62093,38 @@
6190762093
** needs to be flushed.
6190862094
*/
6190962095
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
6191062096
int rc; /* Return code */
6191162097
int cnt = 0; /* Number of TryBeginRead attempts */
61912
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61913
- int tmout = 0;
61914
-#endif
62098
+
62099
+ assert( pWal->ckptLock==0 );
6191562100
6191662101
#ifdef SQLITE_ENABLE_SNAPSHOT
6191762102
int bChanged = 0;
6191862103
WalIndexHdr *pSnapshot = pWal->pSnapshot;
61919
- if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
61920
- bChanged = 1;
61921
- }
61922
-#endif
61923
-
61924
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61925
- /* Disable blocking locks. They are not useful when trying to open a
61926
- ** read-transaction, and blocking may cause deadlock anyway. */
61927
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
62104
+ if( pSnapshot ){
62105
+ if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
62106
+ bChanged = 1;
62107
+ }
62108
+
62109
+ /* It is possible that there is a checkpointer thread running
62110
+ ** concurrent with this code. If this is the case, it may be that the
62111
+ ** checkpointer has already determined that it will checkpoint
62112
+ ** snapshot X, where X is later in the wal file than pSnapshot, but
62113
+ ** has not yet set the pInfo->nBackfillAttempted variable to indicate
62114
+ ** its intent. To avoid the race condition this leads to, ensure that
62115
+ ** there is no checkpointer process by taking a shared CKPT lock
62116
+ ** before checking pInfo->nBackfillAttempted. */
62117
+ (void)walEnableBlocking(pWal);
62118
+ rc = walLockShared(pWal, WAL_CKPT_LOCK);
62119
+ walDisableBlocking(pWal);
62120
+
62121
+ if( rc!=SQLITE_OK ){
62122
+ return rc;
62123
+ }
62124
+ pWal->ckptLock = 1;
62125
+ }
6192862126
#endif
6192962127
6193062128
do{
6193162129
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
6193262130
}while( rc==WAL_RETRY );
@@ -61933,20 +62131,10 @@
6193362131
testcase( (rc&0xff)==SQLITE_BUSY );
6193462132
testcase( (rc&0xff)==SQLITE_IOERR );
6193562133
testcase( rc==SQLITE_PROTOCOL );
6193662134
testcase( rc==SQLITE_OK );
6193762135
61938
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61939
- /* If they were disabled earlier and the read-transaction has been
61940
- ** successfully opened, re-enable blocking locks. This is because the
61941
- ** connection may attempt to upgrade to a write-transaction, which does
61942
- ** benefit from using blocking locks. */
61943
- if( rc==SQLITE_OK ){
61944
- sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
61945
- }
61946
-#endif
61947
-
6194862136
#ifdef SQLITE_ENABLE_SNAPSHOT
6194962137
if( rc==SQLITE_OK ){
6195062138
if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
6195162139
/* At this point the client has a lock on an aReadMark[] slot holding
6195262140
** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
@@ -61964,52 +62152,46 @@
6196462152
volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
6196562153
6196662154
assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
6196762155
assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
6196862156
61969
- /* It is possible that there is a checkpointer thread running
61970
- ** concurrent with this code. If this is the case, it may be that the
61971
- ** checkpointer has already determined that it will checkpoint
61972
- ** snapshot X, where X is later in the wal file than pSnapshot, but
61973
- ** has not yet set the pInfo->nBackfillAttempted variable to indicate
61974
- ** its intent. To avoid the race condition this leads to, ensure that
61975
- ** there is no checkpointer process by taking a shared CKPT lock
61976
- ** before checking pInfo->nBackfillAttempted.
61977
- **
61978
- ** TODO: Does the aReadMark[] lock prevent a checkpointer from doing
61979
- ** this already?
61980
- */
61981
- rc = walLockShared(pWal, WAL_CKPT_LOCK);
61982
-
61983
- if( rc==SQLITE_OK ){
61984
- /* Check that the wal file has not been wrapped. Assuming that it has
61985
- ** not, also check that no checkpointer has attempted to checkpoint any
61986
- ** frames beyond pSnapshot->mxFrame. If either of these conditions are
61987
- ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
61988
- ** with *pSnapshot and set *pChanged as appropriate for opening the
61989
- ** snapshot. */
61990
- if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
61991
- && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
61992
- ){
61993
- assert( pWal->readLock>0 );
61994
- memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
61995
- *pChanged = bChanged;
61996
- }else{
61997
- rc = SQLITE_ERROR_SNAPSHOT;
61998
- }
61999
-
62000
- /* Release the shared CKPT lock obtained above. */
62001
- walUnlockShared(pWal, WAL_CKPT_LOCK);
62002
- pWal->minFrame = 1;
62003
- }
62004
-
62157
+ /* Check that the wal file has not been wrapped. Assuming that it has
62158
+ ** not, also check that no checkpointer has attempted to checkpoint any
62159
+ ** frames beyond pSnapshot->mxFrame. If either of these conditions are
62160
+ ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
62161
+ ** with *pSnapshot and set *pChanged as appropriate for opening the
62162
+ ** snapshot. */
62163
+ if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
62164
+ && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
62165
+ ){
62166
+ assert( pWal->readLock>0 );
62167
+ memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
62168
+ *pChanged = bChanged;
62169
+ }else{
62170
+ rc = SQLITE_ERROR_SNAPSHOT;
62171
+ }
62172
+
62173
+ /* A client using a non-current snapshot may not ignore any frames
62174
+ ** from the start of the wal file. This is because, for a system
62175
+ ** where (minFrame < iSnapshot < maxFrame), a checkpointer may
62176
+ ** have omitted to checkpoint a frame earlier than minFrame in
62177
+ ** the file because there exists a frame after iSnapshot that
62178
+ ** is the same database page. */
62179
+ pWal->minFrame = 1;
6200562180
6200662181
if( rc!=SQLITE_OK ){
6200762182
sqlite3WalEndReadTransaction(pWal);
6200862183
}
6200962184
}
6201062185
}
62186
+
62187
+ /* Release the shared CKPT lock obtained above. */
62188
+ if( pWal->ckptLock ){
62189
+ assert( pSnapshot );
62190
+ walUnlockShared(pWal, WAL_CKPT_LOCK);
62191
+ pWal->ckptLock = 0;
62192
+ }
6201162193
#endif
6201262194
return rc;
6201362195
}
6201462196
6201562197
/*
@@ -62175,10 +62357,20 @@
6217562357
**
6217662358
** There can only be a single writer active at a time.
6217762359
*/
6217862360
SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
6217962361
int rc;
62362
+
62363
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
62364
+ /* If the write-lock is already held, then it was obtained before the
62365
+ ** read-transaction was even opened, making this call a no-op.
62366
+ ** Return early. */
62367
+ if( pWal->writeLock ){
62368
+ assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
62369
+ return SQLITE_OK;
62370
+ }
62371
+#endif
6218062372
6218162373
/* Cannot start a write transaction without first holding a read
6218262374
** transaction. */
6218362375
assert( pWal->readLock>=0 );
6218462376
assert( pWal->writeLock==0 && pWal->iReCksum==0 );
@@ -62751,50 +62943,57 @@
6275162943
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
6275262944
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
6275362945
6275462946
if( pWal->readOnly ) return SQLITE_READONLY;
6275562947
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
62948
+
62949
+ /* Enable blocking locks, if possible. If blocking locks are successfully
62950
+ ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
62951
+ sqlite3WalDb(pWal, db);
62952
+ (void)walEnableBlocking(pWal);
6275662953
6275762954
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
62758
- ** "checkpoint" lock on the database file. */
62955
+ ** "checkpoint" lock on the database file.
62956
+ ** EVIDENCE-OF: R-10421-19736 If any other process is running a
62957
+ ** checkpoint operation at the same time, the lock cannot be obtained and
62958
+ ** SQLITE_BUSY is returned.
62959
+ ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
62960
+ ** it will not be invoked in this case.
62961
+ */
6275962962
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
62760
- if( rc ){
62761
- /* EVIDENCE-OF: R-10421-19736 If any other process is running a
62762
- ** checkpoint operation at the same time, the lock cannot be obtained and
62763
- ** SQLITE_BUSY is returned.
62764
- ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
62765
- ** it will not be invoked in this case.
62766
- */
62767
- testcase( rc==SQLITE_BUSY );
62768
- testcase( xBusy!=0 );
62769
- return rc;
62770
- }
62771
- pWal->ckptLock = 1;
62772
-
62773
- /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
62774
- ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
62775
- ** file.
62776
- **
62777
- ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
62778
- ** immediately, and a busy-handler is configured, it is invoked and the
62779
- ** writer lock retried until either the busy-handler returns 0 or the
62780
- ** lock is successfully obtained.
62781
- */
62782
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
62783
- rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
62784
- if( rc==SQLITE_OK ){
62785
- pWal->writeLock = 1;
62786
- }else if( rc==SQLITE_BUSY ){
62787
- eMode2 = SQLITE_CHECKPOINT_PASSIVE;
62788
- xBusy2 = 0;
62789
- rc = SQLITE_OK;
62790
- }
62791
- }
62963
+ testcase( rc==SQLITE_BUSY );
62964
+ testcase( rc!=SQLITE_OK && xBusy2!=0 );
62965
+ if( rc==SQLITE_OK ){
62966
+ pWal->ckptLock = 1;
62967
+
62968
+ /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
62969
+ ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
62970
+ ** file.
62971
+ **
62972
+ ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
62973
+ ** immediately, and a busy-handler is configured, it is invoked and the
62974
+ ** writer lock retried until either the busy-handler returns 0 or the
62975
+ ** lock is successfully obtained.
62976
+ */
62977
+ if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
62978
+ rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
62979
+ if( rc==SQLITE_OK ){
62980
+ pWal->writeLock = 1;
62981
+ }else if( rc==SQLITE_BUSY ){
62982
+ eMode2 = SQLITE_CHECKPOINT_PASSIVE;
62983
+ xBusy2 = 0;
62984
+ rc = SQLITE_OK;
62985
+ }
62986
+ }
62987
+ }
62988
+
6279262989
6279362990
/* Read the wal-index header. */
6279462991
if( rc==SQLITE_OK ){
62992
+ walDisableBlocking(pWal);
6279562993
rc = walIndexReadHdr(pWal, &isChanged);
62994
+ (void)walEnableBlocking(pWal);
6279662995
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
6279762996
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
6279862997
}
6279962998
}
6280062999
@@ -62821,16 +63020,24 @@
6282163020
** next time the pager opens a snapshot on this database it knows that
6282263021
** the cache needs to be reset.
6282363022
*/
6282463023
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
6282563024
}
63025
+
63026
+ walDisableBlocking(pWal);
63027
+ sqlite3WalDb(pWal, 0);
6282663028
6282763029
/* Release the locks. */
6282863030
sqlite3WalEndWriteTransaction(pWal);
62829
- walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
62830
- pWal->ckptLock = 0;
63031
+ if( pWal->ckptLock ){
63032
+ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
63033
+ pWal->ckptLock = 0;
63034
+ }
6283163035
WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
63036
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
63037
+ if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
63038
+#endif
6283263039
return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
6283363040
}
6283463041
6283563042
/* Return the value to pass to a sqlite3_wal_hook callback, the
6283663043
** number of frames in the WAL at the point of the last commit since
@@ -62943,11 +63150,14 @@
6294363150
return rc;
6294463151
}
6294563152
6294663153
/* Try to open on pSnapshot when the next read-transaction starts
6294763154
*/
62948
-SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
63155
+SQLITE_PRIVATE void sqlite3WalSnapshotOpen(
63156
+ Wal *pWal,
63157
+ sqlite3_snapshot *pSnapshot
63158
+){
6294963159
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
6295063160
}
6295163161
6295263162
/*
6295363163
** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
@@ -63462,11 +63672,11 @@
6346263672
u8 incrVacuum; /* True if incr-vacuum is enabled */
6346363673
u8 bDoTruncate; /* True to truncate db on commit */
6346463674
#endif
6346563675
u8 inTransaction; /* Transaction state */
6346663676
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
63467
- u8 nReserveWanted; /* 1 more than desired number of extra bytes per page */
63677
+ u8 nReserveWanted; /* Desired number of extra bytes per page */
6346863678
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
6346963679
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
6347063680
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
6347163681
u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */
6347263682
u16 minLeaf; /* Minimum local payload in a LEAFDATA table */
@@ -66356,12 +66566,11 @@
6635666566
*/
6635766567
static int btreeInvokeBusyHandler(void *pArg){
6635866568
BtShared *pBt = (BtShared*)pArg;
6635966569
assert( pBt->db );
6636066570
assert( sqlite3_mutex_held(pBt->db->mutex) );
66361
- return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
66362
- sqlite3PagerFile(pBt->pPager));
66571
+ return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
6636366572
}
6636466573
6636566574
/*
6636666575
** Open a database file.
6636766576
**
@@ -66908,23 +67117,21 @@
6690867117
** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
6690967118
** and autovacuum mode can no longer be changed.
6691067119
*/
6691167120
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
6691267121
int rc = SQLITE_OK;
67122
+ int x;
6691367123
BtShared *pBt = p->pBt;
66914
- assert( nReserve>=-1 && nReserve<=254 );
67124
+ assert( nReserve>=0 && nReserve<=255 );
6691567125
sqlite3BtreeEnter(p);
66916
- if( nReserve>=0 ){
66917
- pBt->nReserveWanted = nReserve + 1;
66918
- }
67126
+ pBt->nReserveWanted = nReserve;
67127
+ x = pBt->pageSize - pBt->usableSize;
67128
+ if( nReserve<x ) nReserve = x;
6691967129
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
6692067130
sqlite3BtreeLeave(p);
6692167131
return SQLITE_READONLY;
6692267132
}
66923
- if( nReserve<0 ){
66924
- nReserve = pBt->pageSize - pBt->usableSize;
66925
- }
6692667133
assert( nReserve>=0 && nReserve<=255 );
6692767134
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
6692867135
((pageSize-1)&pageSize)==0 ){
6692967136
assert( (pageSize & 7)==0 );
6693067137
assert( !pBt->pCursor );
@@ -66965,18 +67172,22 @@
6696567172
6696667173
/*
6696767174
** Return the number of bytes of space at the end of every page that
6696867175
** are intentually left unused. This is the "reserved" space that is
6696967176
** sometimes used by extensions.
67177
+**
67178
+** The value returned is the larger of the current reserve size and
67179
+** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
67180
+** The amount of reserve can only grow - never shrink.
6697067181
*/
6697167182
SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){
66972
- int n;
67183
+ int n1, n2;
6697367184
sqlite3BtreeEnter(p);
66974
- n = ((int)p->pBt->nReserveWanted) - 1;
66975
- if( n<0 ) n = sqlite3BtreeGetReserveNoMutex(p);
67185
+ n1 = (int)p->pBt->nReserveWanted;
67186
+ n2 = sqlite3BtreeGetReserveNoMutex(p);
6697667187
sqlite3BtreeLeave(p);
66977
- return n;
67188
+ return n1>n2 ? n1 : n2;
6697867189
}
6697967190
6698067191
6698167192
/*
6698267193
** Set the maximum page count for a database if mxPage is positive.
@@ -67422,10 +67633,11 @@
6742267633
** when A already has a read lock, we encourage A to give up and let B
6742367634
** proceed.
6742467635
*/
6742567636
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
6742667637
BtShared *pBt = p->pBt;
67638
+ Pager *pPager = pBt->pPager;
6742767639
int rc = SQLITE_OK;
6742867640
6742967641
sqlite3BtreeEnter(p);
6743067642
btreeIntegrity(p);
6743167643
@@ -67437,11 +67649,11 @@
6743767649
goto trans_begun;
6743867650
}
6743967651
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
6744067652
6744167653
if( (p->db->flags & SQLITE_ResetDatabase)
67442
- && sqlite3PagerIsreadonly(pBt->pPager)==0
67654
+ && sqlite3PagerIsreadonly(pPager)==0
6744367655
){
6744467656
pBt->btsFlags &= ~BTS_READ_ONLY;
6744567657
}
6744667658
6744767659
/* Write transactions are not possible on a read-only database */
@@ -67485,10 +67697,22 @@
6748567697
if( SQLITE_OK!=rc ) goto trans_begun;
6748667698
6748767699
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
6748867700
if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
6748967701
do {
67702
+ sqlite3PagerWalDb(pPager, p->db);
67703
+
67704
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67705
+ /* If transitioning from no transaction directly to a write transaction,
67706
+ ** block for the WRITER lock first if possible. */
67707
+ if( pBt->pPage1==0 && wrflag ){
67708
+ assert( pBt->inTransaction==TRANS_NONE );
67709
+ rc = sqlite3PagerWalWriteLock(pPager, 1);
67710
+ if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
67711
+ }
67712
+#endif
67713
+
6749067714
/* Call lockBtree() until either pBt->pPage1 is populated or
6749167715
** lockBtree() returns something other than SQLITE_OK. lockBtree()
6749267716
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
6749367717
** reading page 1 it discovers that the page-size of the database
6749467718
** file is not pBt->pageSize. In this case lockBtree() will update
@@ -67498,11 +67722,11 @@
6749867722
6749967723
if( rc==SQLITE_OK && wrflag ){
6750067724
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
6750167725
rc = SQLITE_READONLY;
6750267726
}else{
67503
- rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
67727
+ rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db));
6750467728
if( rc==SQLITE_OK ){
6750567729
rc = newDatabase(pBt);
6750667730
}else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
6750767731
/* if there was no transaction opened when this function was
6750867732
** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
@@ -67511,15 +67735,19 @@
6751167735
}
6751267736
}
6751367737
}
6751467738
6751567739
if( rc!=SQLITE_OK ){
67740
+ (void)sqlite3PagerWalWriteLock(pPager, 0);
6751667741
unlockBtreeIfUnused(pBt);
6751767742
}
6751867743
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
6751967744
btreeInvokeBusyHandler(pBt) );
67520
- sqlite3PagerResetLockTimeout(pBt->pPager);
67745
+ sqlite3PagerWalDb(pPager, 0);
67746
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67747
+ if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
67748
+#endif
6752167749
6752267750
if( rc==SQLITE_OK ){
6752367751
if( p->inTrans==TRANS_NONE ){
6752467752
pBt->nTransaction++;
6752567753
#ifndef SQLITE_OMIT_SHARED_CACHE
@@ -67567,11 +67795,11 @@
6756767795
if( wrflag ){
6756867796
/* This call makes sure that the pager has the correct number of
6756967797
** open savepoints. If the second parameter is greater than 0 and
6757067798
** the sub-journal is not already open, then it will be opened here.
6757167799
*/
67572
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
67800
+ rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint);
6757367801
}
6757467802
}
6757567803
6757667804
btreeIntegrity(p);
6757767805
sqlite3BtreeLeave(p);
@@ -71203,11 +71431,11 @@
7120371431
7120471432
/* Remove cells from the start and end of the page */
7120571433
assert( nCell>=0 );
7120671434
if( iOld<iNew ){
7120771435
int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
71208
- if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
71436
+ if( NEVER(nShift>nCell) ) return SQLITE_CORRUPT_BKPT;
7120971437
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
7121071438
nCell -= nShift;
7121171439
}
7121271440
if( iNewEnd < iOldEnd ){
7121371441
int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
@@ -73560,11 +73788,10 @@
7356073788
}
7356173789
sqlite3BtreeLeave(p);
7356273790
return rc;
7356373791
}
7356473792
73565
-#ifndef SQLITE_OMIT_BTREECOUNT
7356673793
/*
7356773794
** The first argument, pCur, is a cursor opened on some b-tree. Count the
7356873795
** number of entries in the b-tree and write the result to *pnEntry.
7356973796
**
7357073797
** SQLITE_OK is returned if the operation is successfully executed.
@@ -73633,11 +73860,10 @@
7363373860
}
7363473861
7363573862
/* An error has occurred. Return an error code. */
7363673863
return rc;
7363773864
}
73638
-#endif
7363973865
7364073866
/*
7364173867
** Return the pager associated with a BTree. This routine is used for
7364273868
** testing and debugging only.
7364373869
*/
@@ -74684,11 +74910,11 @@
7468474910
** Attempt to set the page size of the destination to match the page size
7468574911
** of the source.
7468674912
*/
7468774913
static int setDestPgsz(sqlite3_backup *p){
7468874914
int rc;
74689
- rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
74915
+ rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
7469074916
return rc;
7469174917
}
7469274918
7469374919
/*
7469474920
** Check that there is no open read-transaction on the b-tree passed as the
@@ -78709,24 +78935,23 @@
7870978935
** "PX" -> "r[X]"
7871078936
** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
7871178937
** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
7871278938
** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
7871378939
*/
78714
-static int displayComment(
78940
+SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
78941
+ sqlite3 *db, /* Optional - Oom error reporting only */
7871578942
const Op *pOp, /* The opcode to be commented */
78716
- const char *zP4, /* Previously obtained value for P4 */
78717
- char *zTemp, /* Write result here */
78718
- int nTemp /* Space available in zTemp[] */
78943
+ const char *zP4 /* Previously obtained value for P4 */
7871978944
){
7872078945
const char *zOpName;
7872178946
const char *zSynopsis;
7872278947
int nOpName;
7872378948
int ii;
7872478949
char zAlt[50];
7872578950
StrAccum x;
78726
- sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
7872778951
78952
+ sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
7872878953
zOpName = sqlite3OpcodeName(pOp->opcode);
7872978954
nOpName = sqlite3Strlen30(zOpName);
7873078955
if( zOpName[nOpName+1] ){
7873178956
int seenCom = 0;
7873278957
char c;
@@ -78789,14 +79014,16 @@
7878979014
sqlite3_str_appendf(&x, "; %s", pOp->zComment);
7879079015
}
7879179016
}else if( pOp->zComment ){
7879279017
sqlite3_str_appendall(&x, pOp->zComment);
7879379018
}
78794
- sqlite3StrAccumFinish(&x);
78795
- return x.nChar;
79019
+ if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
79020
+ sqlite3OomFault(db);
79021
+ }
79022
+ return sqlite3StrAccumFinish(&x);
7879679023
}
78797
-#endif /* SQLITE_DEBUG */
79024
+#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
7879879025
7879979026
#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
7880079027
/*
7880179028
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
7880279029
** that can be displayed in the P4 column of EXPLAIN output.
@@ -78873,15 +79100,15 @@
7887379100
#if VDBE_DISPLAY_P4
7887479101
/*
7887579102
** Compute a string that describes the P4 parameter for an opcode.
7887679103
** Use zTemp for any required temporary buffer space.
7887779104
*/
78878
-static char *displayP4(Op *pOp, char *zTemp, int nTemp){
78879
- char *zP4 = zTemp;
79105
+SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
79106
+ char *zP4 = 0;
7888079107
StrAccum x;
78881
- assert( nTemp>=20 );
78882
- sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
79108
+
79109
+ sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
7888379110
switch( pOp->p4type ){
7888479111
case P4_KEYINFO: {
7888579112
int j;
7888679113
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
7888779114
assert( pKeyInfo->aSortFlags!=0 );
@@ -78961,40 +79188,36 @@
7896179188
int i;
7896279189
int *ai = pOp->p4.ai;
7896379190
int n = ai[0]; /* The first element of an INTARRAY is always the
7896479191
** count of the number of elements to follow */
7896579192
for(i=1; i<=n; i++){
78966
- sqlite3_str_appendf(&x, ",%d", ai[i]);
79193
+ sqlite3_str_appendf(&x, "%c%d", (i==1 ? '[' : ','), ai[i]);
7896779194
}
78968
- zTemp[0] = '[';
7896979195
sqlite3_str_append(&x, "]", 1);
7897079196
break;
7897179197
}
7897279198
case P4_SUBPROGRAM: {
78973
- sqlite3_str_appendf(&x, "program");
79199
+ zP4 = "program";
7897479200
break;
7897579201
}
7897679202
case P4_DYNBLOB:
7897779203
case P4_ADVANCE: {
78978
- zTemp[0] = 0;
7897979204
break;
7898079205
}
7898179206
case P4_TABLE: {
78982
- sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
79207
+ zP4 = pOp->p4.pTab->zName;
7898379208
break;
7898479209
}
7898579210
default: {
7898679211
zP4 = pOp->p4.z;
78987
- if( zP4==0 ){
78988
- zP4 = zTemp;
78989
- zTemp[0] = 0;
78990
- }
7899179212
}
7899279213
}
78993
- sqlite3StrAccumFinish(&x);
78994
- assert( zP4!=0 );
78995
- return zP4;
79214
+ if( zP4 ) sqlite3_str_appendall(&x, zP4);
79215
+ if( (x.accError & SQLITE_NOMEM)!=0 ){
79216
+ sqlite3OomFault(db);
79217
+ }
79218
+ return sqlite3StrAccumFinish(&x);
7899679219
}
7899779220
#endif /* VDBE_DISPLAY_P4 */
7899879221
7899979222
/*
7900079223
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
@@ -79080,28 +79303,32 @@
7908079303
/*
7908179304
** Print a single opcode. This routine is used for debugging only.
7908279305
*/
7908379306
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
7908479307
char *zP4;
79085
- char zPtr[50];
79086
- char zCom[100];
79308
+ char *zCom;
79309
+ sqlite3 dummyDb;
7908779310
static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
7908879311
if( pOut==0 ) pOut = stdout;
79089
- zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
79312
+ dummyDb.mallocFailed = 1;
79313
+ zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp);
7909079314
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
79091
- displayComment(pOp, zP4, zCom, sizeof(zCom));
79315
+ zCom = sqlite3VdbeDisplayComment(0, pOp, zP4);
7909279316
#else
79093
- zCom[0] = 0;
79317
+ zCom = 0;
7909479318
#endif
7909579319
/* NB: The sqlite3OpcodeName() function is implemented by code created
7909679320
** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
7909779321
** information from the vdbe.c source text */
7909879322
fprintf(pOut, zFormat1, pc,
79099
- sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
79100
- zCom
79323
+ sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3,
79324
+ zP4 ? zP4 : "", pOp->p5,
79325
+ zCom ? zCom : ""
7910179326
);
7910279327
fflush(pOut);
79328
+ sqlite3_free(zP4);
79329
+ sqlite3_free(zCom);
7910379330
}
7910479331
#endif
7910579332
7910679333
/*
7910779334
** Initialize an array of N Mem element.
@@ -79188,10 +79415,125 @@
7918879415
assert( sqlite3VdbeFrameIsValid(pFrame) );
7918979416
pFrame->pParent = pFrame->v->pDelFrame;
7919079417
pFrame->v->pDelFrame = pFrame;
7919179418
}
7919279419
79420
+#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN)
79421
+/*
79422
+** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN
79423
+** QUERY PLAN output.
79424
+**
79425
+** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no
79426
+** more opcodes to be displayed.
79427
+*/
79428
+SQLITE_PRIVATE int sqlite3VdbeNextOpcode(
79429
+ Vdbe *p, /* The statement being explained */
79430
+ Mem *pSub, /* Storage for keeping track of subprogram nesting */
79431
+ int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */
79432
+ int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */
79433
+ int *piAddr, /* OUT: Write index into (*paOp)[] here */
79434
+ Op **paOp /* OUT: Write the opcode array here */
79435
+){
79436
+ int nRow; /* Stop when row count reaches this */
79437
+ int nSub = 0; /* Number of sub-vdbes seen so far */
79438
+ SubProgram **apSub = 0; /* Array of sub-vdbes */
79439
+ int i; /* Next instruction address */
79440
+ int rc = SQLITE_OK; /* Result code */
79441
+ Op *aOp = 0; /* Opcode array */
79442
+ int iPc; /* Rowid. Copy of value in *piPc */
79443
+
79444
+ /* When the number of output rows reaches nRow, that means the
79445
+ ** listing has finished and sqlite3_step() should return SQLITE_DONE.
79446
+ ** nRow is the sum of the number of rows in the main program, plus
79447
+ ** the sum of the number of rows in all trigger subprograms encountered
79448
+ ** so far. The nRow value will increase as new trigger subprograms are
79449
+ ** encountered, but p->pc will eventually catch up to nRow.
79450
+ */
79451
+ nRow = p->nOp;
79452
+ if( pSub!=0 ){
79453
+ if( pSub->flags&MEM_Blob ){
79454
+ /* pSub is initiallly NULL. It is initialized to a BLOB by
79455
+ ** the P4_SUBPROGRAM processing logic below */
79456
+ nSub = pSub->n/sizeof(Vdbe*);
79457
+ apSub = (SubProgram **)pSub->z;
79458
+ }
79459
+ for(i=0; i<nSub; i++){
79460
+ nRow += apSub[i]->nOp;
79461
+ }
79462
+ }
79463
+ iPc = *piPc;
79464
+ while(1){ /* Loop exits via break */
79465
+ i = iPc++;
79466
+ if( i>=nRow ){
79467
+ p->rc = SQLITE_OK;
79468
+ rc = SQLITE_DONE;
79469
+ break;
79470
+ }
79471
+ if( i<p->nOp ){
79472
+ /* The rowid is small enough that we are still in the
79473
+ ** main program. */
79474
+ aOp = p->aOp;
79475
+ }else{
79476
+ /* We are currently listing subprograms. Figure out which one and
79477
+ ** pick up the appropriate opcode. */
79478
+ int j;
79479
+ i -= p->nOp;
79480
+ assert( apSub!=0 );
79481
+ assert( nSub>0 );
79482
+ for(j=0; i>=apSub[j]->nOp; j++){
79483
+ i -= apSub[j]->nOp;
79484
+ assert( i<apSub[j]->nOp || j+1<nSub );
79485
+ }
79486
+ aOp = apSub[j]->aOp;
79487
+ }
79488
+
79489
+ /* When an OP_Program opcode is encounter (the only opcode that has
79490
+ ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
79491
+ ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
79492
+ ** has not already been seen.
79493
+ */
79494
+ if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){
79495
+ int nByte = (nSub+1)*sizeof(SubProgram*);
79496
+ int j;
79497
+ for(j=0; j<nSub; j++){
79498
+ if( apSub[j]==aOp[i].p4.pProgram ) break;
79499
+ }
79500
+ if( j==nSub ){
79501
+ p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
79502
+ if( p->rc!=SQLITE_OK ){
79503
+ rc = SQLITE_ERROR;
79504
+ break;
79505
+ }
79506
+ apSub = (SubProgram **)pSub->z;
79507
+ apSub[nSub++] = aOp[i].p4.pProgram;
79508
+ MemSetTypeFlag(pSub, MEM_Blob);
79509
+ pSub->n = nSub*sizeof(SubProgram*);
79510
+ nRow += aOp[i].p4.pProgram->nOp;
79511
+ }
79512
+ }
79513
+ if( eMode==0 ) break;
79514
+#ifdef SQLITE_ENABLE_BYTECODE_VTAB
79515
+ if( eMode==2 ){
79516
+ Op *pOp = aOp + i;
79517
+ if( pOp->opcode==OP_OpenRead ) break;
79518
+ if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break;
79519
+ if( pOp->opcode==OP_ReopenIdx ) break;
79520
+ }else
79521
+#endif
79522
+ {
79523
+ assert( eMode==1 );
79524
+ if( aOp[i].opcode==OP_Explain ) break;
79525
+ if( aOp[i].opcode==OP_Init && iPc>1 ) break;
79526
+ }
79527
+ }
79528
+ *piPc = iPc;
79529
+ *piAddr = i;
79530
+ *paOp = aOp;
79531
+ return rc;
79532
+}
79533
+#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */
79534
+
7919379535
7919479536
/*
7919579537
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
7919679538
** allocated by the OP_Program opcode in sqlite3VdbeExec().
7919779539
*/
@@ -79228,20 +79570,18 @@
7922879570
** the trigger subprograms are listed one by one.
7922979571
*/
7923079572
SQLITE_PRIVATE int sqlite3VdbeList(
7923179573
Vdbe *p /* The VDBE */
7923279574
){
79233
- int nRow; /* Stop when row count reaches this */
79234
- int nSub = 0; /* Number of sub-vdbes seen so far */
79235
- SubProgram **apSub = 0; /* Array of sub-vdbes */
7923679575
Mem *pSub = 0; /* Memory cell hold array of subprogs */
7923779576
sqlite3 *db = p->db; /* The database connection */
7923879577
int i; /* Loop counter */
7923979578
int rc = SQLITE_OK; /* Return code */
7924079579
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
7924179580
int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
79242
- Op *pOp = 0;
79581
+ Op *aOp; /* Array of opcodes */
79582
+ Op *pOp; /* Current opcode */
7924379583
7924479584
assert( p->explain );
7924579585
assert( p->magic==VDBE_MAGIC_RUN );
7924679586
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
7924779587
@@ -79257,166 +79597,66 @@
7925779597
** sqlite3_column_text16() failed. */
7925879598
sqlite3OomFault(db);
7925979599
return SQLITE_ERROR;
7926079600
}
7926179601
79262
- /* When the number of output rows reaches nRow, that means the
79263
- ** listing has finished and sqlite3_step() should return SQLITE_DONE.
79264
- ** nRow is the sum of the number of rows in the main program, plus
79265
- ** the sum of the number of rows in all trigger subprograms encountered
79266
- ** so far. The nRow value will increase as new trigger subprograms are
79267
- ** encountered, but p->pc will eventually catch up to nRow.
79268
- */
79269
- nRow = p->nOp;
7927079602
if( bListSubprogs ){
7927179603
/* The first 8 memory cells are used for the result set. So we will
7927279604
** commandeer the 9th cell to use as storage for an array of pointers
7927379605
** to trigger subprograms. The VDBE is guaranteed to have at least 9
7927479606
** cells. */
7927579607
assert( p->nMem>9 );
7927679608
pSub = &p->aMem[9];
79277
- if( pSub->flags&MEM_Blob ){
79278
- /* On the first call to sqlite3_step(), pSub will hold a NULL. It is
79279
- ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
79280
- nSub = pSub->n/sizeof(Vdbe*);
79281
- apSub = (SubProgram **)pSub->z;
79282
- }
79283
- for(i=0; i<nSub; i++){
79284
- nRow += apSub[i]->nOp;
79285
- }
79286
- }
79287
-
79288
- while(1){ /* Loop exits via break */
79289
- i = p->pc++;
79290
- if( i>=nRow ){
79291
- p->rc = SQLITE_OK;
79292
- rc = SQLITE_DONE;
79293
- break;
79294
- }
79295
- if( i<p->nOp ){
79296
- /* The output line number is small enough that we are still in the
79297
- ** main program. */
79298
- pOp = &p->aOp[i];
79299
- }else{
79300
- /* We are currently listing subprograms. Figure out which one and
79301
- ** pick up the appropriate opcode. */
79302
- int j;
79303
- i -= p->nOp;
79304
- assert( apSub!=0 );
79305
- assert( nSub>0 );
79306
- for(j=0; i>=apSub[j]->nOp; j++){
79307
- i -= apSub[j]->nOp;
79308
- assert( i<apSub[j]->nOp || j+1<nSub );
79309
- }
79310
- pOp = &apSub[j]->aOp[i];
79311
- }
79312
-
79313
- /* When an OP_Program opcode is encounter (the only opcode that has
79314
- ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
79315
- ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
79316
- ** has not already been seen.
79317
- */
79318
- if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
79319
- int nByte = (nSub+1)*sizeof(SubProgram*);
79320
- int j;
79321
- for(j=0; j<nSub; j++){
79322
- if( apSub[j]==pOp->p4.pProgram ) break;
79323
- }
79324
- if( j==nSub ){
79325
- p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
79326
- if( p->rc!=SQLITE_OK ){
79327
- rc = SQLITE_ERROR;
79328
- break;
79329
- }
79330
- apSub = (SubProgram **)pSub->z;
79331
- apSub[nSub++] = pOp->p4.pProgram;
79332
- pSub->flags |= MEM_Blob;
79333
- pSub->n = nSub*sizeof(SubProgram*);
79334
- nRow += pOp->p4.pProgram->nOp;
79335
- }
79336
- }
79337
- if( p->explain<2 ) break;
79338
- if( pOp->opcode==OP_Explain ) break;
79339
- if( pOp->opcode==OP_Init && p->pc>1 ) break;
79340
- }
79341
-
79342
- if( rc==SQLITE_OK ){
79609
+ }else{
79610
+ pSub = 0;
79611
+ }
79612
+
79613
+ /* Figure out which opcode is next to display */
79614
+ rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);
79615
+
79616
+ if( rc==SQLITE_OK ){
79617
+ pOp = aOp + i;
7934379618
if( AtomicLoad(&db->u1.isInterrupted) ){
7934479619
p->rc = SQLITE_INTERRUPT;
7934579620
rc = SQLITE_ERROR;
7934679621
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
7934779622
}else{
79348
- char *zP4;
79349
- if( p->explain==1 ){
79350
- pMem->flags = MEM_Int;
79351
- pMem->u.i = i; /* Program counter */
79352
- pMem++;
79353
-
79354
- pMem->flags = MEM_Static|MEM_Str|MEM_Term;
79355
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
79356
- assert( pMem->z!=0 );
79357
- pMem->n = sqlite3Strlen30(pMem->z);
79358
- pMem->enc = SQLITE_UTF8;
79359
- pMem++;
79360
- }
79361
-
79362
- pMem->flags = MEM_Int;
79363
- pMem->u.i = pOp->p1; /* P1 */
79364
- pMem++;
79365
-
79366
- pMem->flags = MEM_Int;
79367
- pMem->u.i = pOp->p2; /* P2 */
79368
- pMem++;
79369
-
79370
- pMem->flags = MEM_Int;
79371
- pMem->u.i = pOp->p3; /* P3 */
79372
- pMem++;
79373
-
79374
- if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
79375
- assert( p->db->mallocFailed );
79376
- return SQLITE_ERROR;
79377
- }
79378
- pMem->flags = MEM_Str|MEM_Term;
79379
- zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
79380
- if( zP4!=pMem->z ){
79381
- pMem->n = 0;
79382
- sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
79623
+ char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
79624
+ if( p->explain==2 ){
79625
+ sqlite3VdbeMemSetInt64(pMem, pOp->p1);
79626
+ sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
79627
+ sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
79628
+ sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
79629
+ p->nResColumn = 4;
7938379630
}else{
79384
- assert( pMem->z!=0 );
79385
- pMem->n = sqlite3Strlen30(pMem->z);
79386
- pMem->enc = SQLITE_UTF8;
79387
- }
79388
- pMem++;
79389
-
79390
- if( p->explain==1 ){
79391
- if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
79392
- assert( p->db->mallocFailed );
79393
- return SQLITE_ERROR;
79394
- }
79395
- pMem->flags = MEM_Str|MEM_Term;
79396
- pMem->n = 2;
79397
- sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
79398
- pMem->enc = SQLITE_UTF8;
79399
- pMem++;
79400
-
79631
+ sqlite3VdbeMemSetInt64(pMem+0, i);
79632
+ sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
79633
+ -1, SQLITE_UTF8, SQLITE_STATIC);
79634
+ sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
79635
+ sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
79636
+ sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
79637
+ /* pMem+5 for p4 is done last */
79638
+ sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
7940179639
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
79402
- if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
79403
- assert( p->db->mallocFailed );
79404
- return SQLITE_ERROR;
79405
- }
79406
- pMem->flags = MEM_Str|MEM_Term;
79407
- pMem->n = displayComment(pOp, zP4, pMem->z, 500);
79408
- pMem->enc = SQLITE_UTF8;
79409
-#else
79410
- pMem->flags = MEM_Null; /* Comment */
79411
-#endif
79412
- }
79413
-
79414
- p->nResColumn = 8 - 4*(p->explain-1);
79415
- p->pResultSet = &p->aMem[1];
79416
- p->rc = SQLITE_OK;
79417
- rc = SQLITE_ROW;
79640
+ {
79641
+ char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
79642
+ sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
79643
+ }
79644
+#else
79645
+ sqlite3VdbeMemSetNull(pMem+7);
79646
+#endif
79647
+ sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
79648
+ p->nResColumn = 8;
79649
+ }
79650
+ p->pResultSet = pMem;
79651
+ if( db->mallocFailed ){
79652
+ p->rc = SQLITE_NOMEM;
79653
+ rc = SQLITE_ERROR;
79654
+ }else{
79655
+ p->rc = SQLITE_OK;
79656
+ rc = SQLITE_ROW;
79657
+ }
7941879658
}
7941979659
}
7942079660
return rc;
7942179661
}
7942279662
#endif /* SQLITE_OMIT_EXPLAIN */
@@ -79982,12 +80222,13 @@
7998280222
int retryCount = 0;
7998380223
int nMainFile;
7998480224
7998580225
/* Select a master journal file name */
7998680226
nMainFile = sqlite3Strlen30(zMainFile);
79987
- zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz%c%c", zMainFile, 0, 0);
80227
+ zMaster = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0);
7998880228
if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
80229
+ zMaster += 4;
7998980230
do {
7999080231
u32 iRandom;
7999180232
if( retryCount ){
7999280233
if( retryCount>100 ){
7999380234
sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
@@ -80013,11 +80254,11 @@
8001380254
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
8001480255
SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
8001580256
);
8001680257
}
8001780258
if( rc!=SQLITE_OK ){
80018
- sqlite3DbFree(db, zMaster);
80259
+ sqlite3DbFree(db, zMaster-4);
8001980260
return rc;
8002080261
}
8002180262
8002280263
/* Write the name of each database file in the transaction into the new
8002380264
** master journal file. If an error occurs at this point close
@@ -80036,11 +80277,11 @@
8003680277
rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
8003780278
offset += sqlite3Strlen30(zFile)+1;
8003880279
if( rc!=SQLITE_OK ){
8003980280
sqlite3OsCloseFree(pMaster);
8004080281
sqlite3OsDelete(pVfs, zMaster, 0);
80041
- sqlite3DbFree(db, zMaster);
80282
+ sqlite3DbFree(db, zMaster-4);
8004280283
return rc;
8004380284
}
8004480285
}
8004580286
}
8004680287
@@ -80050,11 +80291,11 @@
8005080291
if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
8005180292
&& SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
8005280293
){
8005380294
sqlite3OsCloseFree(pMaster);
8005480295
sqlite3OsDelete(pVfs, zMaster, 0);
80055
- sqlite3DbFree(db, zMaster);
80296
+ sqlite3DbFree(db, zMaster-4);
8005680297
return rc;
8005780298
}
8005880299
8005980300
/* Sync all the db files involved in the transaction. The same call
8006080301
** sets the master journal pointer in each individual journal. If
@@ -80073,20 +80314,20 @@
8007380314
}
8007480315
}
8007580316
sqlite3OsCloseFree(pMaster);
8007680317
assert( rc!=SQLITE_BUSY );
8007780318
if( rc!=SQLITE_OK ){
80078
- sqlite3DbFree(db, zMaster);
80319
+ sqlite3DbFree(db, zMaster-4);
8007980320
return rc;
8008080321
}
8008180322
8008280323
/* Delete the master journal file. This commits the transaction. After
8008380324
** doing this the directory is synced again before any individual
8008480325
** transaction files are deleted.
8008580326
*/
8008680327
rc = sqlite3OsDelete(pVfs, zMaster, 1);
80087
- sqlite3DbFree(db, zMaster);
80328
+ sqlite3DbFree(db, zMaster-4);
8008880329
zMaster = 0;
8008980330
if( rc ){
8009080331
return rc;
8009180332
}
8009280333
@@ -87998,32 +88239,38 @@
8799888239
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
8799988240
REGISTER_TRACE(pOp->p3, pOut);
8800088241
break;
8800188242
}
8800288243
88003
-/* Opcode: Count P1 P2 * * *
88244
+/* Opcode: Count P1 P2 p3 * *
8800488245
** Synopsis: r[P2]=count()
8800588246
**
8800688247
** Store the number of entries (an integer value) in the table or index
88007
-** opened by cursor P1 in register P2
88248
+** opened by cursor P1 in register P2.
88249
+**
88250
+** If P3==0, then an exact count is obtained, which involves visiting
88251
+** every btree page of the table. But if P3 is non-zero, an estimate
88252
+** is returned based on the current cursor position.
8800888253
*/
88009
-#ifndef SQLITE_OMIT_BTREECOUNT
8801088254
case OP_Count: { /* out2 */
8801188255
i64 nEntry;
8801288256
BtCursor *pCrsr;
8801388257
8801488258
assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
8801588259
pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
8801688260
assert( pCrsr );
88017
- nEntry = 0; /* Not needed. Only used to silence a warning. */
88018
- rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
88019
- if( rc ) goto abort_due_to_error;
88261
+ if( pOp->p3 ){
88262
+ nEntry = sqlite3BtreeRowCountEst(pCrsr);
88263
+ }else{
88264
+ nEntry = 0; /* Not needed. Only used to silence a warning. */
88265
+ rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
88266
+ if( rc ) goto abort_due_to_error;
88267
+ }
8802088268
pOut = out2Prerelease(p, pOp);
8802188269
pOut->u.i = nEntry;
8802288270
goto check_for_interrupt;
8802388271
}
88024
-#endif
8802588272
8802688273
/* Opcode: Savepoint P1 * * P4 *
8802788274
**
8802888275
** Open, release or rollback the savepoint named by parameter P4, depending
8802988276
** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
@@ -90457,16 +90704,23 @@
9045790704
rc = sqlite3VdbeSorterWrite(pC, pIn2);
9045890705
if( rc) goto abort_due_to_error;
9045990706
break;
9046090707
}
9046190708
90462
-/* Opcode: IdxDelete P1 P2 P3 * *
90709
+/* Opcode: IdxDelete P1 P2 P3 * P5
9046390710
** Synopsis: key=r[P2@P3]
9046490711
**
9046590712
** The content of P3 registers starting at register P2 form
9046690713
** an unpacked index key. This opcode removes that entry from the
9046790714
** index opened by cursor P1.
90715
+**
90716
+** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
90717
+** if no matching index entry is found. This happens when running
90718
+** an UPDATE or DELETE statement and the index entry to be updated
90719
+** or deleted is not found. For some uses of IdxDelete
90720
+** (example: the EXCEPT operator) it does not matter that no matching
90721
+** entry is found. For those cases, P5 is zero.
9046890722
*/
9046990723
case OP_IdxDelete: {
9047090724
VdbeCursor *pC;
9047190725
BtCursor *pCrsr;
9047290726
int res;
@@ -90479,20 +90733,22 @@
9047990733
assert( pC!=0 );
9048090734
assert( pC->eCurType==CURTYPE_BTREE );
9048190735
sqlite3VdbeIncrWriteCounter(p, pC);
9048290736
pCrsr = pC->uc.pCursor;
9048390737
assert( pCrsr!=0 );
90484
- assert( pOp->p5==0 );
9048590738
r.pKeyInfo = pC->pKeyInfo;
9048690739
r.nField = (u16)pOp->p3;
9048790740
r.default_rc = 0;
9048890741
r.aMem = &aMem[pOp->p2];
9048990742
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
9049090743
if( rc ) goto abort_due_to_error;
9049190744
if( res==0 ){
9049290745
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
9049390746
if( rc ) goto abort_due_to_error;
90747
+ }else if( pOp->p5 ){
90748
+ rc = SQLITE_CORRUPT_INDEX;
90749
+ goto abort_due_to_error;
9049490750
}
9049590751
assert( pC->deferredMoveto==0 );
9049690752
pC->cacheStatus = CACHE_STALE;
9049790753
pC->seekResult = 0;
9049890754
break;
@@ -96093,10 +96349,435 @@
9609396349
*pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
9609496350
return SQLITE_OK;
9609596351
}
9609696352
9609796353
/************** End of vdbesort.c ********************************************/
96354
+/************** Begin file vdbevtab.c ****************************************/
96355
+/*
96356
+** 2020-03-23
96357
+**
96358
+** The author disclaims copyright to this source code. In place of
96359
+** a legal notice, here is a blessing:
96360
+**
96361
+** May you do good and not evil.
96362
+** May you find forgiveness for yourself and forgive others.
96363
+** May you share freely, never taking more than you give.
96364
+**
96365
+*************************************************************************
96366
+**
96367
+** This file implements virtual-tables for examining the bytecode content
96368
+** of a prepared statement.
96369
+*/
96370
+#ifdef SQLITE_ENABLE_BYTECODE_VTAB
96371
+/* #include "sqliteInt.h" */
96372
+/* #include "vdbeInt.h" */
96373
+
96374
+/* An instance of the bytecode() table-valued function.
96375
+*/
96376
+typedef struct bytecodevtab bytecodevtab;
96377
+struct bytecodevtab {
96378
+ sqlite3_vtab base; /* Base class - must be first */
96379
+ sqlite3 *db; /* Database connection */
96380
+ int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */
96381
+};
96382
+
96383
+/* A cursor for scanning through the bytecode
96384
+*/
96385
+typedef struct bytecodevtab_cursor bytecodevtab_cursor;
96386
+struct bytecodevtab_cursor {
96387
+ sqlite3_vtab_cursor base; /* Base class - must be first */
96388
+ sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */
96389
+ int iRowid; /* The rowid of the output table */
96390
+ int iAddr; /* Address */
96391
+ int needFinalize; /* Cursors owns pStmt and must finalize it */
96392
+ int showSubprograms; /* Provide a listing of subprograms */
96393
+ Op *aOp; /* Operand array */
96394
+ char *zP4; /* Rendered P4 value */
96395
+ const char *zType; /* tables_used.type */
96396
+ const char *zSchema; /* tables_used.schema */
96397
+ const char *zName; /* tables_used.name */
96398
+ Mem sub; /* Subprograms */
96399
+};
96400
+
96401
+/*
96402
+** Create a new bytecode() table-valued function.
96403
+*/
96404
+static int bytecodevtabConnect(
96405
+ sqlite3 *db,
96406
+ void *pAux,
96407
+ int argc, const char *const*argv,
96408
+ sqlite3_vtab **ppVtab,
96409
+ char **pzErr
96410
+){
96411
+ bytecodevtab *pNew;
96412
+ int rc;
96413
+ int isTabUsed = pAux!=0;
96414
+ const char *azSchema[2] = {
96415
+ /* bytecode() schema */
96416
+ "CREATE TABLE x("
96417
+ "addr INT,"
96418
+ "opcode TEXT,"
96419
+ "p1 INT,"
96420
+ "p2 INT,"
96421
+ "p3 INT,"
96422
+ "p4 TEXT,"
96423
+ "p5 INT,"
96424
+ "comment TEXT,"
96425
+ "subprog TEXT,"
96426
+ "stmt HIDDEN"
96427
+ ");",
96428
+
96429
+ /* Tables_used() schema */
96430
+ "CREATE TABLE x("
96431
+ "type TEXT,"
96432
+ "schema TEXT,"
96433
+ "name TEXT,"
96434
+ "wr INT,"
96435
+ "subprog TEXT,"
96436
+ "stmt HIDDEN"
96437
+ ");"
96438
+ };
96439
+
96440
+ rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
96441
+ if( rc==SQLITE_OK ){
96442
+ pNew = sqlite3_malloc( sizeof(*pNew) );
96443
+ *ppVtab = (sqlite3_vtab*)pNew;
96444
+ if( pNew==0 ) return SQLITE_NOMEM;
96445
+ memset(pNew, 0, sizeof(*pNew));
96446
+ pNew->db = db;
96447
+ pNew->bTablesUsed = isTabUsed*2;
96448
+ }
96449
+ return rc;
96450
+}
96451
+
96452
+/*
96453
+** This method is the destructor for bytecodevtab objects.
96454
+*/
96455
+static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
96456
+ bytecodevtab *p = (bytecodevtab*)pVtab;
96457
+ sqlite3_free(p);
96458
+ return SQLITE_OK;
96459
+}
96460
+
96461
+/*
96462
+** Constructor for a new bytecodevtab_cursor object.
96463
+*/
96464
+static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
96465
+ bytecodevtab *pVTab = (bytecodevtab*)p;
96466
+ bytecodevtab_cursor *pCur;
96467
+ pCur = sqlite3_malloc( sizeof(*pCur) );
96468
+ if( pCur==0 ) return SQLITE_NOMEM;
96469
+ memset(pCur, 0, sizeof(*pCur));
96470
+ sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
96471
+ *ppCursor = &pCur->base;
96472
+ return SQLITE_OK;
96473
+}
96474
+
96475
+/*
96476
+** Clear all internal content from a bytecodevtab cursor.
96477
+*/
96478
+static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
96479
+ sqlite3_free(pCur->zP4);
96480
+ pCur->zP4 = 0;
96481
+ sqlite3VdbeMemRelease(&pCur->sub);
96482
+ sqlite3VdbeMemSetNull(&pCur->sub);
96483
+ if( pCur->needFinalize ){
96484
+ sqlite3_finalize(pCur->pStmt);
96485
+ }
96486
+ pCur->pStmt = 0;
96487
+ pCur->needFinalize = 0;
96488
+ pCur->zType = 0;
96489
+ pCur->zSchema = 0;
96490
+ pCur->zName = 0;
96491
+}
96492
+
96493
+/*
96494
+** Destructor for a bytecodevtab_cursor.
96495
+*/
96496
+static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
96497
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96498
+ bytecodevtabCursorClear(pCur);
96499
+ sqlite3_free(pCur);
96500
+ return SQLITE_OK;
96501
+}
96502
+
96503
+
96504
+/*
96505
+** Advance a bytecodevtab_cursor to its next row of output.
96506
+*/
96507
+static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
96508
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96509
+ bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
96510
+ int rc;
96511
+ if( pCur->zP4 ){
96512
+ sqlite3_free(pCur->zP4);
96513
+ pCur->zP4 = 0;
96514
+ }
96515
+ if( pCur->zName ){
96516
+ pCur->zName = 0;
96517
+ pCur->zType = 0;
96518
+ pCur->zSchema = 0;
96519
+ }
96520
+ rc = sqlite3VdbeNextOpcode(
96521
+ (Vdbe*)pCur->pStmt,
96522
+ pCur->showSubprograms ? &pCur->sub : 0,
96523
+ pTab->bTablesUsed,
96524
+ &pCur->iRowid,
96525
+ &pCur->iAddr,
96526
+ &pCur->aOp);
96527
+ if( rc!=SQLITE_OK ){
96528
+ sqlite3VdbeMemSetNull(&pCur->sub);
96529
+ pCur->aOp = 0;
96530
+ }
96531
+ return SQLITE_OK;
96532
+}
96533
+
96534
+/*
96535
+** Return TRUE if the cursor has been moved off of the last
96536
+** row of output.
96537
+*/
96538
+static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
96539
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96540
+ return pCur->aOp==0;
96541
+}
96542
+
96543
+/*
96544
+** Return values of columns for the row at which the bytecodevtab_cursor
96545
+** is currently pointing.
96546
+*/
96547
+static int bytecodevtabColumn(
96548
+ sqlite3_vtab_cursor *cur, /* The cursor */
96549
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
96550
+ int i /* Which column to return */
96551
+){
96552
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96553
+ bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
96554
+ Op *pOp = pCur->aOp + pCur->iAddr;
96555
+ if( pVTab->bTablesUsed ){
96556
+ if( i==4 ){
96557
+ i = 8;
96558
+ }else{
96559
+ if( i<=2 && pCur->zType==0 ){
96560
+ Schema *pSchema;
96561
+ HashElem *k;
96562
+ int iDb = pOp->p3;
96563
+ int iRoot = pOp->p2;
96564
+ sqlite3 *db = pVTab->db;
96565
+ pSchema = db->aDb[iDb].pSchema;
96566
+ pCur->zSchema = db->aDb[iDb].zDbSName;
96567
+ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
96568
+ Table *pTab = (Table*)sqliteHashData(k);
96569
+ if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
96570
+ pCur->zName = pTab->zName;
96571
+ pCur->zType = "table";
96572
+ break;
96573
+ }
96574
+ }
96575
+ if( pCur->zName==0 ){
96576
+ for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
96577
+ Index *pIdx = (Index*)sqliteHashData(k);
96578
+ if( pIdx->tnum==iRoot ){
96579
+ pCur->zName = pIdx->zName;
96580
+ pCur->zType = "index";
96581
+ }
96582
+ }
96583
+ }
96584
+ }
96585
+ i += 10;
96586
+ }
96587
+ }
96588
+ switch( i ){
96589
+ case 0: /* addr */
96590
+ sqlite3_result_int(ctx, pCur->iAddr);
96591
+ break;
96592
+ case 1: /* opcode */
96593
+ sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
96594
+ -1, SQLITE_STATIC);
96595
+ break;
96596
+ case 2: /* p1 */
96597
+ sqlite3_result_int(ctx, pOp->p1);
96598
+ break;
96599
+ case 3: /* p2 */
96600
+ sqlite3_result_int(ctx, pOp->p2);
96601
+ break;
96602
+ case 4: /* p3 */
96603
+ sqlite3_result_int(ctx, pOp->p3);
96604
+ break;
96605
+ case 5: /* p4 */
96606
+ case 7: /* comment */
96607
+ if( pCur->zP4==0 ){
96608
+ pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
96609
+ }
96610
+ if( i==5 ){
96611
+ sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
96612
+ }else{
96613
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
96614
+ char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
96615
+ sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
96616
+#endif
96617
+ }
96618
+ break;
96619
+ case 6: /* p5 */
96620
+ sqlite3_result_int(ctx, pOp->p5);
96621
+ break;
96622
+ case 8: { /* subprog */
96623
+ Op *aOp = pCur->aOp;
96624
+ assert( aOp[0].opcode==OP_Init );
96625
+ assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
96626
+ if( pCur->iRowid==pCur->iAddr+1 ){
96627
+ break; /* Result is NULL for the main program */
96628
+ }else if( aOp[0].p4.z!=0 ){
96629
+ sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
96630
+ }else{
96631
+ sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
96632
+ }
96633
+ break;
96634
+ }
96635
+ case 10: /* tables_used.type */
96636
+ sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
96637
+ break;
96638
+ case 11: /* tables_used.schema */
96639
+ sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
96640
+ break;
96641
+ case 12: /* tables_used.name */
96642
+ sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
96643
+ break;
96644
+ case 13: /* tables_used.wr */
96645
+ sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
96646
+ break;
96647
+ }
96648
+ return SQLITE_OK;
96649
+}
96650
+
96651
+/*
96652
+** Return the rowid for the current row. In this implementation, the
96653
+** rowid is the same as the output value.
96654
+*/
96655
+static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
96656
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96657
+ *pRowid = pCur->iRowid;
96658
+ return SQLITE_OK;
96659
+}
96660
+
96661
+/*
96662
+** Initialize a cursor.
96663
+**
96664
+** idxNum==0 means show all subprograms
96665
+** idxNum==1 means show only the main bytecode and omit subprograms.
96666
+*/
96667
+static int bytecodevtabFilter(
96668
+ sqlite3_vtab_cursor *pVtabCursor,
96669
+ int idxNum, const char *idxStr,
96670
+ int argc, sqlite3_value **argv
96671
+){
96672
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
96673
+ bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
96674
+ int rc = SQLITE_OK;
96675
+
96676
+ bytecodevtabCursorClear(pCur);
96677
+ pCur->iRowid = 0;
96678
+ pCur->iAddr = 0;
96679
+ pCur->showSubprograms = idxNum==0;
96680
+ assert( argc==1 );
96681
+ if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
96682
+ const char *zSql = (const char*)sqlite3_value_text(argv[0]);
96683
+ if( zSql==0 ){
96684
+ rc = SQLITE_NOMEM;
96685
+ }else{
96686
+ rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
96687
+ pCur->needFinalize = 1;
96688
+ }
96689
+ }else{
96690
+ pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
96691
+ }
96692
+ if( pCur->pStmt==0 ){
96693
+ pVTab->base.zErrMsg = sqlite3_mprintf(
96694
+ "argument to %s() is not a valid SQL statement",
96695
+ pVTab->bTablesUsed ? "tables_used" : "bytecode"
96696
+ );
96697
+ rc = SQLITE_ERROR;
96698
+ }else{
96699
+ bytecodevtabNext(pVtabCursor);
96700
+ }
96701
+ return rc;
96702
+}
96703
+
96704
+/*
96705
+** We must have a single stmt=? constraint that will be passed through
96706
+** into the xFilter method. If there is no valid stmt=? constraint,
96707
+** then return an SQLITE_CONSTRAINT error.
96708
+*/
96709
+static int bytecodevtabBestIndex(
96710
+ sqlite3_vtab *tab,
96711
+ sqlite3_index_info *pIdxInfo
96712
+){
96713
+ int i;
96714
+ int rc = SQLITE_CONSTRAINT;
96715
+ struct sqlite3_index_constraint *p;
96716
+ bytecodevtab *pVTab = (bytecodevtab*)tab;
96717
+ int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
96718
+ pIdxInfo->estimatedCost = (double)100;
96719
+ pIdxInfo->estimatedRows = 100;
96720
+ pIdxInfo->idxNum = 0;
96721
+ for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
96722
+ if( p->usable==0 ) continue;
96723
+ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
96724
+ rc = SQLITE_OK;
96725
+ pIdxInfo->aConstraintUsage[i].omit = 1;
96726
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
96727
+ }
96728
+ if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
96729
+ pIdxInfo->aConstraintUsage[i].omit = 1;
96730
+ pIdxInfo->idxNum = 1;
96731
+ }
96732
+ }
96733
+ return rc;
96734
+}
96735
+
96736
+/*
96737
+** This following structure defines all the methods for the
96738
+** virtual table.
96739
+*/
96740
+static sqlite3_module bytecodevtabModule = {
96741
+ /* iVersion */ 0,
96742
+ /* xCreate */ 0,
96743
+ /* xConnect */ bytecodevtabConnect,
96744
+ /* xBestIndex */ bytecodevtabBestIndex,
96745
+ /* xDisconnect */ bytecodevtabDisconnect,
96746
+ /* xDestroy */ 0,
96747
+ /* xOpen */ bytecodevtabOpen,
96748
+ /* xClose */ bytecodevtabClose,
96749
+ /* xFilter */ bytecodevtabFilter,
96750
+ /* xNext */ bytecodevtabNext,
96751
+ /* xEof */ bytecodevtabEof,
96752
+ /* xColumn */ bytecodevtabColumn,
96753
+ /* xRowid */ bytecodevtabRowid,
96754
+ /* xUpdate */ 0,
96755
+ /* xBegin */ 0,
96756
+ /* xSync */ 0,
96757
+ /* xCommit */ 0,
96758
+ /* xRollback */ 0,
96759
+ /* xFindMethod */ 0,
96760
+ /* xRename */ 0,
96761
+ /* xSavepoint */ 0,
96762
+ /* xRelease */ 0,
96763
+ /* xRollbackTo */ 0,
96764
+ /* xShadowName */ 0
96765
+};
96766
+
96767
+
96768
+SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
96769
+ int rc;
96770
+ rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
96771
+ if( rc==SQLITE_OK ){
96772
+ rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
96773
+ }
96774
+ return rc;
96775
+}
96776
+#endif /* SQLITE_ENABLE_BYTECODE_VTAB */
96777
+
96778
+/************** End of vdbevtab.c ********************************************/
9609896779
/************** Begin file memjournal.c **************************************/
9609996780
/*
9610096781
** 2008 October 7
9610196782
**
9610296783
** The author disclaims copyright to this source code. In place of
@@ -98739,11 +99420,11 @@
9873999420
** SELECT * FROM t1 WHERE (select a from t1);
9874099421
*/
9874199422
SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
9874299423
int op;
9874399424
while( ExprHasProperty(pExpr, EP_Skip) ){
98744
- assert( pExpr->op==TK_COLLATE );
99425
+ assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
9874599426
pExpr = pExpr->pLeft;
9874699427
assert( pExpr!=0 );
9874799428
}
9874899429
op = pExpr->op;
9874999430
if( op==TK_SELECT ){
@@ -98806,11 +99487,11 @@
9880699487
/*
9880799488
** Skip over any TK_COLLATE operators.
9880899489
*/
9880999490
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
9881099491
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
98811
- assert( pExpr->op==TK_COLLATE );
99492
+ assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
9881299493
pExpr = pExpr->pLeft;
9881399494
}
9881499495
return pExpr;
9881599496
}
9881699497
@@ -98825,11 +99506,11 @@
9882599506
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
9882699507
assert( pExpr->x.pList->nExpr>0 );
9882799508
assert( pExpr->op==TK_FUNCTION );
9882899509
pExpr = pExpr->x.pList->a[0].pExpr;
9882999510
}else{
98830
- assert( pExpr->op==TK_COLLATE );
99511
+ assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
9883199512
pExpr = pExpr->pLeft;
9883299513
}
9883399514
}
9883499515
return pExpr;
9883599516
}
@@ -103176,11 +103857,11 @@
103176103857
assert( pExpr->affExpr==OE_Rollback
103177103858
|| pExpr->affExpr==OE_Abort
103178103859
|| pExpr->affExpr==OE_Fail
103179103860
|| pExpr->affExpr==OE_Ignore
103180103861
);
103181
- if( !pParse->pTriggerTab ){
103862
+ if( !pParse->pTriggerTab && !pParse->nested ){
103182103863
sqlite3ErrorMsg(pParse,
103183103864
"RAISE() may only be used within a trigger-program");
103184103865
return 0;
103185103866
}
103186103867
if( pExpr->affExpr==OE_Abort ){
@@ -103190,12 +103871,13 @@
103190103871
if( pExpr->affExpr==OE_Ignore ){
103191103872
sqlite3VdbeAddOp4(
103192103873
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
103193103874
VdbeCoverage(v);
103194103875
}else{
103195
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
103196
- pExpr->affExpr, pExpr->u.zToken, 0, 0);
103876
+ sqlite3HaltConstraint(pParse,
103877
+ pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
103878
+ pExpr->affExpr, pExpr->u.zToken, 0, 0);
103197103879
}
103198103880
103199103881
break;
103200103882
}
103201103883
#endif
@@ -104946,10 +105628,26 @@
104946105628
exit_rename_table:
104947105629
sqlite3SrcListDelete(db, pSrc);
104948105630
sqlite3DbFree(db, zName);
104949105631
db->mDbFlags = savedDbFlags;
104950105632
}
105633
+
105634
+/*
105635
+** Write code that will raise an error if the table described by
105636
+** zDb and zTab is not empty.
105637
+*/
105638
+static void sqlite3ErrorIfNotEmpty(
105639
+ Parse *pParse, /* Parsing context */
105640
+ const char *zDb, /* Schema holding the table */
105641
+ const char *zTab, /* Table to check for empty */
105642
+ const char *zErr /* Error message text */
105643
+){
105644
+ sqlite3NestedParse(pParse,
105645
+ "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
105646
+ zErr, zDb, zTab
105647
+ );
105648
+}
104951105649
104952105650
/*
104953105651
** This function is called after an "ALTER TABLE ... ADD" statement
104954105652
** has been parsed. Argument pColDef contains the text of the new
104955105653
** column definition.
@@ -104999,11 +105697,12 @@
104999105697
if( pCol->colFlags & COLFLAG_PRIMKEY ){
105000105698
sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
105001105699
return;
105002105700
}
105003105701
if( pNew->pIndex ){
105004
- sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
105702
+ sqlite3ErrorMsg(pParse,
105703
+ "Cannot add a UNIQUE column");
105005105704
return;
105006105705
}
105007105706
if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
105008105707
/* If the default value for the new column was specified with a
105009105708
** literal NULL, then set pDflt to 0. This simplifies checking
@@ -105012,19 +105711,18 @@
105012105711
assert( pDflt==0 || pDflt->op==TK_SPAN );
105013105712
if( pDflt && pDflt->pLeft->op==TK_NULL ){
105014105713
pDflt = 0;
105015105714
}
105016105715
if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
105017
- sqlite3ErrorMsg(pParse,
105716
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
105018105717
"Cannot add a REFERENCES column with non-NULL default value");
105019
- return;
105020105718
}
105021105719
if( pCol->notNull && !pDflt ){
105022
- sqlite3ErrorMsg(pParse,
105720
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
105023105721
"Cannot add a NOT NULL column with default value NULL");
105024
- return;
105025105722
}
105723
+
105026105724
105027105725
/* Ensure the default expression is something that sqlite3ValueFromExpr()
105028105726
** can handle (i.e. not CURRENT_TIME etc.)
105029105727
*/
105030105728
if( pDflt ){
@@ -105035,18 +105733,17 @@
105035105733
if( rc!=SQLITE_OK ){
105036105734
assert( db->mallocFailed == 1 );
105037105735
return;
105038105736
}
105039105737
if( !pVal ){
105040
- sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default");
105041
- return;
105738
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
105739
+ "Cannot add a column with non-constant default");
105042105740
}
105043105741
sqlite3ValueFree(pVal);
105044105742
}
105045105743
}else if( pCol->colFlags & COLFLAG_STORED ){
105046
- sqlite3ErrorMsg(pParse, "cannot add a STORED column");
105047
- return;
105744
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
105048105745
}
105049105746
105050105747
105051105748
/* Modify the CREATE TABLE statement. */
105052105749
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
@@ -106605,10 +107302,15 @@
106605107302
sqlite3 *db = pParse->db;
106606107303
Db *pDb;
106607107304
Vdbe *v = sqlite3GetVdbe(pParse);
106608107305
int aRoot[ArraySize(aTable)];
106609107306
u8 aCreateTbl[ArraySize(aTable)];
107307
+#ifdef SQLITE_ENABLE_STAT4
107308
+ const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
107309
+#else
107310
+ const int nToOpen = 1;
107311
+#endif
106610107312
106611107313
if( v==0 ) return;
106612107314
assert( sqlite3BtreeHoldsAllMutexes(db) );
106613107315
assert( sqlite3VdbeDb(v)==db );
106614107316
pDb = &db->aDb[iDb];
@@ -106617,12 +107319,13 @@
106617107319
** if they do already exist.
106618107320
*/
106619107321
for(i=0; i<ArraySize(aTable); i++){
106620107322
const char *zTab = aTable[i].zName;
106621107323
Table *pStat;
107324
+ aCreateTbl[i] = 0;
106622107325
if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
106623
- if( aTable[i].zCols ){
107326
+ if( i<nToOpen ){
106624107327
/* The sqlite_statN table does not exist. Create it. Note that a
106625107328
** side-effect of the CREATE TABLE statement is to leave the rootpage
106626107329
** of the new table in register pParse->regRoot. This is important
106627107330
** because the OpenWrite opcode below will be needing it. */
106628107331
sqlite3NestedParse(pParse,
@@ -106634,11 +107337,10 @@
106634107337
}else{
106635107338
/* The table already exists. If zWhere is not NULL, delete all entries
106636107339
** associated with the table zWhere. If zWhere is NULL, delete the
106637107340
** entire contents of the table. */
106638107341
aRoot[i] = pStat->tnum;
106639
- aCreateTbl[i] = 0;
106640107342
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
106641107343
if( zWhere ){
106642107344
sqlite3NestedParse(pParse,
106643107345
"DELETE FROM %Q.%s WHERE %s=%Q",
106644107346
pDb->zDbSName, zTab, zWhereType, zWhere
@@ -106653,11 +107355,11 @@
106653107355
}
106654107356
}
106655107357
}
106656107358
106657107359
/* Open the sqlite_stat[134] tables for writing. */
106658
- for(i=0; aTable[i].zCols; i++){
107360
+ for(i=0; i<nToOpen; i++){
106659107361
assert( i<ArraySize(aTable) );
106660107362
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
106661107363
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
106662107364
VdbeComment((v, aTable[i].zName));
106663107365
}
@@ -106692,13 +107394,16 @@
106692107394
u32 iHash; /* Tiebreaker hash */
106693107395
#endif
106694107396
};
106695107397
struct StatAccum {
106696107398
sqlite3 *db; /* Database connection, for malloc() */
106697
- tRowcnt nRow; /* Number of rows in the entire table */
107399
+ tRowcnt nEst; /* Estimated number of rows */
107400
+ tRowcnt nRow; /* Number of rows visited so far */
107401
+ int nLimit; /* Analysis row-scan limit */
106698107402
int nCol; /* Number of columns in index + pk/rowid */
106699107403
int nKeyCol; /* Number of index columns w/o the pk/rowid */
107404
+ u8 nSkipAhead; /* Number of times of skip-ahead */
106700107405
StatSample current; /* Current row as a StatSample */
106701107406
#ifdef SQLITE_ENABLE_STAT4
106702107407
tRowcnt nPSample; /* How often to do a periodic sample */
106703107408
int mxSample; /* Maximum number of samples to accumulate */
106704107409
u32 iPrn; /* Pseudo-random number used for sampling */
@@ -106774,31 +107479,32 @@
106774107479
** Reclaim all memory of a StatAccum structure.
106775107480
*/
106776107481
static void statAccumDestructor(void *pOld){
106777107482
StatAccum *p = (StatAccum*)pOld;
106778107483
#ifdef SQLITE_ENABLE_STAT4
106779
- int i;
106780
- for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
106781
- for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
106782
- sampleClear(p->db, &p->current);
107484
+ if( p->mxSample ){
107485
+ int i;
107486
+ for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
107487
+ for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
107488
+ sampleClear(p->db, &p->current);
107489
+ }
106783107490
#endif
106784107491
sqlite3DbFree(p->db, p);
106785107492
}
106786107493
106787107494
/*
106788
-** Implementation of the stat_init(N,K,C) SQL function. The three parameters
107495
+** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
106789107496
** are:
106790107497
** N: The number of columns in the index including the rowid/pk (note 1)
106791107498
** K: The number of columns in the index excluding the rowid/pk.
106792
-** C: The number of rows in the index (note 2)
107499
+** C: Estimated number of rows in the index
107500
+** L: A limit on the number of rows to scan, or 0 for no-limit
106793107501
**
106794107502
** Note 1: In the special case of the covering index that implements a
106795107503
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
106796107504
** total number of columns in the table.
106797107505
**
106798
-** Note 2: C is only used for STAT4.
106799
-**
106800107506
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
106801107507
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
106802107508
** PRIMARY KEY of the table. The covering index that implements the
106803107509
** original WITHOUT ROWID table as N==K as a special case.
106804107510
**
@@ -106815,13 +107521,14 @@
106815107521
StatAccum *p;
106816107522
int nCol; /* Number of columns in index being sampled */
106817107523
int nKeyCol; /* Number of key columns */
106818107524
int nColUp; /* nCol rounded up for alignment */
106819107525
int n; /* Bytes of space to allocate */
106820
- sqlite3 *db; /* Database connection */
107526
+ sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
106821107527
#ifdef SQLITE_ENABLE_STAT4
106822
- int mxSample = SQLITE_STAT4_SAMPLES;
107528
+ /* Maximum number of samples. 0 if STAT4 data is not collected */
107529
+ int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
106823107530
#endif
106824107531
106825107532
/* Decode the three function arguments */
106826107533
UNUSED_PARAMETER(argc);
106827107534
nCol = sqlite3_value_int(argv[0]);
@@ -106832,39 +107539,43 @@
106832107539
assert( nKeyCol>0 );
106833107540
106834107541
/* Allocate the space required for the StatAccum object */
106835107542
n = sizeof(*p)
106836107543
+ sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
106837
- + sizeof(tRowcnt)*nColUp /* StatAccum.anDLt */
107544
+ + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
106838107545
#ifdef SQLITE_ENABLE_STAT4
106839
- + sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
106840
- + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
106841
- + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
107546
+ if( mxSample ){
107547
+ n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
107548
+ + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
107549
+ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
107550
+ }
106842107551
#endif
106843
- ;
106844107552
db = sqlite3_context_db_handle(context);
106845107553
p = sqlite3DbMallocZero(db, n);
106846107554
if( p==0 ){
106847107555
sqlite3_result_error_nomem(context);
106848107556
return;
106849107557
}
106850107558
106851107559
p->db = db;
107560
+ p->nEst = sqlite3_value_int64(argv[2]);
106852107561
p->nRow = 0;
107562
+ p->nLimit = sqlite3_value_int64(argv[3]);
106853107563
p->nCol = nCol;
106854107564
p->nKeyCol = nKeyCol;
107565
+ p->nSkipAhead = 0;
106855107566
p->current.anDLt = (tRowcnt*)&p[1];
106856107567
p->current.anEq = &p->current.anDLt[nColUp];
106857107568
106858107569
#ifdef SQLITE_ENABLE_STAT4
106859
- {
107570
+ p->mxSample = p->nLimit==0 ? mxSample : 0;
107571
+ if( mxSample ){
106860107572
u8 *pSpace; /* Allocated space not yet assigned */
106861107573
int i; /* Used to iterate through p->aSample[] */
106862107574
106863107575
p->iGet = -1;
106864
- p->mxSample = mxSample;
106865
- p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
107576
+ p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
106866107577
p->current.anLt = &p->current.anEq[nColUp];
106867107578
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
106868107579
106869107580
/* Set up the StatAccum.a[] and aBest[] arrays */
106870107581
p->a = (struct StatSample*)&p->current.anLt[nColUp];
@@ -106888,11 +107599,11 @@
106888107599
** (given by the 3rd parameter) is never used and can be any positive
106889107600
** value. */
106890107601
sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
106891107602
}
106892107603
static const FuncDef statInitFuncdef = {
106893
- 2+IsStat4, /* nArg */
107604
+ 4, /* nArg */
106894107605
SQLITE_UTF8, /* funcFlags */
106895107606
0, /* pUserData */
106896107607
0, /* pNext */
106897107608
statInit, /* xSFunc */
106898107609
0, /* xFinalize */
@@ -107092,14 +107803,17 @@
107092107803
** P Pointer to the StatAccum object created by stat_init()
107093107804
** C Index of left-most column to differ from previous row
107094107805
** R Rowid for the current row. Might be a key record for
107095107806
** WITHOUT ROWID tables.
107096107807
**
107097
-** This SQL function always returns NULL. It's purpose it to accumulate
107098
-** statistical data and/or samples in the StatAccum object about the
107099
-** index being analyzed. The stat_get() SQL function will later be used to
107100
-** extract relevant information for constructing the sqlite_statN tables.
107808
+** The purpose of this routine is to collect statistical data and/or
107809
+** samples from the index being analyzed into the StatAccum object.
107810
+** The stat_get() SQL function will be used afterwards to
107811
+** retrieve the information gathered.
107812
+**
107813
+** This SQL function usually returns NULL, but might return an integer
107814
+** if it wants the byte-code to do special processing.
107101107815
**
107102107816
** The R parameter is only used for STAT4
107103107817
*/
107104107818
static void statPush(
107105107819
sqlite3_context *context,
@@ -107121,11 +107835,11 @@
107121107835
/* This is the first call to this function. Do initialization. */
107122107836
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
107123107837
}else{
107124107838
/* Second and subsequent calls get processed here */
107125107839
#ifdef SQLITE_ENABLE_STAT4
107126
- samplePushPrevious(p, iChng);
107840
+ if( p->mxSample ) samplePushPrevious(p, iChng);
107127107841
#endif
107128107842
107129107843
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
107130107844
** to the current row of the index. */
107131107845
for(i=0; i<iChng; i++){
@@ -107132,30 +107846,29 @@
107132107846
p->current.anEq[i]++;
107133107847
}
107134107848
for(i=iChng; i<p->nCol; i++){
107135107849
p->current.anDLt[i]++;
107136107850
#ifdef SQLITE_ENABLE_STAT4
107137
- p->current.anLt[i] += p->current.anEq[i];
107851
+ if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
107138107852
#endif
107139107853
p->current.anEq[i] = 1;
107140107854
}
107141107855
}
107856
+
107142107857
p->nRow++;
107143107858
#ifdef SQLITE_ENABLE_STAT4
107144
- if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
107145
- sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
107146
- }else{
107147
- sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
107148
- sqlite3_value_blob(argv[2]));
107149
- }
107150
- p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
107151
-#endif
107152
-
107153
-#ifdef SQLITE_ENABLE_STAT4
107154
- {
107155
- tRowcnt nLt = p->current.anLt[p->nCol-1];
107156
-
107859
+ if( p->mxSample ){
107860
+ tRowcnt nLt;
107861
+ if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
107862
+ sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
107863
+ }else{
107864
+ sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
107865
+ sqlite3_value_blob(argv[2]));
107866
+ }
107867
+ p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
107868
+
107869
+ nLt = p->current.anLt[p->nCol-1];
107157107870
/* Check if this is to be a periodic sample. If so, add it. */
107158107871
if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
107159107872
p->current.isPSample = 1;
107160107873
p->current.iCol = 0;
107161107874
sampleInsert(p, &p->current, p->nCol-1);
@@ -107167,13 +107880,18 @@
107167107880
p->current.iCol = i;
107168107881
if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
107169107882
sampleCopy(p, &p->aBest[i], &p->current);
107170107883
}
107171107884
}
107885
+ }else
107886
+#endif
107887
+ if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
107888
+ p->nSkipAhead++;
107889
+ sqlite3_result_int(context, p->current.anDLt[0]>0);
107172107890
}
107173
-#endif
107174107891
}
107892
+
107175107893
static const FuncDef statPushFuncdef = {
107176107894
2+IsStat4, /* nArg */
107177107895
SQLITE_UTF8, /* funcFlags */
107178107896
0, /* pUserData */
107179107897
0, /* pNext */
@@ -107221,10 +107939,11 @@
107221107939
assert( argc==2 );
107222107940
assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
107223107941
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
107224107942
|| eCall==STAT_GET_NDLT
107225107943
);
107944
+ assert( eCall==STAT_GET_STAT1 || p->mxSample );
107226107945
if( eCall==STAT_GET_STAT1 )
107227107946
#else
107228107947
assert( argc==1 );
107229107948
#endif
107230107949
{
@@ -107256,11 +107975,12 @@
107256107975
if( zRet==0 ){
107257107976
sqlite3_result_error_nomem(context);
107258107977
return;
107259107978
}
107260107979
107261
- sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
107980
+ sqlite3_snprintf(24, zRet, "%llu",
107981
+ p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
107262107982
z = zRet + sqlite3Strlen30(zRet);
107263107983
for(i=0; i<p->nKeyCol; i++){
107264107984
u64 nDistinct = p->current.anDLt[i] + 1;
107265107985
u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
107266107986
sqlite3_snprintf(24, z, " %llu", iVal);
@@ -107332,20 +108052,20 @@
107332108052
0, 0, /* xValue, xInverse */
107333108053
"stat_get", /* zName */
107334108054
{0}
107335108055
};
107336108056
107337
-static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){
108057
+static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
107338108058
#ifdef SQLITE_ENABLE_STAT4
107339
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1);
108059
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
107340108060
#elif SQLITE_DEBUG
107341108061
assert( iParam==STAT_GET_STAT1 );
107342108062
#else
107343108063
UNUSED_PARAMETER( iParam );
107344108064
#endif
107345
- assert( regOut!=regStat4 && regOut!=regStat4+1 );
107346
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4,
108065
+ assert( regOut!=regStat && regOut!=regStat+1 );
108066
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
107347108067
&statGetFuncdef, 0);
107348108068
}
107349108069
107350108070
/*
107351108071
** Generate code to do an analysis of all indices associated with
@@ -107367,16 +108087,15 @@
107367108087
int i; /* Loop counter */
107368108088
int jZeroRows = -1; /* Jump from here if number of rows is zero */
107369108089
int iDb; /* Index of database containing pTab */
107370108090
u8 needTableCnt = 1; /* True to count the table */
107371108091
int regNewRowid = iMem++; /* Rowid for the inserted record */
107372
- int regStat4 = iMem++; /* Register to hold StatAccum object */
108092
+ int regStat = iMem++; /* Register to hold StatAccum object */
107373108093
int regChng = iMem++; /* Index of changed index field */
107374
-#ifdef SQLITE_ENABLE_STAT4
107375108094
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
107376
-#endif
107377108095
int regTemp = iMem++; /* Temporary use register */
108096
+ int regTemp2 = iMem++; /* Second temporary use register */
107378108097
int regTabname = iMem++; /* Register containing table name */
107379108098
int regIdxname = iMem++; /* Register containing index name */
107380108099
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
107381108100
int regPrev = iMem; /* MUST BE LAST (see below) */
107382108101
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -107500,21 +108219,30 @@
107500108219
/* Invoke the stat_init() function. The arguments are:
107501108220
**
107502108221
** (1) the number of columns in the index including the rowid
107503108222
** (or for a WITHOUT ROWID table, the number of PK columns),
107504108223
** (2) the number of columns in the key without the rowid/pk
107505
- ** (3) the number of rows in the index,
107506
- **
107507
- **
107508
- ** The third argument is only used for STAT4
108224
+ ** (3) estimated number of rows in the index,
107509108225
*/
108226
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
108227
+ assert( regRowid==regStat+2 );
108228
+ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
107510108229
#ifdef SQLITE_ENABLE_STAT4
107511
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
108230
+ if( OptimizationEnabled(db, SQLITE_Stat4) ){
108231
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
108232
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
108233
+ VdbeCoverage(v);
108234
+ }else
107512108235
#endif
107513
- sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
107514
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
107515
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4,
108236
+ {
108237
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
108238
+ VdbeCoverage(v);
108239
+ sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
108240
+ }
108241
+ assert( regTemp2==regStat+4 );
108242
+ sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
108243
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
107516108244
&statInitFuncdef, 0);
107517108245
107518108246
/* Implementation of the following:
107519108247
**
107520108248
** Rewind csr
@@ -107521,12 +108249,10 @@
107521108249
** if eof(csr) goto end_of_scan;
107522108250
** regChng = 0
107523108251
** goto next_push_0;
107524108252
**
107525108253
*/
107526
- addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
107527
- VdbeCoverage(v);
107528108254
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
107529108255
addrNextRow = sqlite3VdbeCurrentAddr(v);
107530108256
107531108257
if( nColTest>0 ){
107532108258
int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
@@ -107555,10 +108281,11 @@
107555108281
}
107556108282
for(i=0; i<nColTest; i++){
107557108283
char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
107558108284
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
107559108285
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
108286
+ VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
107560108287
aGotoChng[i] =
107561108288
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
107562108289
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
107563108290
VdbeCoverage(v);
107564108291
}
@@ -107575,10 +108302,11 @@
107575108302
*/
107576108303
sqlite3VdbeJumpHere(v, addrNextRow-1);
107577108304
for(i=0; i<nColTest; i++){
107578108305
sqlite3VdbeJumpHere(v, aGotoChng[i]);
107579108306
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
108307
+ VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
107580108308
}
107581108309
sqlite3VdbeResolveLabel(v, endDistinctTest);
107582108310
sqlite3DbFree(db, aGotoChng);
107583108311
}
107584108312
@@ -107588,34 +108316,50 @@
107588108316
** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
107589108317
** Next csr
107590108318
** if !eof(csr) goto next_row;
107591108319
*/
107592108320
#ifdef SQLITE_ENABLE_STAT4
107593
- assert( regRowid==(regStat4+2) );
107594
- if( HasRowid(pTab) ){
107595
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
107596
- }else{
107597
- Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
107598
- int j, k, regKey;
107599
- regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
107600
- for(j=0; j<pPk->nKeyCol; j++){
107601
- k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
107602
- assert( k>=0 && k<pIdx->nColumn );
107603
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
107604
- VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
107605
- }
107606
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
107607
- sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
108321
+ if( OptimizationEnabled(db, SQLITE_Stat4) ){
108322
+ assert( regRowid==(regStat+2) );
108323
+ if( HasRowid(pTab) ){
108324
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
108325
+ }else{
108326
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
108327
+ int j, k, regKey;
108328
+ regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
108329
+ for(j=0; j<pPk->nKeyCol; j++){
108330
+ k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
108331
+ assert( k>=0 && k<pIdx->nColumn );
108332
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
108333
+ VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
108334
+ }
108335
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
108336
+ sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
108337
+ }
107608108338
}
107609108339
#endif
107610
- assert( regChng==(regStat4+1) );
107611
- sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4,
107612
- &statPushFuncdef, 0);
107613
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
108340
+ assert( regChng==(regStat+1) );
108341
+ {
108342
+ sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
108343
+ &statPushFuncdef, 0);
108344
+ if( db->nAnalysisLimit ){
108345
+ int j1, j2, j3;
108346
+ j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
108347
+ j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
108348
+ j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
108349
+ VdbeCoverage(v);
108350
+ sqlite3VdbeJumpHere(v, j1);
108351
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
108352
+ sqlite3VdbeJumpHere(v, j2);
108353
+ sqlite3VdbeJumpHere(v, j3);
108354
+ }else{
108355
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
108356
+ }
108357
+ }
107614108358
107615108359
/* Add the entry to the stat1 table. */
107616
- callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1);
108360
+ callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
107617108361
assert( "BBB"[0]==SQLITE_AFF_TEXT );
107618108362
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
107619108363
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
107620108364
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
107621108365
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -107623,11 +108367,11 @@
107623108367
#endif
107624108368
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
107625108369
107626108370
/* Add the entries to the stat4 table. */
107627108371
#ifdef SQLITE_ENABLE_STAT4
107628
- {
108372
+ if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
107629108373
int regEq = regStat1;
107630108374
int regLt = regStat1+1;
107631108375
int regDLt = regStat1+2;
107632108376
int regSample = regStat1+3;
107633108377
int regCol = regStat1+4;
@@ -107637,16 +108381,16 @@
107637108381
u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
107638108382
107639108383
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
107640108384
107641108385
addrNext = sqlite3VdbeCurrentAddr(v);
107642
- callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid);
108386
+ callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
107643108387
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
107644108388
VdbeCoverage(v);
107645
- callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq);
107646
- callStatGet(pParse, regStat4, STAT_GET_NLT, regLt);
107647
- callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt);
108389
+ callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
108390
+ callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
108391
+ callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
107648108392
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
107649108393
VdbeCoverage(v);
107650108394
for(i=0; i<nCol; i++){
107651108395
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
107652108396
}
@@ -113818,11 +114562,11 @@
113818114562
pParse->rc = rc;
113819114563
return 1;
113820114564
}
113821114565
db->aDb[1].pBt = pBt;
113822114566
assert( db->aDb[1].pSchema );
113823
- if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
114567
+ if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){
113824114568
sqlite3OomFault(db);
113825114569
return 1;
113826114570
}
113827114571
}
113828114572
return 0;
@@ -113929,11 +114673,11 @@
113929114673
char *p4, /* Error message */
113930114674
i8 p4type, /* P4_STATIC or P4_TRANSIENT */
113931114675
u8 p5Errmsg /* P5_ErrMsg type */
113932114676
){
113933114677
Vdbe *v = sqlite3GetVdbe(pParse);
113934
- assert( (errCode&0xff)==SQLITE_CONSTRAINT );
114678
+ assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
113935114679
if( onError==OE_Abort ){
113936114680
sqlite3MayAbort(pParse);
113937114681
}
113938114682
sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
113939114683
sqlite3VdbeChangeP5(v, p5Errmsg);
@@ -115642,10 +116386,11 @@
115642116386
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
115643116387
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
115644116388
&iPartIdxLabel, pPrior, r1);
115645116389
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
115646116390
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
116391
+ sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */
115647116392
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
115648116393
pPrior = pIdx;
115649116394
}
115650116395
}
115651116396
@@ -122629,10 +123374,11 @@
122629123374
const char *(*filename_wal)(const char*);
122630123375
/* Version 3.32.0 and later */
122631123376
char *(*create_filename)(const char*,const char*,const char*,
122632123377
int,const char**);
122633123378
void (*free_filename)(char*);
123379
+ sqlite3_file *(*database_file_object)(const char*);
122634123380
};
122635123381
122636123382
/*
122637123383
** This is the function signature used for all extension entry points. It
122638123384
** is also defined in the file "loadext.c".
@@ -122932,10 +123678,11 @@
122932123678
#define sqlite3_filename_journal sqlite3_api->filename_journal
122933123679
#define sqlite3_filename_wal sqlite3_api->filename_wal
122934123680
/* Version 3.32.0 and later */
122935123681
#define sqlite3_create_filename sqlite3_api->create_filename
122936123682
#define sqlite3_free_filename sqlite3_api->free_filename
123683
+#define sqlite3_database_file_object sqlite3_api->database_file_object
122937123684
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
122938123685
122939123686
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
122940123687
/* This case when the file really is being compiled as a loadable
122941123688
** extension */
@@ -123413,11 +124160,20 @@
123413124160
sqlite3_filename_journal,
123414124161
sqlite3_filename_wal,
123415124162
/* Version 3.32.0 and later */
123416124163
sqlite3_create_filename,
123417124164
sqlite3_free_filename,
124165
+ sqlite3_database_file_object,
123418124166
};
124167
+
124168
+/* True if x is the directory separator character
124169
+*/
124170
+#if SQLITE_OS_WIN
124171
+# define DirSep(X) ((X)=='/'||(X)=='\\')
124172
+#else
124173
+# define DirSep(X) ((X)=='/')
124174
+#endif
123419124175
123420124176
/*
123421124177
** Attempt to load an SQLite extension library contained in the file
123422124178
** zFile. The entry point is zProc. zProc may be 0 in which case a
123423124179
** default entry point name (sqlite3_extension_init) is used. Use
@@ -123516,11 +124272,11 @@
123516124272
if( zAltEntry==0 ){
123517124273
sqlite3OsDlClose(pVfs, handle);
123518124274
return SQLITE_NOMEM_BKPT;
123519124275
}
123520124276
memcpy(zAltEntry, "sqlite3_", 8);
123521
- for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
124277
+ for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){}
123522124278
iFile++;
123523124279
if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
123524124280
for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
123525124281
if( sqlite3Isalpha(c) ){
123526124282
zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
@@ -123820,53 +124576,54 @@
123820124576
** that script and rerun it.
123821124577
*/
123822124578
123823124579
/* The various pragma types */
123824124580
#define PragTyp_ACTIVATE_EXTENSIONS 0
123825
-#define PragTyp_HEADER_VALUE 1
123826
-#define PragTyp_AUTO_VACUUM 2
123827
-#define PragTyp_FLAG 3
123828
-#define PragTyp_BUSY_TIMEOUT 4
123829
-#define PragTyp_CACHE_SIZE 5
123830
-#define PragTyp_CACHE_SPILL 6
123831
-#define PragTyp_CASE_SENSITIVE_LIKE 7
123832
-#define PragTyp_COLLATION_LIST 8
123833
-#define PragTyp_COMPILE_OPTIONS 9
123834
-#define PragTyp_DATA_STORE_DIRECTORY 10
123835
-#define PragTyp_DATABASE_LIST 11
123836
-#define PragTyp_DEFAULT_CACHE_SIZE 12
123837
-#define PragTyp_ENCODING 13
123838
-#define PragTyp_FOREIGN_KEY_CHECK 14
123839
-#define PragTyp_FOREIGN_KEY_LIST 15
123840
-#define PragTyp_FUNCTION_LIST 16
123841
-#define PragTyp_HARD_HEAP_LIMIT 17
123842
-#define PragTyp_INCREMENTAL_VACUUM 18
123843
-#define PragTyp_INDEX_INFO 19
123844
-#define PragTyp_INDEX_LIST 20
123845
-#define PragTyp_INTEGRITY_CHECK 21
123846
-#define PragTyp_JOURNAL_MODE 22
123847
-#define PragTyp_JOURNAL_SIZE_LIMIT 23
123848
-#define PragTyp_LOCK_PROXY_FILE 24
123849
-#define PragTyp_LOCKING_MODE 25
123850
-#define PragTyp_PAGE_COUNT 26
123851
-#define PragTyp_MMAP_SIZE 27
123852
-#define PragTyp_MODULE_LIST 28
123853
-#define PragTyp_OPTIMIZE 29
123854
-#define PragTyp_PAGE_SIZE 30
123855
-#define PragTyp_PRAGMA_LIST 31
123856
-#define PragTyp_SECURE_DELETE 32
123857
-#define PragTyp_SHRINK_MEMORY 33
123858
-#define PragTyp_SOFT_HEAP_LIMIT 34
123859
-#define PragTyp_SYNCHRONOUS 35
123860
-#define PragTyp_TABLE_INFO 36
123861
-#define PragTyp_TEMP_STORE 37
123862
-#define PragTyp_TEMP_STORE_DIRECTORY 38
123863
-#define PragTyp_THREADS 39
123864
-#define PragTyp_WAL_AUTOCHECKPOINT 40
123865
-#define PragTyp_WAL_CHECKPOINT 41
123866
-#define PragTyp_LOCK_STATUS 42
123867
-#define PragTyp_STATS 43
124581
+#define PragTyp_ANALYSIS_LIMIT 1
124582
+#define PragTyp_HEADER_VALUE 2
124583
+#define PragTyp_AUTO_VACUUM 3
124584
+#define PragTyp_FLAG 4
124585
+#define PragTyp_BUSY_TIMEOUT 5
124586
+#define PragTyp_CACHE_SIZE 6
124587
+#define PragTyp_CACHE_SPILL 7
124588
+#define PragTyp_CASE_SENSITIVE_LIKE 8
124589
+#define PragTyp_COLLATION_LIST 9
124590
+#define PragTyp_COMPILE_OPTIONS 10
124591
+#define PragTyp_DATA_STORE_DIRECTORY 11
124592
+#define PragTyp_DATABASE_LIST 12
124593
+#define PragTyp_DEFAULT_CACHE_SIZE 13
124594
+#define PragTyp_ENCODING 14
124595
+#define PragTyp_FOREIGN_KEY_CHECK 15
124596
+#define PragTyp_FOREIGN_KEY_LIST 16
124597
+#define PragTyp_FUNCTION_LIST 17
124598
+#define PragTyp_HARD_HEAP_LIMIT 18
124599
+#define PragTyp_INCREMENTAL_VACUUM 19
124600
+#define PragTyp_INDEX_INFO 20
124601
+#define PragTyp_INDEX_LIST 21
124602
+#define PragTyp_INTEGRITY_CHECK 22
124603
+#define PragTyp_JOURNAL_MODE 23
124604
+#define PragTyp_JOURNAL_SIZE_LIMIT 24
124605
+#define PragTyp_LOCK_PROXY_FILE 25
124606
+#define PragTyp_LOCKING_MODE 26
124607
+#define PragTyp_PAGE_COUNT 27
124608
+#define PragTyp_MMAP_SIZE 28
124609
+#define PragTyp_MODULE_LIST 29
124610
+#define PragTyp_OPTIMIZE 30
124611
+#define PragTyp_PAGE_SIZE 31
124612
+#define PragTyp_PRAGMA_LIST 32
124613
+#define PragTyp_SECURE_DELETE 33
124614
+#define PragTyp_SHRINK_MEMORY 34
124615
+#define PragTyp_SOFT_HEAP_LIMIT 35
124616
+#define PragTyp_SYNCHRONOUS 36
124617
+#define PragTyp_TABLE_INFO 37
124618
+#define PragTyp_TEMP_STORE 38
124619
+#define PragTyp_TEMP_STORE_DIRECTORY 39
124620
+#define PragTyp_THREADS 40
124621
+#define PragTyp_WAL_AUTOCHECKPOINT 41
124622
+#define PragTyp_WAL_CHECKPOINT 42
124623
+#define PragTyp_LOCK_STATUS 43
124624
+#define PragTyp_STATS 44
123868124625
123869124626
/* Property flags associated with various pragma. */
123870124627
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
123871124628
#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
123872124629
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
@@ -123953,10 +124710,15 @@
123953124710
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
123954124711
/* ePragFlg: */ 0,
123955124712
/* ColNames: */ 0, 0,
123956124713
/* iArg: */ 0 },
123957124714
#endif
124715
+ {/* zName: */ "analysis_limit",
124716
+ /* ePragTyp: */ PragTyp_ANALYSIS_LIMIT,
124717
+ /* ePragFlg: */ PragFlg_Result0,
124718
+ /* ColNames: */ 0, 0,
124719
+ /* iArg: */ 0 },
123958124720
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
123959124721
{/* zName: */ "application_id",
123960124722
/* ePragTyp: */ PragTyp_HEADER_VALUE,
123961124723
/* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
123962124724
/* ColNames: */ 0, 0,
@@ -124453,11 +125215,11 @@
124453125215
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
124454125216
/* ColNames: */ 0, 0,
124455125217
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
124456125218
#endif
124457125219
};
124458
-/* Number of pragmas: 66 on by default, 76 total. */
125220
+/* Number of pragmas: 67 on by default, 77 total. */
124459125221
124460125222
/************** End of pragma.h **********************************************/
124461125223
/************** Continuing where we left off in pragma.c *********************/
124462125224
124463125225
/*
@@ -124983,11 +125745,11 @@
124983125745
}else{
124984125746
/* Malloc may fail when setting the page-size, as there is an internal
124985125747
** buffer that the pager module resizes using sqlite3_realloc().
124986125748
*/
124987125749
db->nextPagesize = sqlite3Atoi(zRight);
124988
- if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
125750
+ if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){
124989125751
sqlite3OomFault(db);
124990125752
}
124991125753
}
124992125754
break;
124993125755
}
@@ -126157,11 +126919,10 @@
126157126919
sqlite3ResolvePartIdxLabel(pParse, jmp3);
126158126920
}
126159126921
}
126160126922
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
126161126923
sqlite3VdbeJumpHere(v, loopTop-1);
126162
-#ifndef SQLITE_OMIT_BTREECOUNT
126163126924
if( !isQuick ){
126164126925
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
126165126926
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
126166126927
if( pPk==pIdx ) continue;
126167126928
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
@@ -126171,11 +126932,10 @@
126171126932
sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
126172126933
integrityCheckResultRow(v);
126173126934
sqlite3VdbeJumpHere(v, addr);
126174126935
}
126175126936
}
126176
-#endif /* SQLITE_OMIT_BTREECOUNT */
126177126937
}
126178126938
}
126179126939
{
126180126940
static const int iLn = VDBE_OFFSET_LINENO(2);
126181126941
static const VdbeOpList endCode[] = {
@@ -126605,10 +127365,29 @@
126605127365
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
126606127366
}
126607127367
returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
126608127368
break;
126609127369
}
127370
+
127371
+ /*
127372
+ ** PRAGMA analysis_limit
127373
+ ** PRAGMA analysis_limit = N
127374
+ **
127375
+ ** Configure the maximum number of rows that ANALYZE will examine
127376
+ ** in each index that it looks at. Return the new limit.
127377
+ */
127378
+ case PragTyp_ANALYSIS_LIMIT: {
127379
+ sqlite3_int64 N;
127380
+ if( zRight
127381
+ && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
127382
+ && N>=0
127383
+ ){
127384
+ db->nAnalysisLimit = (int)(N&0x7fffffff);
127385
+ }
127386
+ returnSingleInt(v, db->nAnalysisLimit);
127387
+ break;
127388
+ }
126610127389
126611127390
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
126612127391
/*
126613127392
** Report the current state of file logs for all databases
126614127393
*/
@@ -131404,10 +132183,11 @@
131404132183
if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
131405132184
memset(&ifNullRow, 0, sizeof(ifNullRow));
131406132185
ifNullRow.op = TK_IF_NULL_ROW;
131407132186
ifNullRow.pLeft = pCopy;
131408132187
ifNullRow.iTable = pSubst->iNewTable;
132188
+ ifNullRow.flags = EP_Skip;
131409132189
pCopy = &ifNullRow;
131410132190
}
131411132191
testcase( ExprHasProperty(pCopy, EP_Subquery) );
131412132192
pNew = sqlite3ExprDup(db, pCopy, 0);
131413132193
if( pNew && pSubst->isLeftJoin ){
@@ -134568,11 +135348,10 @@
134568135348
VdbeComment((v, "indicate accumulator empty"));
134569135349
sqlite3VdbeAddOp1(v, OP_Return, regReset);
134570135350
134571135351
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
134572135352
else {
134573
-#ifndef SQLITE_OMIT_BTREECOUNT
134574135353
Table *pTab;
134575135354
if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
134576135355
/* If isSimpleCount() returns a pointer to a Table structure, then
134577135356
** the SQL statement is of the form:
134578135357
**
@@ -134604,17 +135383,19 @@
134604135383
**
134605135384
** In practice the KeyInfo structure will not be used. It is only
134606135385
** passed to keep OP_OpenRead happy.
134607135386
*/
134608135387
if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
134609
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
134610
- if( pIdx->bUnordered==0
134611
- && pIdx->szIdxRow<pTab->szTabRow
134612
- && pIdx->pPartIdxWhere==0
134613
- && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
134614
- ){
134615
- pBest = pIdx;
135388
+ if( !p->pSrc->a[0].fg.notIndexed ){
135389
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
135390
+ if( pIdx->bUnordered==0
135391
+ && pIdx->szIdxRow<pTab->szTabRow
135392
+ && pIdx->pPartIdxWhere==0
135393
+ && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
135394
+ ){
135395
+ pBest = pIdx;
135396
+ }
134616135397
}
134617135398
}
134618135399
if( pBest ){
134619135400
iRoot = pBest->tnum;
134620135401
pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
@@ -134626,13 +135407,11 @@
134626135407
sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
134627135408
}
134628135409
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
134629135410
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
134630135411
explainSimpleCount(pParse, pTab, pBest);
134631
- }else
134632
-#endif /* SQLITE_OMIT_BTREECOUNT */
134633
- {
135412
+ }else{
134634135413
int regAcc = 0; /* "populate accumulators" flag */
134635135414
134636135415
/* If there are accumulator registers but no min() or max() functions
134637135416
** without FILTER clauses, allocate register regAcc. Register regAcc
134638135417
** will contain 0 the first time the inner loop runs, and 1 thereafter.
@@ -137852,11 +138631,11 @@
137852138631
db->mDbFlags = saved_mDbFlags;
137853138632
db->flags = saved_flags;
137854138633
db->nChange = saved_nChange;
137855138634
db->nTotalChange = saved_nTotalChange;
137856138635
db->mTrace = saved_mTrace;
137857
- sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
138636
+ sqlite3BtreeSetPageSize(pMain, -1, 0, 1);
137858138637
137859138638
/* Currently there is an SQL level transaction open on the vacuum
137860138639
** database. No locks are held on any other files (since the main file
137861138640
** was committed at the btree level). So it safe to end the transaction
137862138641
** by manually setting the autoCommit flag to true and detaching the
@@ -159255,19 +160034,82 @@
159255160034
159256160035
159257160036
/************** End of sqliteicu.h *******************************************/
159258160037
/************** Continuing where we left off in main.c ***********************/
159259160038
#endif
160039
+
160040
+/*
160041
+** This is an extension initializer that is a no-op and always
160042
+** succeeds, except that it fails if the fault-simulation is set
160043
+** to 500.
160044
+*/
160045
+static int sqlite3TestExtInit(sqlite3 *db){
160046
+ (void)db;
160047
+ return sqlite3FaultSim(500);
160048
+}
160049
+
160050
+
160051
+/*
160052
+** Forward declarations of external module initializer functions
160053
+** for modules that need them.
160054
+*/
160055
+#ifdef SQLITE_ENABLE_FTS1
160056
+SQLITE_PRIVATE int sqlite3Fts1Init(sqlite3*);
160057
+#endif
160058
+#ifdef SQLITE_ENABLE_FTS2
160059
+SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*);
160060
+#endif
160061
+#ifdef SQLITE_ENABLE_FTS5
160062
+SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
160063
+#endif
159260160064
#ifdef SQLITE_ENABLE_JSON1
159261160065
SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
159262160066
#endif
159263160067
#ifdef SQLITE_ENABLE_STMTVTAB
159264160068
SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
159265160069
#endif
160070
+
160071
+/*
160072
+** An array of pointers to extension initializer functions for
160073
+** built-in extensions.
160074
+*/
160075
+static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
160076
+#ifdef SQLITE_ENABLE_FTS1
160077
+ sqlite3Fts1Init,
160078
+#endif
160079
+#ifdef SQLITE_ENABLE_FTS2
160080
+ sqlite3Fts2Init,
160081
+#endif
160082
+#ifdef SQLITE_ENABLE_FTS3
160083
+ sqlite3Fts3Init,
160084
+#endif
159266160085
#ifdef SQLITE_ENABLE_FTS5
159267
-SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
160086
+ sqlite3Fts5Init,
159268160087
#endif
160088
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
160089
+ sqlite3IcuInit,
160090
+#endif
160091
+#ifdef SQLITE_ENABLE_RTREE
160092
+ sqlite3RtreeInit,
160093
+#endif
160094
+#ifdef SQLITE_ENABLE_DBPAGE_VTAB
160095
+ sqlite3DbpageRegister,
160096
+#endif
160097
+#ifdef SQLITE_ENABLE_DBSTAT_VTAB
160098
+ sqlite3DbstatRegister,
160099
+#endif
160100
+ sqlite3TestExtInit,
160101
+#ifdef SQLITE_ENABLE_JSON1
160102
+ sqlite3Json1Init,
160103
+#endif
160104
+#ifdef SQLITE_ENABLE_STMTVTAB
160105
+ sqlite3StmtVtabInit,
160106
+#endif
160107
+#ifdef SQLITE_ENABLE_BYTECODE_VTAB
160108
+ sqlite3VdbeBytecodeVtabInit,
160109
+#endif
160110
+};
159269160111
159270160112
#ifndef SQLITE_AMALGAMATION
159271160113
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
159272160114
** contains the text of SQLITE_VERSION macro.
159273160115
*/
@@ -160781,12 +161623,11 @@
160781161623
** Return non-zero to retry the lock. Return zero to stop trying
160782161624
** and cause SQLite to return SQLITE_BUSY.
160783161625
*/
160784161626
static int sqliteDefaultBusyCallback(
160785161627
void *ptr, /* Database connection */
160786
- int count, /* Number of times table has been busy */
160787
- sqlite3_file *pFile /* The file on which the lock occurred */
161628
+ int count /* Number of times table has been busy */
160788161629
){
160789161630
#if SQLITE_OS_WIN || HAVE_USLEEP
160790161631
/* This case is for systems that have support for sleeping for fractions of
160791161632
** a second. Examples: All windows systems, unix systems with usleep() */
160792161633
static const u8 delays[] =
@@ -160796,35 +161637,10 @@
160796161637
# define NDELAY ArraySize(delays)
160797161638
sqlite3 *db = (sqlite3 *)ptr;
160798161639
int tmout = db->busyTimeout;
160799161640
int delay, prior;
160800161641
160801
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
160802
- if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
160803
- if( count ){
160804
- /* If this is the second or later invocation of the busy-handler,
160805
- ** but tmout==0, then code in wal.c must have disabled the blocking
160806
- ** lock before the SQLITE_BUSY error was hit. In this case, no delay
160807
- ** occurred while waiting for the lock, so fall through to the xSleep()
160808
- ** code below to delay a while before retrying the lock.
160809
- **
160810
- ** Alternatively, if tmout!=0, then SQLite has already waited
160811
- ** sqlite3.busyTimeout ms for a lock. In this case, return 0 to
160812
- ** indicate that the lock should not be retried and the SQLITE_BUSY
160813
- ** error returned to the application. */
160814
- if( tmout ){
160815
- tmout = 0;
160816
- sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
160817
- return 0;
160818
- }
160819
- }else{
160820
- return 1;
160821
- }
160822
- }
160823
-#else
160824
- UNUSED_PARAMETER(pFile);
160825
-#endif
160826161642
assert( count>=0 );
160827161643
if( count < NDELAY ){
160828161644
delay = delays[count];
160829161645
prior = totals[count];
160830161646
}else{
@@ -160840,11 +161656,10 @@
160840161656
#else
160841161657
/* This case for unix systems that lack usleep() support. Sleeping
160842161658
** must be done in increments of whole seconds */
160843161659
sqlite3 *db = (sqlite3 *)ptr;
160844161660
int tmout = ((sqlite3 *)ptr)->busyTimeout;
160845
- UNUSED_PARAMETER(pFile);
160846161661
if( (count+1)*1000 > tmout ){
160847161662
return 0;
160848161663
}
160849161664
sqlite3OsSleep(db->pVfs, 1000000);
160850161665
return 1;
@@ -160858,23 +161673,14 @@
160858161673
** lock on VFS file pFile.
160859161674
**
160860161675
** If this routine returns non-zero, the lock is retried. If it
160861161676
** returns 0, the operation aborts with an SQLITE_BUSY error.
160862161677
*/
160863
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
161678
+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
160864161679
int rc;
160865161680
if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
160866
- if( p->bExtraFileArg ){
160867
- /* Add an extra parameter with the pFile pointer to the end of the
160868
- ** callback argument list */
160869
- int (*xTra)(void*,int,sqlite3_file*);
160870
- xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
160871
- rc = xTra(p->pBusyArg, p->nBusy, pFile);
160872
- }else{
160873
- /* Legacy style busy handler callback */
160874
- rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
160875
- }
161681
+ rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
160876161682
if( rc==0 ){
160877161683
p->nBusy = -1;
160878161684
}else{
160879161685
p->nBusy++;
160880161686
}
@@ -160895,11 +161701,10 @@
160895161701
#endif
160896161702
sqlite3_mutex_enter(db->mutex);
160897161703
db->busyHandler.xBusyHandler = xBusy;
160898161704
db->busyHandler.pBusyArg = pArg;
160899161705
db->busyHandler.nBusy = 0;
160900
- db->busyHandler.bExtraFileArg = 0;
160901161706
db->busyTimeout = 0;
160902161707
sqlite3_mutex_leave(db->mutex);
160903161708
return SQLITE_OK;
160904161709
}
160905161710
@@ -160946,11 +161751,10 @@
160946161751
#endif
160947161752
if( ms>0 ){
160948161753
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
160949161754
(void*)db);
160950161755
db->busyTimeout = ms;
160951
- db->busyHandler.bExtraFileArg = 1;
160952161756
}else{
160953161757
sqlite3_busy_handler(db, 0, 0);
160954161758
}
160955161759
return SQLITE_OK;
160956161760
}
@@ -162272,10 +163076,11 @@
162272163076
sqlite3 *db; /* Store allocated handle here */
162273163077
int rc; /* Return code */
162274163078
int isThreadsafe; /* True for threadsafe connections */
162275163079
char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
162276163080
char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
163081
+ int i; /* Loop counter */
162277163082
162278163083
#ifdef SQLITE_ENABLE_API_ARMOR
162279163084
if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
162280163085
#endif
162281163086
*ppDb = 0;
@@ -162420,10 +163225,13 @@
162420163225
| SQLITE_EnableQPSG
162421163226
#endif
162422163227
#if defined(SQLITE_DEFAULT_DEFENSIVE)
162423163228
| SQLITE_Defensive
162424163229
#endif
163230
+#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE)
163231
+ | SQLITE_LegacyAlter
163232
+#endif
162425163233
;
162426163234
sqlite3HashInit(&db->aCollSeq);
162427163235
#ifndef SQLITE_OMIT_VIRTUALTABLE
162428163236
sqlite3HashInit(&db->aModule);
162429163237
#endif
@@ -162512,18 +163320,15 @@
162512163320
*/
162513163321
sqlite3Error(db, SQLITE_OK);
162514163322
sqlite3RegisterPerConnectionBuiltinFunctions(db);
162515163323
rc = sqlite3_errcode(db);
162516163324
162517
-#ifdef SQLITE_ENABLE_FTS5
162518
- /* Register any built-in FTS5 module before loading the automatic
162519
- ** extensions. This allows automatic extensions to register FTS5
162520
- ** tokenizers and auxiliary functions. */
162521
- if( !db->mallocFailed && rc==SQLITE_OK ){
162522
- rc = sqlite3Fts5Init(db);
162523
- }
162524
-#endif
163325
+
163326
+ /* Load compiled-in extensions */
163327
+ for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
163328
+ rc = sqlite3BuiltinExtensions[i](db);
163329
+ }
162525163330
162526163331
/* Load automatic extensions - extensions that have been registered
162527163332
** using the sqlite3_automatic_extension() API.
162528163333
*/
162529163334
if( rc==SQLITE_OK ){
@@ -162532,66 +163337,10 @@
162532163337
if( rc!=SQLITE_OK ){
162533163338
goto opendb_out;
162534163339
}
162535163340
}
162536163341
162537
-#ifdef SQLITE_ENABLE_FTS1
162538
- if( !db->mallocFailed ){
162539
- extern int sqlite3Fts1Init(sqlite3*);
162540
- rc = sqlite3Fts1Init(db);
162541
- }
162542
-#endif
162543
-
162544
-#ifdef SQLITE_ENABLE_FTS2
162545
- if( !db->mallocFailed && rc==SQLITE_OK ){
162546
- extern int sqlite3Fts2Init(sqlite3*);
162547
- rc = sqlite3Fts2Init(db);
162548
- }
162549
-#endif
162550
-
162551
-#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
162552
- if( !db->mallocFailed && rc==SQLITE_OK ){
162553
- rc = sqlite3Fts3Init(db);
162554
- }
162555
-#endif
162556
-
162557
-#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
162558
- if( !db->mallocFailed && rc==SQLITE_OK ){
162559
- rc = sqlite3IcuInit(db);
162560
- }
162561
-#endif
162562
-
162563
-#ifdef SQLITE_ENABLE_RTREE
162564
- if( !db->mallocFailed && rc==SQLITE_OK){
162565
- rc = sqlite3RtreeInit(db);
162566
- }
162567
-#endif
162568
-
162569
-#ifdef SQLITE_ENABLE_DBPAGE_VTAB
162570
- if( !db->mallocFailed && rc==SQLITE_OK){
162571
- rc = sqlite3DbpageRegister(db);
162572
- }
162573
-#endif
162574
-
162575
-#ifdef SQLITE_ENABLE_DBSTAT_VTAB
162576
- if( !db->mallocFailed && rc==SQLITE_OK){
162577
- rc = sqlite3DbstatRegister(db);
162578
- }
162579
-#endif
162580
-
162581
-#ifdef SQLITE_ENABLE_JSON1
162582
- if( !db->mallocFailed && rc==SQLITE_OK){
162583
- rc = sqlite3Json1Init(db);
162584
- }
162585
-#endif
162586
-
162587
-#ifdef SQLITE_ENABLE_STMTVTAB
162588
- if( !db->mallocFailed && rc==SQLITE_OK){
162589
- rc = sqlite3StmtVtabInit(db);
162590
- }
162591
-#endif
162592
-
162593163342
#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
162594163343
/* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
162595163344
** option gives access to internal functions by default.
162596163345
** Testing use only!!! */
162597163346
db->mDbFlags |= DBFLAG_InternalFunc;
@@ -163076,11 +163825,11 @@
163076163825
*(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
163077163826
rc = SQLITE_OK;
163078163827
}else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
163079163828
int iNew = *(int*)pArg;
163080163829
*(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
163081
- if( iNew>=0 && iNew<=254 ){
163830
+ if( iNew>=0 && iNew<=255 ){
163082163831
sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
163083163832
}
163084163833
rc = SQLITE_OK;
163085163834
}else{
163086163835
rc = sqlite3OsFileControl(fd, op, pArg);
@@ -165357,10 +166106,11 @@
165357166106
SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
165358166107
SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
165359166108
SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
165360166109
SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
165361166110
SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
166111
+SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut);
165362166112
165363166113
/* fts3_tokenizer.c */
165364166114
SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
165365166115
SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
165366166116
SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -166088,10 +166838,26 @@
166088166838
fts3Appendf(pRc, &zRet, ", ?");
166089166839
}
166090166840
sqlite3_free(zFree);
166091166841
return zRet;
166092166842
}
166843
+
166844
+/*
166845
+** Buffer z contains a positive integer value encoded as utf-8 text.
166846
+** Decode this value and store it in *pnOut, returning the number of bytes
166847
+** consumed. If an overflow error occurs return a negative value.
166848
+*/
166849
+SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut){
166850
+ u64 iVal = 0;
166851
+ int i;
166852
+ for(i=0; z[i]>='0' && z[i]<='9'; i++){
166853
+ iVal = iVal*10 + (z[i] - '0');
166854
+ if( iVal>0x7FFFFFFF ) return -1;
166855
+ }
166856
+ *pnOut = (int)iVal;
166857
+ return i;
166858
+}
166093166859
166094166860
/*
166095166861
** This function interprets the string at (*pp) as a non-negative integer
166096166862
** value. It reads the integer and sets *pnOut to the value read, then
166097166863
** sets *pp to point to the byte immediately following the last byte of
@@ -166104,23 +166870,21 @@
166104166870
**
166105166871
** This function is used when parsing the "prefix=" FTS4 parameter.
166106166872
*/
166107166873
static int fts3GobbleInt(const char **pp, int *pnOut){
166108166874
const int MAX_NPREFIX = 10000000;
166109
- const char *p; /* Iterator pointer */
166110166875
int nInt = 0; /* Output value */
166111
-
166112
- for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
166113
- nInt = nInt * 10 + (p[0] - '0');
166114
- if( nInt>MAX_NPREFIX ){
166115
- nInt = 0;
166116
- break;
166117
- }
166118
- }
166119
- if( p==*pp ) return SQLITE_ERROR;
166876
+ int nByte;
166877
+ nByte = sqlite3Fts3ReadInt(*pp, &nInt);
166878
+ if( nInt>MAX_NPREFIX ){
166879
+ nInt = 0;
166880
+ }
166881
+ if( nByte==0 ){
166882
+ return SQLITE_ERROR;
166883
+ }
166120166884
*pnOut = nInt;
166121
- *pp = p;
166885
+ *pp += nByte;
166122166886
return SQLITE_OK;
166123166887
}
166124166888
166125166889
/*
166126166890
** This function is called to allocate an array of Fts3Index structures
@@ -167298,11 +168062,13 @@
167298168062
static void fts3ReadNextPos(
167299168063
char **pp, /* IN/OUT: Pointer into position-list buffer */
167300168064
sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
167301168065
){
167302168066
if( (**pp)&0xFE ){
167303
- fts3GetDeltaVarint(pp, pi);
168067
+ int iVal;
168068
+ *pp += fts3GetVarint32((*pp), &iVal);
168069
+ *pi += iVal;
167304168070
*pi -= 2;
167305168071
}else{
167306168072
*pi = POSITION_LIST_END;
167307168073
}
167308168074
}
@@ -172198,14 +172964,11 @@
172198172964
172199172965
/* If this is a "NEAR" keyword, check for an explicit nearness. */
172200172966
if( pKey->eType==FTSQUERY_NEAR ){
172201172967
assert( nKey==4 );
172202172968
if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
172203
- nNear = 0;
172204
- for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
172205
- nNear = nNear * 10 + (zInput[nKey] - '0');
172206
- }
172969
+ nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
172207172970
}
172208172971
}
172209172972
172210172973
/* At this point this is probably a keyword. But for that to be true,
172211172974
** the next byte must contain either whitespace, an open or close
@@ -178384,25 +179147,25 @@
178384179147
){
178385179148
const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
178386179149
if( zText ){
178387179150
int i;
178388179151
int iMul = 1;
178389
- i64 iVal = 0;
179152
+ u64 iVal = 0;
178390179153
for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
178391179154
iVal = iVal*10 + (zText[i] - '0');
178392179155
}
178393
- *piEndBlock = iVal;
179156
+ *piEndBlock = (i64)iVal;
178394179157
while( zText[i]==' ' ) i++;
178395179158
iVal = 0;
178396179159
if( zText[i]=='-' ){
178397179160
i++;
178398179161
iMul = -1;
178399179162
}
178400179163
for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
178401179164
iVal = iVal*10 + (zText[i] - '0');
178402179165
}
178403
- *pnByte = (iVal * (i64)iMul);
179166
+ *pnByte = ((i64)iVal * (i64)iMul);
178404179167
}
178405179168
}
178406179169
178407179170
178408179171
/*
@@ -223901,11 +224664,11 @@
223901224664
int nArg, /* Number of args */
223902224665
sqlite3_value **apUnused /* Function arguments */
223903224666
){
223904224667
assert( nArg==0 );
223905224668
UNUSED_PARAM2(nArg, apUnused);
223906
- sqlite3_result_text(pCtx, "fts5: 2020-03-03 20:04:29 bd94d7d052734460904c687756231f8aa243a2252f07f742dd1e437aa940f536", -1, SQLITE_TRANSIENT);
224669
+ sqlite3_result_text(pCtx, "fts5: 2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff", -1, SQLITE_TRANSIENT);
223907224670
}
223908224671
223909224672
/*
223910224673
** Return true if zName is the extension on one of the shadow tables used
223911224674
** by this module.
@@ -228552,11 +229315,12 @@
228552229315
}
228553229316
case STMT_COLUMN_BUSY: {
228554229317
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
228555229318
break;
228556229319
}
228557
- case STMT_COLUMN_MEM: {
229320
+ default: {
229321
+ assert( i==STMT_COLUMN_MEM );
228558229322
i = SQLITE_STMTSTATUS_MEMUSED +
228559229323
STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
228560229324
/* Fall thru */
228561229325
}
228562229326
case STMT_COLUMN_NSCAN:
@@ -228683,12 +229447,12 @@
228683229447
}
228684229448
#endif /* SQLITE_CORE */
228685229449
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
228686229450
228687229451
/************** End of stmt.c ************************************************/
228688
-#if __LINE__!=228688
229452
+#if __LINE__!=229452
228689229453
#undef SQLITE_SOURCE_ID
228690
-#define SQLITE_SOURCE_ID "2020-04-20 17:35:32 2fc80ef16ce5878311ab88a0c64631813572ffbb71f75363b4619c9667e0alt2"
229454
+#define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f96alt2"
228691229455
#endif
228692229456
/* Return the source-id for this library */
228693229457
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
228694229458
/************************** End of sqlite3.c ******************************/
228695229459
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -216,10 +216,13 @@
216 "ENABLE_ATOMIC_WRITE",
217 #endif
218 #if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
219 "ENABLE_BATCH_ATOMIC_WRITE",
220 #endif
 
 
 
221 #if SQLITE_ENABLE_CEROD
222 "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
223 #endif
224 #if SQLITE_ENABLE_COLUMN_METADATA
225 "ENABLE_COLUMN_METADATA",
@@ -534,13 +537,10 @@
534 "OMIT_BETWEEN_OPTIMIZATION",
535 #endif
536 #if SQLITE_OMIT_BLOB_LITERAL
537 "OMIT_BLOB_LITERAL",
538 #endif
539 #if SQLITE_OMIT_BTREECOUNT
540 "OMIT_BTREECOUNT",
541 #endif
542 #if SQLITE_OMIT_CAST
543 "OMIT_CAST",
544 #endif
545 #if SQLITE_OMIT_CHECK
546 "OMIT_CHECK",
@@ -1162,11 +1162,11 @@
1162 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1163 ** [sqlite_version()] and [sqlite_source_id()].
1164 */
1165 #define SQLITE_VERSION "3.32.0"
1166 #define SQLITE_VERSION_NUMBER 3032000
1167 #define SQLITE_SOURCE_ID "2020-04-20 17:35:32 2fc80ef16ce5878311ab88a0c64631813572ffbb71f75363b4619c9667e0926b"
1168
1169 /*
1170 ** CAPI3REF: Run-Time Library Version Numbers
1171 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1172 **
@@ -1336,30 +1336,26 @@
1336 ** for the [sqlite3] object.
1337 ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
1338 ** the [sqlite3] object is successfully destroyed and all associated
1339 ** resources are deallocated.
1340 **
 
 
 
 
1341 ** ^If the database connection is associated with unfinalized prepared
1342 ** statements or unfinished sqlite3_backup objects then sqlite3_close()
1343 ** will leave the database connection open and return [SQLITE_BUSY].
1344 ** ^If sqlite3_close_v2() is called with unfinalized prepared statements
1345 ** and/or unfinished sqlite3_backups, then the database connection becomes
1346 ** an unusable "zombie" which will automatically be deallocated when the
1347 ** last prepared statement is finalized or the last sqlite3_backup is
1348 ** finished. The sqlite3_close_v2() interface is intended for use with
1349 ** host languages that are garbage collected, and where the order in which
1350 ** destructors are called is arbitrary.
1351 **
1352 ** Applications should [sqlite3_finalize | finalize] all [prepared statements],
1353 ** [sqlite3_blob_close | close] all [BLOB handles], and
1354 ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
1355 ** with the [sqlite3] object prior to attempting to close the object. ^If
1356 ** sqlite3_close_v2() is called on a [database connection] that still has
1357 ** outstanding [prepared statements], [BLOB handles], and/or
1358 ** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
1359 ** of resources is deferred until all [prepared statements], [BLOB handles],
1360 ** and [sqlite3_backup] objects are also destroyed.
1361 **
1362 ** ^If an [sqlite3] object is destroyed while a transaction is open,
1363 ** the transaction is automatically rolled back.
1364 **
1365 ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
@@ -1544,22 +1540,25 @@
1544 #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
1545 #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
1546 #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
1547 #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
1548 #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
 
1549 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
1550 #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
1551 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
1552 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
 
1553 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
1554 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
1555 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
1556 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
1557 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
1558 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
1559 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
1560 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
 
1561 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
1562 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
1563 #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
1564 #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
1565 #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
@@ -2150,10 +2149,15 @@
2150 ** a single attached database that occur due to other database connections,
2151 ** but omits changes implemented by the database connection on which it is
2152 ** called. This file control is the only mechanism to detect changes that
2153 ** happen either internally or externally and that are associated with
2154 ** a particular attached database.
 
 
 
 
 
2155 **
2156 ** <li>[[SQLITE_FCNTL_CKPT_DONE]]
2157 ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
2158 ** in wal mode after the client has finished copying pages from the wal
2159 ** file to the database file, but before the *-shm file is updated to
@@ -2195,10 +2199,11 @@
2195 #define SQLITE_FCNTL_LOCK_TIMEOUT 34
2196 #define SQLITE_FCNTL_DATA_VERSION 35
2197 #define SQLITE_FCNTL_SIZE_LIMIT 36
2198 #define SQLITE_FCNTL_CKPT_DONE 37
2199 #define SQLITE_FCNTL_RESERVE_BYTES 38
 
2200
2201 /* deprecated names */
2202 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
2203 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
2204 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -4573,12 +4578,23 @@
4573 **
4574 ** These are utility routines, useful to [VFS|custom VFS implementations],
4575 ** that check if a database file was a URI that contained a specific query
4576 ** parameter, and if so obtains the value of that query parameter.
4577 **
4578 ** If F is the database filename pointer passed into the xOpen() method of
4579 ** a VFS implementation or it is the return value of [sqlite3_db_filename()]
 
 
 
 
 
 
 
 
 
 
 
4580 ** and if P is the name of the query parameter, then
4581 ** sqlite3_uri_parameter(F,P) returns the value of the P
4582 ** parameter if it exists or a NULL pointer if P does not appear as a
4583 ** query parameter on F. If P is a query parameter of F and it
4584 ** has no explicit value, then sqlite3_uri_parameter(F,P) returns
@@ -4657,10 +4673,29 @@
4657 */
4658 SQLITE_API const char *sqlite3_filename_database(const char*);
4659 SQLITE_API const char *sqlite3_filename_journal(const char*);
4660 SQLITE_API const char *sqlite3_filename_wal(const char*);
4661
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4662 /*
4663 ** CAPI3REF: Create and Destroy VFS Filenames
4664 **
4665 ** These interfces are provided for use by [VFS shim] implementations and
4666 ** are not useful outside of that context.
@@ -4691,11 +4726,11 @@
4691 ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
4692 ** be NULL pointers, though they can be empty strings.
4693 **
4694 ** The sqlite3_free_filename(Y) routine releases a memory allocation
4695 ** previously obtained from sqlite3_create_filename(). Invoking
4696 ** sqlite3_free_filename(Y) is a NULL pointer is a harmless no-op.
4697 **
4698 ** If the Y parameter to sqlite3_free_filename(Y) is anything other
4699 ** than a NULL pointer or a pointer previously acquired from
4700 ** sqlite3_create_filename(), then bad things such as heap
4701 ** corruption or segfaults may occur. The value Y should be
@@ -14502,11 +14537,10 @@
14502 typedef struct BusyHandler BusyHandler;
14503 struct BusyHandler {
14504 int (*xBusyHandler)(void *,int); /* The busy callback */
14505 void *pBusyArg; /* First arg to busy callback */
14506 int nBusy; /* Incremented with each busy call */
14507 u8 bExtraFileArg; /* Include sqlite3_file as callback arg */
14508 };
14509
14510 /*
14511 ** Name of the master database table. The master database table
14512 ** is a special table that holds the names and attributes of all
@@ -15022,13 +15056,11 @@
15022 #ifndef NDEBUG
15023 SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
15024 #endif
15025 SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
15026
15027 #ifndef SQLITE_OMIT_BTREECOUNT
15028 SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
15029 #endif
15030
15031 #ifdef SQLITE_TEST
15032 SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
15033 SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
15034 #endif
@@ -15599,10 +15631,13 @@
15599
15600 SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
15601 SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
15602
15603 SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
 
 
 
15604
15605 /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
15606 ** each VDBE opcode.
15607 **
15608 ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
@@ -15884,17 +15919,25 @@
15884 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
15885 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
15886 SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
15887 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
15888 # ifdef SQLITE_ENABLE_SNAPSHOT
15889 SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
15890 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
15891 SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
15892 SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
15893 SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
15894 # endif
15895 #endif
 
 
 
 
 
 
 
 
15896
15897 #ifdef SQLITE_DIRECT_OVERFLOW_READ
15898 SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
15899 #endif
15900
@@ -15917,15 +15960,10 @@
15917 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
15918 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
15919 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
15920 SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
15921 SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
15922 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
15923 SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager);
15924 #else
15925 # define sqlite3PagerResetLockTimeout(X)
15926 #endif
15927
15928 /* Functions used to truncate the database file. */
15929 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
15930
15931 SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
@@ -16855,10 +16893,11 @@
16855 Hash aFunc; /* Hash table of connection functions */
16856 Hash aCollSeq; /* All collating sequences */
16857 BusyHandler busyHandler; /* Busy callback */
16858 Db aDbStatic[2]; /* Static space for the 2 default backends */
16859 Savepoint *pSavepoint; /* List of active savepoints */
 
16860 int busyTimeout; /* Busy handler timeout, in msec */
16861 int nSavepoint; /* Number of non-transaction savepoints */
16862 int nStatement; /* Number of nested statement-transactions */
16863 i64 nDeferredCons; /* Net deferred constraints this transaction. */
16864 i64 nDeferredImmCons; /* Net deferred immediate constraints */
@@ -19900,11 +19939,11 @@
19900 SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*);
19901 SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
19902 SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
19903 SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
19904 SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
19905 SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
19906 SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
19907 SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
19908 SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
19909 SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
19910 SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
@@ -20636,11 +20675,12 @@
20636 /*
20637 ** VDBE_DISPLAY_P4 is true or false depending on whether or not the
20638 ** "explain" P4 display logic is enabled.
20639 */
20640 #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
20641 || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
 
20642 # define VDBE_DISPLAY_P4 1
20643 #else
20644 # define VDBE_DISPLAY_P4 0
20645 #endif
20646
@@ -21101,11 +21141,18 @@
21101
21102 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
21103 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
21104 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
21105 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
21106 #ifndef SQLITE_OMIT_EXPLAIN
 
 
 
 
 
 
 
21107 SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
21108 #endif
21109 SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
21110 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
21111 SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -21143,11 +21190,11 @@
21143 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
21144 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
21145 #ifndef SQLITE_OMIT_WINDOWFUNC
21146 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
21147 #endif
21148 #ifndef SQLITE_OMIT_EXPLAIN
21149 SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
21150 #endif
21151 SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
21152 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
21153 SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
@@ -27316,11 +27363,11 @@
27316 if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
27317 n = mem0.hardLimit;
27318 }
27319 mem0.alarmThreshold = n;
27320 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
27321 mem0.nearlyFull = (n>0 && n<=nUsed);
27322 sqlite3_mutex_leave(mem0.mutex);
27323 excess = sqlite3_memory_used() - n;
27324 if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
27325 return priorLimit;
27326 }
@@ -27384,11 +27431,11 @@
27384 ** Return true if the heap is currently under memory pressure - in other
27385 ** words if the amount of heap used is close to the limit set by
27386 ** sqlite3_soft_heap_limit().
27387 */
27388 SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
27389 return mem0.nearlyFull;
27390 }
27391
27392 /*
27393 ** Deinitialize the memory allocation subsystem.
27394 */
@@ -27448,21 +27495,21 @@
27448
27449 sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
27450 if( mem0.alarmThreshold>0 ){
27451 sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
27452 if( nUsed >= mem0.alarmThreshold - nFull ){
27453 mem0.nearlyFull = 1;
27454 sqlite3MallocAlarm(nFull);
27455 if( mem0.hardLimit ){
27456 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
27457 if( nUsed >= mem0.hardLimit - nFull ){
27458 *pp = 0;
27459 return;
27460 }
27461 }
27462 }else{
27463 mem0.nearlyFull = 0;
27464 }
27465 }
27466 p = sqlite3GlobalConfig.m.xMalloc(nFull);
27467 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
27468 if( p==0 && mem0.alarmThreshold>0 ){
@@ -27687,14 +27734,16 @@
27687 if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
27688 mem0.alarmThreshold-nDiff ){
27689 sqlite3MallocAlarm(nDiff);
27690 }
27691 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
 
27692 if( pNew==0 && mem0.alarmThreshold>0 ){
27693 sqlite3MallocAlarm((int)nBytes);
27694 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
27695 }
 
27696 if( pNew ){
27697 nNew = sqlite3MallocSize(pNew);
27698 sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
27699 }
27700 sqlite3_mutex_leave(mem0.mutex);
@@ -34928,20 +34977,21 @@
34928 static int osSetPosixAdvisoryLock(
34929 int h, /* The file descriptor on which to take the lock */
34930 struct flock *pLock, /* The description of the lock */
34931 unixFile *pFile /* Structure holding timeout value */
34932 ){
 
34933 int rc = osFcntl(h,F_SETLK,pLock);
34934 while( rc<0 && pFile->iBusyTimeout>0 ){
34935 /* On systems that support some kind of blocking file lock with a timeout,
34936 ** make appropriate changes here to invoke that blocking file lock. On
34937 ** generic posix, however, there is no such API. So we simply try the
34938 ** lock once every millisecond until either the timeout expires, or until
34939 ** the lock is obtained. */
34940 usleep(1000);
34941 rc = osFcntl(h,F_SETLK,pLock);
34942 pFile->iBusyTimeout--;
34943 }
34944 return rc;
34945 }
34946 #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
34947
@@ -37679,17 +37729,24 @@
37679
37680 /* Locks are within range */
37681 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
37682
37683 if( pShmNode->hShm>=0 ){
 
37684 /* Initialize the locking parameters */
37685 f.l_type = lockType;
37686 f.l_whence = SEEK_SET;
37687 f.l_start = ofst;
37688 f.l_len = n;
37689 rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
37690 rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
 
 
 
 
 
 
37691 }
37692
37693 /* Update the global lock state and do debug tracing */
37694 #ifdef SQLITE_DEBUG
37695 { u16 mask;
@@ -38182,26 +38239,27 @@
38182 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
38183 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
38184 assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
38185 assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
38186
38187 /* Check that, if this to be a blocking lock, that locks have been
38188 ** obtained in the following order.
38189 **
38190 ** 1. Checkpointer lock (ofst==1).
38191 ** 2. Recover lock (ofst==2).
38192 ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
38193 ** 4. Write lock (ofst==0).
38194 **
38195 ** In other words, if this is a blocking lock, none of the locks that
38196 ** occur later in the above list than the lock being obtained may be
38197 ** held. */
38198 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
38199 assert( pDbFd->iBusyTimeout==0
38200 || (flags & SQLITE_SHM_UNLOCK) || ofst==0
38201 || ((p->exclMask|p->sharedMask)&~((1<<ofst)-2))==0
38202 );
 
 
38203 #endif
38204
38205 mask = (1<<(ofst+n)) - (1<<ofst);
38206 assert( n>1 || mask==(1<<ofst) );
38207 sqlite3_mutex_enter(pShmNode->pShmMutex);
@@ -51505,10 +51563,15 @@
51505 SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
51506 #endif
51507
51508 /* Return the sqlite3_file object for the WAL file */
51509 SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
 
 
 
 
 
51510
51511 #endif /* ifndef SQLITE_OMIT_WAL */
51512 #endif /* SQLITE_WAL_H */
51513
51514 /************** End of wal.h *************************************************/
@@ -54026,13 +54089,16 @@
54026 }
54027 if( exists ){
54028 /* One of the journals pointed to by the master journal exists.
54029 ** Open it and check if it points at the master journal. If
54030 ** so, return without deleting the master journal file.
 
 
 
54031 */
54032 int c;
54033 int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
54034 rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
54035 if( rc!=SQLITE_OK ){
54036 goto delmaster_out;
54037 }
54038
@@ -56232,10 +56298,11 @@
56232 ** Pager object (sizeof(Pager) bytes)
56233 ** PCache object (sqlite3PcacheSize() bytes)
56234 ** Database file handle (pVfs->szOsFile bytes)
56235 ** Sub-journal file handle (journalFileSize bytes)
56236 ** Main journal file handle (journalFileSize bytes)
 
56237 ** \0\0\0\0 database prefix (4 bytes)
56238 ** Database file name (nPathname+1 bytes)
56239 ** URI query parameters (nUriByte bytes)
56240 ** Journal filename (nPathname+8+1 bytes)
56241 ** WAL filename (nPathname+4+1 bytes)
@@ -56271,10 +56338,11 @@
56271 pPtr = (u8 *)sqlite3MallocZero(
56272 ROUND8(sizeof(*pPager)) + /* Pager structure */
56273 ROUND8(pcacheSize) + /* PCache object */
56274 ROUND8(pVfs->szOsFile) + /* The main db file */
56275 journalFileSize * 2 + /* The two journal files */
 
56276 4 + /* Database prefix */
56277 nPathname + 1 + /* database filename */
56278 nUriByte + /* query parameters */
56279 nPathname + 8 + 1 + /* Journal filename */
56280 #ifndef SQLITE_OMIT_WAL
@@ -56291,10 +56359,11 @@
56291 pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
56292 pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
56293 pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
56294 pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
56295 assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
 
56296
56297 /* Fill in the Pager.zFilename and pPager.zQueryParam fields */
56298 pPtr += 4; /* Skip zero prefix */
56299 pPager->zFilename = (char*)pPtr;
56300 if( nPathname>0 ){
@@ -56491,10 +56560,23 @@
56491
56492 *ppPager = pPager;
56493 return SQLITE_OK;
56494 }
56495
 
 
 
 
 
 
 
 
 
 
 
 
 
56496
56497
56498 /*
56499 ** This function is called after transitioning from PAGER_UNLOCK to
56500 ** PAGER_SHARED state. It tests if there is a hot journal present in
@@ -57176,11 +57258,10 @@
57176 Pager *pPager;
57177 assert( pPg!=0 );
57178 assert( pPg->pgno==1 );
57179 assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
57180 pPager = pPg->pPager;
57181 sqlite3PagerResetLockTimeout(pPager);
57182 sqlite3PcacheRelease(pPg);
57183 pagerUnlockIfUnused(pPager);
57184 }
57185
57186 /*
@@ -58469,20 +58550,10 @@
58469 */
58470 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
58471 return pPager->fd;
58472 }
58473
58474 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
58475 /*
58476 ** Reset the lock timeout for pager.
58477 */
58478 SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){
58479 int x = 0;
58480 sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
58481 }
58482 #endif
58483
58484 /*
58485 ** Return the file handle for the journal file (if it exists).
58486 ** This will be either the rollback journal or the WAL file.
58487 */
58488 SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
@@ -58892,11 +58963,10 @@
58892 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
58893 pPager->pBusyHandlerArg,
58894 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
58895 pnLog, pnCkpt
58896 );
58897 sqlite3PagerResetLockTimeout(pPager);
58898 }
58899 return rc;
58900 }
58901
58902 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
@@ -59057,11 +59127,35 @@
59057 }
59058 }
59059 return rc;
59060 }
59061
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59062
 
 
 
 
 
 
 
 
 
 
59063
59064 #ifdef SQLITE_ENABLE_SNAPSHOT
59065 /*
59066 ** If this is a WAL database, obtain a snapshot handle for the snapshot
59067 ** currently open. Otherwise, return an error.
@@ -59077,11 +59171,14 @@
59077 /*
59078 ** If this is a WAL database, store a pointer to pSnapshot. Next time a
59079 ** read transaction is opened, attempt to read from the snapshot it
59080 ** identifies. If this is not a WAL database, return an error.
59081 */
59082 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
 
 
 
59083 int rc = SQLITE_OK;
59084 if( pPager->pWal ){
59085 sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
59086 }else{
59087 rc = SQLITE_ERROR;
@@ -59622,10 +59719,13 @@
59622 u8 lockError; /* True if a locking error has occurred */
59623 #endif
59624 #ifdef SQLITE_ENABLE_SNAPSHOT
59625 WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
59626 #endif
 
 
 
59627 };
59628
59629 /*
59630 ** Candidate values for Wal.exclusiveMode.
59631 */
@@ -59995,11 +60095,11 @@
59995 if( pWal->exclusiveMode ) return SQLITE_OK;
59996 rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
59997 SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
59998 WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
59999 walLockName(lockIdx), rc ? "failed" : "ok"));
60000 VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
60001 return rc;
60002 }
60003 static void walUnlockShared(Wal *pWal, int lockIdx){
60004 if( pWal->exclusiveMode ) return;
60005 (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
@@ -60011,11 +60111,11 @@
60011 if( pWal->exclusiveMode ) return SQLITE_OK;
60012 rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
60013 SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
60014 WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
60015 walLockName(lockIdx), n, rc ? "failed" : "ok"));
60016 VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
60017 return rc;
60018 }
60019 static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
60020 if( pWal->exclusiveMode ) return;
60021 (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
@@ -60283,15 +60383,10 @@
60283 int rc; /* Return Code */
60284 i64 nSize; /* Size of log file */
60285 u32 aFrameCksum[2] = {0, 0};
60286 int iLock; /* Lock offset to lock for checkpoint */
60287
60288 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
60289 int tmout = 0;
60290 sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
60291 #endif
60292
60293 /* Obtain an exclusive lock on all byte in the locking range not already
60294 ** locked by the caller. The caller is guaranteed to have locked the
60295 ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
60296 ** If successful, the same bytes that are locked here are unlocked before
60297 ** this function returns.
@@ -60835,10 +60930,93 @@
60835 p = 0;
60836 }
60837 *pp = p;
60838 return rc;
60839 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60840
60841 /*
60842 ** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
60843 ** n. If the attempt fails and parameter xBusy is not NULL, then it is a
60844 ** busy-handler function. Invoke it and retry the lock until either the
@@ -60853,10 +61031,16 @@
60853 ){
60854 int rc;
60855 do {
60856 rc = walLockExclusive(pWal, lockIdx, n);
60857 }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
 
 
 
 
 
 
60858 return rc;
60859 }
60860
60861 /*
60862 ** The cache of the wal-index header must be valid to call this function.
@@ -61023,10 +61207,11 @@
61023 ** about the eventual size of the db file to the VFS layer.
61024 */
61025 if( rc==SQLITE_OK ){
61026 i64 nReq = ((i64)mxPage * szPage);
61027 i64 nSize; /* Current size of database file */
 
61028 rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
61029 if( rc==SQLITE_OK && nSize<nReq ){
61030 sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
61031 }
61032 }
@@ -61050,10 +61235,11 @@
61050 iOffset = (iDbpage-1)*(i64)szPage;
61051 testcase( IS_BIG_INT(iOffset) );
61052 rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
61053 if( rc!=SQLITE_OK ) break;
61054 }
 
61055
61056 /* If work was actually accomplished... */
61057 if( rc==SQLITE_OK ){
61058 if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
61059 i64 szDb = pWal->hdr.nPage*(i64)szPage;
@@ -61061,14 +61247,10 @@
61061 rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
61062 if( rc==SQLITE_OK ){
61063 rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
61064 }
61065 }
61066 if( rc==SQLITE_OK ){
61067 rc = sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
61068 if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
61069 }
61070 if( rc==SQLITE_OK ){
61071 pInfo->nBackfill = mxSafeFrame;
61072 }
61073 }
61074
@@ -61334,32 +61516,36 @@
61334 badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
61335
61336 /* If the first attempt failed, it might have been due to a race
61337 ** with a writer. So get a WRITE lock and try again.
61338 */
61339 assert( badHdr==0 || pWal->writeLock==0 );
61340 if( badHdr ){
61341 if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
61342 if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
61343 walUnlockShared(pWal, WAL_WRITE_LOCK);
61344 rc = SQLITE_READONLY_RECOVERY;
61345 }
61346 }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
61347 pWal->writeLock = 1;
61348 if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
61349 badHdr = walIndexTryHdr(pWal, pChanged);
61350 if( badHdr ){
61351 /* If the wal-index header is still malformed even while holding
61352 ** a WRITE lock, it can only mean that the header is corrupted and
61353 ** needs to be reconstructed. So run recovery to do exactly that.
61354 */
61355 rc = walIndexRecover(pWal);
61356 *pChanged = 1;
61357 }
61358 }
61359 pWal->writeLock = 0;
61360 walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
 
 
 
 
 
61361 }
61362 }
61363
61364 /* If the header is read successfully, check the version number to make
61365 ** sure the wal-index was not constructed with some future format that
@@ -61907,26 +62093,38 @@
61907 ** needs to be flushed.
61908 */
61909 SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
61910 int rc; /* Return code */
61911 int cnt = 0; /* Number of TryBeginRead attempts */
61912 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61913 int tmout = 0;
61914 #endif
61915
61916 #ifdef SQLITE_ENABLE_SNAPSHOT
61917 int bChanged = 0;
61918 WalIndexHdr *pSnapshot = pWal->pSnapshot;
61919 if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
61920 bChanged = 1;
61921 }
61922 #endif
61923
61924 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61925 /* Disable blocking locks. They are not useful when trying to open a
61926 ** read-transaction, and blocking may cause deadlock anyway. */
61927 sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
 
 
 
 
 
 
 
 
 
 
 
 
 
61928 #endif
61929
61930 do{
61931 rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
61932 }while( rc==WAL_RETRY );
@@ -61933,20 +62131,10 @@
61933 testcase( (rc&0xff)==SQLITE_BUSY );
61934 testcase( (rc&0xff)==SQLITE_IOERR );
61935 testcase( rc==SQLITE_PROTOCOL );
61936 testcase( rc==SQLITE_OK );
61937
61938 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61939 /* If they were disabled earlier and the read-transaction has been
61940 ** successfully opened, re-enable blocking locks. This is because the
61941 ** connection may attempt to upgrade to a write-transaction, which does
61942 ** benefit from using blocking locks. */
61943 if( rc==SQLITE_OK ){
61944 sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
61945 }
61946 #endif
61947
61948 #ifdef SQLITE_ENABLE_SNAPSHOT
61949 if( rc==SQLITE_OK ){
61950 if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
61951 /* At this point the client has a lock on an aReadMark[] slot holding
61952 ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
@@ -61964,52 +62152,46 @@
61964 volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
61965
61966 assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
61967 assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
61968
61969 /* It is possible that there is a checkpointer thread running
61970 ** concurrent with this code. If this is the case, it may be that the
61971 ** checkpointer has already determined that it will checkpoint
61972 ** snapshot X, where X is later in the wal file than pSnapshot, but
61973 ** has not yet set the pInfo->nBackfillAttempted variable to indicate
61974 ** its intent. To avoid the race condition this leads to, ensure that
61975 ** there is no checkpointer process by taking a shared CKPT lock
61976 ** before checking pInfo->nBackfillAttempted.
61977 **
61978 ** TODO: Does the aReadMark[] lock prevent a checkpointer from doing
61979 ** this already?
61980 */
61981 rc = walLockShared(pWal, WAL_CKPT_LOCK);
61982
61983 if( rc==SQLITE_OK ){
61984 /* Check that the wal file has not been wrapped. Assuming that it has
61985 ** not, also check that no checkpointer has attempted to checkpoint any
61986 ** frames beyond pSnapshot->mxFrame. If either of these conditions are
61987 ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
61988 ** with *pSnapshot and set *pChanged as appropriate for opening the
61989 ** snapshot. */
61990 if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
61991 && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
61992 ){
61993 assert( pWal->readLock>0 );
61994 memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
61995 *pChanged = bChanged;
61996 }else{
61997 rc = SQLITE_ERROR_SNAPSHOT;
61998 }
61999
62000 /* Release the shared CKPT lock obtained above. */
62001 walUnlockShared(pWal, WAL_CKPT_LOCK);
62002 pWal->minFrame = 1;
62003 }
62004
62005
62006 if( rc!=SQLITE_OK ){
62007 sqlite3WalEndReadTransaction(pWal);
62008 }
62009 }
62010 }
 
 
 
 
 
 
 
62011 #endif
62012 return rc;
62013 }
62014
62015 /*
@@ -62175,10 +62357,20 @@
62175 **
62176 ** There can only be a single writer active at a time.
62177 */
62178 SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
62179 int rc;
 
 
 
 
 
 
 
 
 
 
62180
62181 /* Cannot start a write transaction without first holding a read
62182 ** transaction. */
62183 assert( pWal->readLock>=0 );
62184 assert( pWal->writeLock==0 && pWal->iReCksum==0 );
@@ -62751,50 +62943,57 @@
62751 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
62752 assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
62753
62754 if( pWal->readOnly ) return SQLITE_READONLY;
62755 WALTRACE(("WAL%p: checkpoint begins\n", pWal));
 
 
 
 
 
62756
62757 /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
62758 ** "checkpoint" lock on the database file. */
 
 
 
 
 
 
62759 rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
62760 if( rc ){
62761 /* EVIDENCE-OF: R-10421-19736 If any other process is running a
62762 ** checkpoint operation at the same time, the lock cannot be obtained and
62763 ** SQLITE_BUSY is returned.
62764 ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
62765 ** it will not be invoked in this case.
62766 */
62767 testcase( rc==SQLITE_BUSY );
62768 testcase( xBusy!=0 );
62769 return rc;
62770 }
62771 pWal->ckptLock = 1;
62772
62773 /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
62774 ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
62775 ** file.
62776 **
62777 ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
62778 ** immediately, and a busy-handler is configured, it is invoked and the
62779 ** writer lock retried until either the busy-handler returns 0 or the
62780 ** lock is successfully obtained.
62781 */
62782 if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
62783 rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
62784 if( rc==SQLITE_OK ){
62785 pWal->writeLock = 1;
62786 }else if( rc==SQLITE_BUSY ){
62787 eMode2 = SQLITE_CHECKPOINT_PASSIVE;
62788 xBusy2 = 0;
62789 rc = SQLITE_OK;
62790 }
62791 }
62792
62793 /* Read the wal-index header. */
62794 if( rc==SQLITE_OK ){
 
62795 rc = walIndexReadHdr(pWal, &isChanged);
 
62796 if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
62797 sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
62798 }
62799 }
62800
@@ -62821,16 +63020,24 @@
62821 ** next time the pager opens a snapshot on this database it knows that
62822 ** the cache needs to be reset.
62823 */
62824 memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
62825 }
 
 
 
62826
62827 /* Release the locks. */
62828 sqlite3WalEndWriteTransaction(pWal);
62829 walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
62830 pWal->ckptLock = 0;
 
 
62831 WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
 
 
 
62832 return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
62833 }
62834
62835 /* Return the value to pass to a sqlite3_wal_hook callback, the
62836 ** number of frames in the WAL at the point of the last commit since
@@ -62943,11 +63150,14 @@
62943 return rc;
62944 }
62945
62946 /* Try to open on pSnapshot when the next read-transaction starts
62947 */
62948 SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
 
 
 
62949 pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
62950 }
62951
62952 /*
62953 ** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
@@ -63462,11 +63672,11 @@
63462 u8 incrVacuum; /* True if incr-vacuum is enabled */
63463 u8 bDoTruncate; /* True to truncate db on commit */
63464 #endif
63465 u8 inTransaction; /* Transaction state */
63466 u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
63467 u8 nReserveWanted; /* 1 more than desired number of extra bytes per page */
63468 u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
63469 u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
63470 u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
63471 u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */
63472 u16 minLeaf; /* Minimum local payload in a LEAFDATA table */
@@ -66356,12 +66566,11 @@
66356 */
66357 static int btreeInvokeBusyHandler(void *pArg){
66358 BtShared *pBt = (BtShared*)pArg;
66359 assert( pBt->db );
66360 assert( sqlite3_mutex_held(pBt->db->mutex) );
66361 return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
66362 sqlite3PagerFile(pBt->pPager));
66363 }
66364
66365 /*
66366 ** Open a database file.
66367 **
@@ -66908,23 +67117,21 @@
66908 ** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
66909 ** and autovacuum mode can no longer be changed.
66910 */
66911 SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
66912 int rc = SQLITE_OK;
 
66913 BtShared *pBt = p->pBt;
66914 assert( nReserve>=-1 && nReserve<=254 );
66915 sqlite3BtreeEnter(p);
66916 if( nReserve>=0 ){
66917 pBt->nReserveWanted = nReserve + 1;
66918 }
66919 if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
66920 sqlite3BtreeLeave(p);
66921 return SQLITE_READONLY;
66922 }
66923 if( nReserve<0 ){
66924 nReserve = pBt->pageSize - pBt->usableSize;
66925 }
66926 assert( nReserve>=0 && nReserve<=255 );
66927 if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
66928 ((pageSize-1)&pageSize)==0 ){
66929 assert( (pageSize & 7)==0 );
66930 assert( !pBt->pCursor );
@@ -66965,18 +67172,22 @@
66965
66966 /*
66967 ** Return the number of bytes of space at the end of every page that
66968 ** are intentually left unused. This is the "reserved" space that is
66969 ** sometimes used by extensions.
 
 
 
 
66970 */
66971 SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){
66972 int n;
66973 sqlite3BtreeEnter(p);
66974 n = ((int)p->pBt->nReserveWanted) - 1;
66975 if( n<0 ) n = sqlite3BtreeGetReserveNoMutex(p);
66976 sqlite3BtreeLeave(p);
66977 return n;
66978 }
66979
66980
66981 /*
66982 ** Set the maximum page count for a database if mxPage is positive.
@@ -67422,10 +67633,11 @@
67422 ** when A already has a read lock, we encourage A to give up and let B
67423 ** proceed.
67424 */
67425 SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
67426 BtShared *pBt = p->pBt;
 
67427 int rc = SQLITE_OK;
67428
67429 sqlite3BtreeEnter(p);
67430 btreeIntegrity(p);
67431
@@ -67437,11 +67649,11 @@
67437 goto trans_begun;
67438 }
67439 assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
67440
67441 if( (p->db->flags & SQLITE_ResetDatabase)
67442 && sqlite3PagerIsreadonly(pBt->pPager)==0
67443 ){
67444 pBt->btsFlags &= ~BTS_READ_ONLY;
67445 }
67446
67447 /* Write transactions are not possible on a read-only database */
@@ -67485,10 +67697,22 @@
67485 if( SQLITE_OK!=rc ) goto trans_begun;
67486
67487 pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
67488 if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
67489 do {
 
 
 
 
 
 
 
 
 
 
 
 
67490 /* Call lockBtree() until either pBt->pPage1 is populated or
67491 ** lockBtree() returns something other than SQLITE_OK. lockBtree()
67492 ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
67493 ** reading page 1 it discovers that the page-size of the database
67494 ** file is not pBt->pageSize. In this case lockBtree() will update
@@ -67498,11 +67722,11 @@
67498
67499 if( rc==SQLITE_OK && wrflag ){
67500 if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
67501 rc = SQLITE_READONLY;
67502 }else{
67503 rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
67504 if( rc==SQLITE_OK ){
67505 rc = newDatabase(pBt);
67506 }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
67507 /* if there was no transaction opened when this function was
67508 ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
@@ -67511,15 +67735,19 @@
67511 }
67512 }
67513 }
67514
67515 if( rc!=SQLITE_OK ){
 
67516 unlockBtreeIfUnused(pBt);
67517 }
67518 }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
67519 btreeInvokeBusyHandler(pBt) );
67520 sqlite3PagerResetLockTimeout(pBt->pPager);
 
 
 
67521
67522 if( rc==SQLITE_OK ){
67523 if( p->inTrans==TRANS_NONE ){
67524 pBt->nTransaction++;
67525 #ifndef SQLITE_OMIT_SHARED_CACHE
@@ -67567,11 +67795,11 @@
67567 if( wrflag ){
67568 /* This call makes sure that the pager has the correct number of
67569 ** open savepoints. If the second parameter is greater than 0 and
67570 ** the sub-journal is not already open, then it will be opened here.
67571 */
67572 rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
67573 }
67574 }
67575
67576 btreeIntegrity(p);
67577 sqlite3BtreeLeave(p);
@@ -71203,11 +71431,11 @@
71203
71204 /* Remove cells from the start and end of the page */
71205 assert( nCell>=0 );
71206 if( iOld<iNew ){
71207 int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
71208 if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
71209 memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
71210 nCell -= nShift;
71211 }
71212 if( iNewEnd < iOldEnd ){
71213 int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
@@ -73560,11 +73788,10 @@
73560 }
73561 sqlite3BtreeLeave(p);
73562 return rc;
73563 }
73564
73565 #ifndef SQLITE_OMIT_BTREECOUNT
73566 /*
73567 ** The first argument, pCur, is a cursor opened on some b-tree. Count the
73568 ** number of entries in the b-tree and write the result to *pnEntry.
73569 **
73570 ** SQLITE_OK is returned if the operation is successfully executed.
@@ -73633,11 +73860,10 @@
73633 }
73634
73635 /* An error has occurred. Return an error code. */
73636 return rc;
73637 }
73638 #endif
73639
73640 /*
73641 ** Return the pager associated with a BTree. This routine is used for
73642 ** testing and debugging only.
73643 */
@@ -74684,11 +74910,11 @@
74684 ** Attempt to set the page size of the destination to match the page size
74685 ** of the source.
74686 */
74687 static int setDestPgsz(sqlite3_backup *p){
74688 int rc;
74689 rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
74690 return rc;
74691 }
74692
74693 /*
74694 ** Check that there is no open read-transaction on the b-tree passed as the
@@ -78709,24 +78935,23 @@
78709 ** "PX" -> "r[X]"
78710 ** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
78711 ** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
78712 ** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
78713 */
78714 static int displayComment(
 
78715 const Op *pOp, /* The opcode to be commented */
78716 const char *zP4, /* Previously obtained value for P4 */
78717 char *zTemp, /* Write result here */
78718 int nTemp /* Space available in zTemp[] */
78719 ){
78720 const char *zOpName;
78721 const char *zSynopsis;
78722 int nOpName;
78723 int ii;
78724 char zAlt[50];
78725 StrAccum x;
78726 sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
78727
 
78728 zOpName = sqlite3OpcodeName(pOp->opcode);
78729 nOpName = sqlite3Strlen30(zOpName);
78730 if( zOpName[nOpName+1] ){
78731 int seenCom = 0;
78732 char c;
@@ -78789,14 +79014,16 @@
78789 sqlite3_str_appendf(&x, "; %s", pOp->zComment);
78790 }
78791 }else if( pOp->zComment ){
78792 sqlite3_str_appendall(&x, pOp->zComment);
78793 }
78794 sqlite3StrAccumFinish(&x);
78795 return x.nChar;
 
 
78796 }
78797 #endif /* SQLITE_DEBUG */
78798
78799 #if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
78800 /*
78801 ** Translate the P4.pExpr value for an OP_CursorHint opcode into text
78802 ** that can be displayed in the P4 column of EXPLAIN output.
@@ -78873,15 +79100,15 @@
78873 #if VDBE_DISPLAY_P4
78874 /*
78875 ** Compute a string that describes the P4 parameter for an opcode.
78876 ** Use zTemp for any required temporary buffer space.
78877 */
78878 static char *displayP4(Op *pOp, char *zTemp, int nTemp){
78879 char *zP4 = zTemp;
78880 StrAccum x;
78881 assert( nTemp>=20 );
78882 sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
78883 switch( pOp->p4type ){
78884 case P4_KEYINFO: {
78885 int j;
78886 KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
78887 assert( pKeyInfo->aSortFlags!=0 );
@@ -78961,40 +79188,36 @@
78961 int i;
78962 int *ai = pOp->p4.ai;
78963 int n = ai[0]; /* The first element of an INTARRAY is always the
78964 ** count of the number of elements to follow */
78965 for(i=1; i<=n; i++){
78966 sqlite3_str_appendf(&x, ",%d", ai[i]);
78967 }
78968 zTemp[0] = '[';
78969 sqlite3_str_append(&x, "]", 1);
78970 break;
78971 }
78972 case P4_SUBPROGRAM: {
78973 sqlite3_str_appendf(&x, "program");
78974 break;
78975 }
78976 case P4_DYNBLOB:
78977 case P4_ADVANCE: {
78978 zTemp[0] = 0;
78979 break;
78980 }
78981 case P4_TABLE: {
78982 sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
78983 break;
78984 }
78985 default: {
78986 zP4 = pOp->p4.z;
78987 if( zP4==0 ){
78988 zP4 = zTemp;
78989 zTemp[0] = 0;
78990 }
78991 }
78992 }
78993 sqlite3StrAccumFinish(&x);
78994 assert( zP4!=0 );
78995 return zP4;
 
 
78996 }
78997 #endif /* VDBE_DISPLAY_P4 */
78998
78999 /*
79000 ** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
@@ -79080,28 +79303,32 @@
79080 /*
79081 ** Print a single opcode. This routine is used for debugging only.
79082 */
79083 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
79084 char *zP4;
79085 char zPtr[50];
79086 char zCom[100];
79087 static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
79088 if( pOut==0 ) pOut = stdout;
79089 zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
 
79090 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
79091 displayComment(pOp, zP4, zCom, sizeof(zCom));
79092 #else
79093 zCom[0] = 0;
79094 #endif
79095 /* NB: The sqlite3OpcodeName() function is implemented by code created
79096 ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
79097 ** information from the vdbe.c source text */
79098 fprintf(pOut, zFormat1, pc,
79099 sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
79100 zCom
 
79101 );
79102 fflush(pOut);
 
 
79103 }
79104 #endif
79105
79106 /*
79107 ** Initialize an array of N Mem element.
@@ -79188,10 +79415,125 @@
79188 assert( sqlite3VdbeFrameIsValid(pFrame) );
79189 pFrame->pParent = pFrame->v->pDelFrame;
79190 pFrame->v->pDelFrame = pFrame;
79191 }
79192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79193
79194 /*
79195 ** Delete a VdbeFrame object and its contents. VdbeFrame objects are
79196 ** allocated by the OP_Program opcode in sqlite3VdbeExec().
79197 */
@@ -79228,20 +79570,18 @@
79228 ** the trigger subprograms are listed one by one.
79229 */
79230 SQLITE_PRIVATE int sqlite3VdbeList(
79231 Vdbe *p /* The VDBE */
79232 ){
79233 int nRow; /* Stop when row count reaches this */
79234 int nSub = 0; /* Number of sub-vdbes seen so far */
79235 SubProgram **apSub = 0; /* Array of sub-vdbes */
79236 Mem *pSub = 0; /* Memory cell hold array of subprogs */
79237 sqlite3 *db = p->db; /* The database connection */
79238 int i; /* Loop counter */
79239 int rc = SQLITE_OK; /* Return code */
79240 Mem *pMem = &p->aMem[1]; /* First Mem of result set */
79241 int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
79242 Op *pOp = 0;
 
79243
79244 assert( p->explain );
79245 assert( p->magic==VDBE_MAGIC_RUN );
79246 assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
79247
@@ -79257,166 +79597,66 @@
79257 ** sqlite3_column_text16() failed. */
79258 sqlite3OomFault(db);
79259 return SQLITE_ERROR;
79260 }
79261
79262 /* When the number of output rows reaches nRow, that means the
79263 ** listing has finished and sqlite3_step() should return SQLITE_DONE.
79264 ** nRow is the sum of the number of rows in the main program, plus
79265 ** the sum of the number of rows in all trigger subprograms encountered
79266 ** so far. The nRow value will increase as new trigger subprograms are
79267 ** encountered, but p->pc will eventually catch up to nRow.
79268 */
79269 nRow = p->nOp;
79270 if( bListSubprogs ){
79271 /* The first 8 memory cells are used for the result set. So we will
79272 ** commandeer the 9th cell to use as storage for an array of pointers
79273 ** to trigger subprograms. The VDBE is guaranteed to have at least 9
79274 ** cells. */
79275 assert( p->nMem>9 );
79276 pSub = &p->aMem[9];
79277 if( pSub->flags&MEM_Blob ){
79278 /* On the first call to sqlite3_step(), pSub will hold a NULL. It is
79279 ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
79280 nSub = pSub->n/sizeof(Vdbe*);
79281 apSub = (SubProgram **)pSub->z;
79282 }
79283 for(i=0; i<nSub; i++){
79284 nRow += apSub[i]->nOp;
79285 }
79286 }
79287
79288 while(1){ /* Loop exits via break */
79289 i = p->pc++;
79290 if( i>=nRow ){
79291 p->rc = SQLITE_OK;
79292 rc = SQLITE_DONE;
79293 break;
79294 }
79295 if( i<p->nOp ){
79296 /* The output line number is small enough that we are still in the
79297 ** main program. */
79298 pOp = &p->aOp[i];
79299 }else{
79300 /* We are currently listing subprograms. Figure out which one and
79301 ** pick up the appropriate opcode. */
79302 int j;
79303 i -= p->nOp;
79304 assert( apSub!=0 );
79305 assert( nSub>0 );
79306 for(j=0; i>=apSub[j]->nOp; j++){
79307 i -= apSub[j]->nOp;
79308 assert( i<apSub[j]->nOp || j+1<nSub );
79309 }
79310 pOp = &apSub[j]->aOp[i];
79311 }
79312
79313 /* When an OP_Program opcode is encounter (the only opcode that has
79314 ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
79315 ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
79316 ** has not already been seen.
79317 */
79318 if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
79319 int nByte = (nSub+1)*sizeof(SubProgram*);
79320 int j;
79321 for(j=0; j<nSub; j++){
79322 if( apSub[j]==pOp->p4.pProgram ) break;
79323 }
79324 if( j==nSub ){
79325 p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
79326 if( p->rc!=SQLITE_OK ){
79327 rc = SQLITE_ERROR;
79328 break;
79329 }
79330 apSub = (SubProgram **)pSub->z;
79331 apSub[nSub++] = pOp->p4.pProgram;
79332 pSub->flags |= MEM_Blob;
79333 pSub->n = nSub*sizeof(SubProgram*);
79334 nRow += pOp->p4.pProgram->nOp;
79335 }
79336 }
79337 if( p->explain<2 ) break;
79338 if( pOp->opcode==OP_Explain ) break;
79339 if( pOp->opcode==OP_Init && p->pc>1 ) break;
79340 }
79341
79342 if( rc==SQLITE_OK ){
79343 if( AtomicLoad(&db->u1.isInterrupted) ){
79344 p->rc = SQLITE_INTERRUPT;
79345 rc = SQLITE_ERROR;
79346 sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
79347 }else{
79348 char *zP4;
79349 if( p->explain==1 ){
79350 pMem->flags = MEM_Int;
79351 pMem->u.i = i; /* Program counter */
79352 pMem++;
79353
79354 pMem->flags = MEM_Static|MEM_Str|MEM_Term;
79355 pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
79356 assert( pMem->z!=0 );
79357 pMem->n = sqlite3Strlen30(pMem->z);
79358 pMem->enc = SQLITE_UTF8;
79359 pMem++;
79360 }
79361
79362 pMem->flags = MEM_Int;
79363 pMem->u.i = pOp->p1; /* P1 */
79364 pMem++;
79365
79366 pMem->flags = MEM_Int;
79367 pMem->u.i = pOp->p2; /* P2 */
79368 pMem++;
79369
79370 pMem->flags = MEM_Int;
79371 pMem->u.i = pOp->p3; /* P3 */
79372 pMem++;
79373
79374 if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
79375 assert( p->db->mallocFailed );
79376 return SQLITE_ERROR;
79377 }
79378 pMem->flags = MEM_Str|MEM_Term;
79379 zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
79380 if( zP4!=pMem->z ){
79381 pMem->n = 0;
79382 sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
79383 }else{
79384 assert( pMem->z!=0 );
79385 pMem->n = sqlite3Strlen30(pMem->z);
79386 pMem->enc = SQLITE_UTF8;
79387 }
79388 pMem++;
79389
79390 if( p->explain==1 ){
79391 if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
79392 assert( p->db->mallocFailed );
79393 return SQLITE_ERROR;
79394 }
79395 pMem->flags = MEM_Str|MEM_Term;
79396 pMem->n = 2;
79397 sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
79398 pMem->enc = SQLITE_UTF8;
79399 pMem++;
79400
79401 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
79402 if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
79403 assert( p->db->mallocFailed );
79404 return SQLITE_ERROR;
79405 }
79406 pMem->flags = MEM_Str|MEM_Term;
79407 pMem->n = displayComment(pOp, zP4, pMem->z, 500);
79408 pMem->enc = SQLITE_UTF8;
79409 #else
79410 pMem->flags = MEM_Null; /* Comment */
79411 #endif
79412 }
79413
79414 p->nResColumn = 8 - 4*(p->explain-1);
79415 p->pResultSet = &p->aMem[1];
79416 p->rc = SQLITE_OK;
79417 rc = SQLITE_ROW;
 
 
79418 }
79419 }
79420 return rc;
79421 }
79422 #endif /* SQLITE_OMIT_EXPLAIN */
@@ -79982,12 +80222,13 @@
79982 int retryCount = 0;
79983 int nMainFile;
79984
79985 /* Select a master journal file name */
79986 nMainFile = sqlite3Strlen30(zMainFile);
79987 zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz%c%c", zMainFile, 0, 0);
79988 if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
 
79989 do {
79990 u32 iRandom;
79991 if( retryCount ){
79992 if( retryCount>100 ){
79993 sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
@@ -80013,11 +80254,11 @@
80013 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
80014 SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
80015 );
80016 }
80017 if( rc!=SQLITE_OK ){
80018 sqlite3DbFree(db, zMaster);
80019 return rc;
80020 }
80021
80022 /* Write the name of each database file in the transaction into the new
80023 ** master journal file. If an error occurs at this point close
@@ -80036,11 +80277,11 @@
80036 rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
80037 offset += sqlite3Strlen30(zFile)+1;
80038 if( rc!=SQLITE_OK ){
80039 sqlite3OsCloseFree(pMaster);
80040 sqlite3OsDelete(pVfs, zMaster, 0);
80041 sqlite3DbFree(db, zMaster);
80042 return rc;
80043 }
80044 }
80045 }
80046
@@ -80050,11 +80291,11 @@
80050 if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
80051 && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
80052 ){
80053 sqlite3OsCloseFree(pMaster);
80054 sqlite3OsDelete(pVfs, zMaster, 0);
80055 sqlite3DbFree(db, zMaster);
80056 return rc;
80057 }
80058
80059 /* Sync all the db files involved in the transaction. The same call
80060 ** sets the master journal pointer in each individual journal. If
@@ -80073,20 +80314,20 @@
80073 }
80074 }
80075 sqlite3OsCloseFree(pMaster);
80076 assert( rc!=SQLITE_BUSY );
80077 if( rc!=SQLITE_OK ){
80078 sqlite3DbFree(db, zMaster);
80079 return rc;
80080 }
80081
80082 /* Delete the master journal file. This commits the transaction. After
80083 ** doing this the directory is synced again before any individual
80084 ** transaction files are deleted.
80085 */
80086 rc = sqlite3OsDelete(pVfs, zMaster, 1);
80087 sqlite3DbFree(db, zMaster);
80088 zMaster = 0;
80089 if( rc ){
80090 return rc;
80091 }
80092
@@ -87998,32 +88239,38 @@
87998 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
87999 REGISTER_TRACE(pOp->p3, pOut);
88000 break;
88001 }
88002
88003 /* Opcode: Count P1 P2 * * *
88004 ** Synopsis: r[P2]=count()
88005 **
88006 ** Store the number of entries (an integer value) in the table or index
88007 ** opened by cursor P1 in register P2
 
 
 
 
88008 */
88009 #ifndef SQLITE_OMIT_BTREECOUNT
88010 case OP_Count: { /* out2 */
88011 i64 nEntry;
88012 BtCursor *pCrsr;
88013
88014 assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
88015 pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
88016 assert( pCrsr );
88017 nEntry = 0; /* Not needed. Only used to silence a warning. */
88018 rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
88019 if( rc ) goto abort_due_to_error;
 
 
 
 
88020 pOut = out2Prerelease(p, pOp);
88021 pOut->u.i = nEntry;
88022 goto check_for_interrupt;
88023 }
88024 #endif
88025
88026 /* Opcode: Savepoint P1 * * P4 *
88027 **
88028 ** Open, release or rollback the savepoint named by parameter P4, depending
88029 ** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
@@ -90457,16 +90704,23 @@
90457 rc = sqlite3VdbeSorterWrite(pC, pIn2);
90458 if( rc) goto abort_due_to_error;
90459 break;
90460 }
90461
90462 /* Opcode: IdxDelete P1 P2 P3 * *
90463 ** Synopsis: key=r[P2@P3]
90464 **
90465 ** The content of P3 registers starting at register P2 form
90466 ** an unpacked index key. This opcode removes that entry from the
90467 ** index opened by cursor P1.
 
 
 
 
 
 
 
90468 */
90469 case OP_IdxDelete: {
90470 VdbeCursor *pC;
90471 BtCursor *pCrsr;
90472 int res;
@@ -90479,20 +90733,22 @@
90479 assert( pC!=0 );
90480 assert( pC->eCurType==CURTYPE_BTREE );
90481 sqlite3VdbeIncrWriteCounter(p, pC);
90482 pCrsr = pC->uc.pCursor;
90483 assert( pCrsr!=0 );
90484 assert( pOp->p5==0 );
90485 r.pKeyInfo = pC->pKeyInfo;
90486 r.nField = (u16)pOp->p3;
90487 r.default_rc = 0;
90488 r.aMem = &aMem[pOp->p2];
90489 rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
90490 if( rc ) goto abort_due_to_error;
90491 if( res==0 ){
90492 rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
90493 if( rc ) goto abort_due_to_error;
 
 
 
90494 }
90495 assert( pC->deferredMoveto==0 );
90496 pC->cacheStatus = CACHE_STALE;
90497 pC->seekResult = 0;
90498 break;
@@ -96093,10 +96349,435 @@
96093 *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
96094 return SQLITE_OK;
96095 }
96096
96097 /************** End of vdbesort.c ********************************************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96098 /************** Begin file memjournal.c **************************************/
96099 /*
96100 ** 2008 October 7
96101 **
96102 ** The author disclaims copyright to this source code. In place of
@@ -98739,11 +99420,11 @@
98739 ** SELECT * FROM t1 WHERE (select a from t1);
98740 */
98741 SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
98742 int op;
98743 while( ExprHasProperty(pExpr, EP_Skip) ){
98744 assert( pExpr->op==TK_COLLATE );
98745 pExpr = pExpr->pLeft;
98746 assert( pExpr!=0 );
98747 }
98748 op = pExpr->op;
98749 if( op==TK_SELECT ){
@@ -98806,11 +99487,11 @@
98806 /*
98807 ** Skip over any TK_COLLATE operators.
98808 */
98809 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
98810 while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
98811 assert( pExpr->op==TK_COLLATE );
98812 pExpr = pExpr->pLeft;
98813 }
98814 return pExpr;
98815 }
98816
@@ -98825,11 +99506,11 @@
98825 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
98826 assert( pExpr->x.pList->nExpr>0 );
98827 assert( pExpr->op==TK_FUNCTION );
98828 pExpr = pExpr->x.pList->a[0].pExpr;
98829 }else{
98830 assert( pExpr->op==TK_COLLATE );
98831 pExpr = pExpr->pLeft;
98832 }
98833 }
98834 return pExpr;
98835 }
@@ -103176,11 +103857,11 @@
103176 assert( pExpr->affExpr==OE_Rollback
103177 || pExpr->affExpr==OE_Abort
103178 || pExpr->affExpr==OE_Fail
103179 || pExpr->affExpr==OE_Ignore
103180 );
103181 if( !pParse->pTriggerTab ){
103182 sqlite3ErrorMsg(pParse,
103183 "RAISE() may only be used within a trigger-program");
103184 return 0;
103185 }
103186 if( pExpr->affExpr==OE_Abort ){
@@ -103190,12 +103871,13 @@
103190 if( pExpr->affExpr==OE_Ignore ){
103191 sqlite3VdbeAddOp4(
103192 v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
103193 VdbeCoverage(v);
103194 }else{
103195 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
103196 pExpr->affExpr, pExpr->u.zToken, 0, 0);
 
103197 }
103198
103199 break;
103200 }
103201 #endif
@@ -104946,10 +105628,26 @@
104946 exit_rename_table:
104947 sqlite3SrcListDelete(db, pSrc);
104948 sqlite3DbFree(db, zName);
104949 db->mDbFlags = savedDbFlags;
104950 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104951
104952 /*
104953 ** This function is called after an "ALTER TABLE ... ADD" statement
104954 ** has been parsed. Argument pColDef contains the text of the new
104955 ** column definition.
@@ -104999,11 +105697,12 @@
104999 if( pCol->colFlags & COLFLAG_PRIMKEY ){
105000 sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
105001 return;
105002 }
105003 if( pNew->pIndex ){
105004 sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
 
105005 return;
105006 }
105007 if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
105008 /* If the default value for the new column was specified with a
105009 ** literal NULL, then set pDflt to 0. This simplifies checking
@@ -105012,19 +105711,18 @@
105012 assert( pDflt==0 || pDflt->op==TK_SPAN );
105013 if( pDflt && pDflt->pLeft->op==TK_NULL ){
105014 pDflt = 0;
105015 }
105016 if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
105017 sqlite3ErrorMsg(pParse,
105018 "Cannot add a REFERENCES column with non-NULL default value");
105019 return;
105020 }
105021 if( pCol->notNull && !pDflt ){
105022 sqlite3ErrorMsg(pParse,
105023 "Cannot add a NOT NULL column with default value NULL");
105024 return;
105025 }
 
105026
105027 /* Ensure the default expression is something that sqlite3ValueFromExpr()
105028 ** can handle (i.e. not CURRENT_TIME etc.)
105029 */
105030 if( pDflt ){
@@ -105035,18 +105733,17 @@
105035 if( rc!=SQLITE_OK ){
105036 assert( db->mallocFailed == 1 );
105037 return;
105038 }
105039 if( !pVal ){
105040 sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default");
105041 return;
105042 }
105043 sqlite3ValueFree(pVal);
105044 }
105045 }else if( pCol->colFlags & COLFLAG_STORED ){
105046 sqlite3ErrorMsg(pParse, "cannot add a STORED column");
105047 return;
105048 }
105049
105050
105051 /* Modify the CREATE TABLE statement. */
105052 zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
@@ -106605,10 +107302,15 @@
106605 sqlite3 *db = pParse->db;
106606 Db *pDb;
106607 Vdbe *v = sqlite3GetVdbe(pParse);
106608 int aRoot[ArraySize(aTable)];
106609 u8 aCreateTbl[ArraySize(aTable)];
 
 
 
 
 
106610
106611 if( v==0 ) return;
106612 assert( sqlite3BtreeHoldsAllMutexes(db) );
106613 assert( sqlite3VdbeDb(v)==db );
106614 pDb = &db->aDb[iDb];
@@ -106617,12 +107319,13 @@
106617 ** if they do already exist.
106618 */
106619 for(i=0; i<ArraySize(aTable); i++){
106620 const char *zTab = aTable[i].zName;
106621 Table *pStat;
 
106622 if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
106623 if( aTable[i].zCols ){
106624 /* The sqlite_statN table does not exist. Create it. Note that a
106625 ** side-effect of the CREATE TABLE statement is to leave the rootpage
106626 ** of the new table in register pParse->regRoot. This is important
106627 ** because the OpenWrite opcode below will be needing it. */
106628 sqlite3NestedParse(pParse,
@@ -106634,11 +107337,10 @@
106634 }else{
106635 /* The table already exists. If zWhere is not NULL, delete all entries
106636 ** associated with the table zWhere. If zWhere is NULL, delete the
106637 ** entire contents of the table. */
106638 aRoot[i] = pStat->tnum;
106639 aCreateTbl[i] = 0;
106640 sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
106641 if( zWhere ){
106642 sqlite3NestedParse(pParse,
106643 "DELETE FROM %Q.%s WHERE %s=%Q",
106644 pDb->zDbSName, zTab, zWhereType, zWhere
@@ -106653,11 +107355,11 @@
106653 }
106654 }
106655 }
106656
106657 /* Open the sqlite_stat[134] tables for writing. */
106658 for(i=0; aTable[i].zCols; i++){
106659 assert( i<ArraySize(aTable) );
106660 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
106661 sqlite3VdbeChangeP5(v, aCreateTbl[i]);
106662 VdbeComment((v, aTable[i].zName));
106663 }
@@ -106692,13 +107394,16 @@
106692 u32 iHash; /* Tiebreaker hash */
106693 #endif
106694 };
106695 struct StatAccum {
106696 sqlite3 *db; /* Database connection, for malloc() */
106697 tRowcnt nRow; /* Number of rows in the entire table */
 
 
106698 int nCol; /* Number of columns in index + pk/rowid */
106699 int nKeyCol; /* Number of index columns w/o the pk/rowid */
 
106700 StatSample current; /* Current row as a StatSample */
106701 #ifdef SQLITE_ENABLE_STAT4
106702 tRowcnt nPSample; /* How often to do a periodic sample */
106703 int mxSample; /* Maximum number of samples to accumulate */
106704 u32 iPrn; /* Pseudo-random number used for sampling */
@@ -106774,31 +107479,32 @@
106774 ** Reclaim all memory of a StatAccum structure.
106775 */
106776 static void statAccumDestructor(void *pOld){
106777 StatAccum *p = (StatAccum*)pOld;
106778 #ifdef SQLITE_ENABLE_STAT4
106779 int i;
106780 for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
106781 for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
106782 sampleClear(p->db, &p->current);
 
 
106783 #endif
106784 sqlite3DbFree(p->db, p);
106785 }
106786
106787 /*
106788 ** Implementation of the stat_init(N,K,C) SQL function. The three parameters
106789 ** are:
106790 ** N: The number of columns in the index including the rowid/pk (note 1)
106791 ** K: The number of columns in the index excluding the rowid/pk.
106792 ** C: The number of rows in the index (note 2)
 
106793 **
106794 ** Note 1: In the special case of the covering index that implements a
106795 ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
106796 ** total number of columns in the table.
106797 **
106798 ** Note 2: C is only used for STAT4.
106799 **
106800 ** For indexes on ordinary rowid tables, N==K+1. But for indexes on
106801 ** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
106802 ** PRIMARY KEY of the table. The covering index that implements the
106803 ** original WITHOUT ROWID table as N==K as a special case.
106804 **
@@ -106815,13 +107521,14 @@
106815 StatAccum *p;
106816 int nCol; /* Number of columns in index being sampled */
106817 int nKeyCol; /* Number of key columns */
106818 int nColUp; /* nCol rounded up for alignment */
106819 int n; /* Bytes of space to allocate */
106820 sqlite3 *db; /* Database connection */
106821 #ifdef SQLITE_ENABLE_STAT4
106822 int mxSample = SQLITE_STAT4_SAMPLES;
 
106823 #endif
106824
106825 /* Decode the three function arguments */
106826 UNUSED_PARAMETER(argc);
106827 nCol = sqlite3_value_int(argv[0]);
@@ -106832,39 +107539,43 @@
106832 assert( nKeyCol>0 );
106833
106834 /* Allocate the space required for the StatAccum object */
106835 n = sizeof(*p)
106836 + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
106837 + sizeof(tRowcnt)*nColUp /* StatAccum.anDLt */
106838 #ifdef SQLITE_ENABLE_STAT4
106839 + sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
106840 + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
106841 + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
 
 
106842 #endif
106843 ;
106844 db = sqlite3_context_db_handle(context);
106845 p = sqlite3DbMallocZero(db, n);
106846 if( p==0 ){
106847 sqlite3_result_error_nomem(context);
106848 return;
106849 }
106850
106851 p->db = db;
 
106852 p->nRow = 0;
 
106853 p->nCol = nCol;
106854 p->nKeyCol = nKeyCol;
 
106855 p->current.anDLt = (tRowcnt*)&p[1];
106856 p->current.anEq = &p->current.anDLt[nColUp];
106857
106858 #ifdef SQLITE_ENABLE_STAT4
106859 {
 
106860 u8 *pSpace; /* Allocated space not yet assigned */
106861 int i; /* Used to iterate through p->aSample[] */
106862
106863 p->iGet = -1;
106864 p->mxSample = mxSample;
106865 p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
106866 p->current.anLt = &p->current.anEq[nColUp];
106867 p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
106868
106869 /* Set up the StatAccum.a[] and aBest[] arrays */
106870 p->a = (struct StatSample*)&p->current.anLt[nColUp];
@@ -106888,11 +107599,11 @@
106888 ** (given by the 3rd parameter) is never used and can be any positive
106889 ** value. */
106890 sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
106891 }
106892 static const FuncDef statInitFuncdef = {
106893 2+IsStat4, /* nArg */
106894 SQLITE_UTF8, /* funcFlags */
106895 0, /* pUserData */
106896 0, /* pNext */
106897 statInit, /* xSFunc */
106898 0, /* xFinalize */
@@ -107092,14 +107803,17 @@
107092 ** P Pointer to the StatAccum object created by stat_init()
107093 ** C Index of left-most column to differ from previous row
107094 ** R Rowid for the current row. Might be a key record for
107095 ** WITHOUT ROWID tables.
107096 **
107097 ** This SQL function always returns NULL. It's purpose it to accumulate
107098 ** statistical data and/or samples in the StatAccum object about the
107099 ** index being analyzed. The stat_get() SQL function will later be used to
107100 ** extract relevant information for constructing the sqlite_statN tables.
 
 
 
107101 **
107102 ** The R parameter is only used for STAT4
107103 */
107104 static void statPush(
107105 sqlite3_context *context,
@@ -107121,11 +107835,11 @@
107121 /* This is the first call to this function. Do initialization. */
107122 for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
107123 }else{
107124 /* Second and subsequent calls get processed here */
107125 #ifdef SQLITE_ENABLE_STAT4
107126 samplePushPrevious(p, iChng);
107127 #endif
107128
107129 /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
107130 ** to the current row of the index. */
107131 for(i=0; i<iChng; i++){
@@ -107132,30 +107846,29 @@
107132 p->current.anEq[i]++;
107133 }
107134 for(i=iChng; i<p->nCol; i++){
107135 p->current.anDLt[i]++;
107136 #ifdef SQLITE_ENABLE_STAT4
107137 p->current.anLt[i] += p->current.anEq[i];
107138 #endif
107139 p->current.anEq[i] = 1;
107140 }
107141 }
 
107142 p->nRow++;
107143 #ifdef SQLITE_ENABLE_STAT4
107144 if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
107145 sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
107146 }else{
107147 sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
107148 sqlite3_value_blob(argv[2]));
107149 }
107150 p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
107151 #endif
107152
107153 #ifdef SQLITE_ENABLE_STAT4
107154 {
107155 tRowcnt nLt = p->current.anLt[p->nCol-1];
107156
107157 /* Check if this is to be a periodic sample. If so, add it. */
107158 if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
107159 p->current.isPSample = 1;
107160 p->current.iCol = 0;
107161 sampleInsert(p, &p->current, p->nCol-1);
@@ -107167,13 +107880,18 @@
107167 p->current.iCol = i;
107168 if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
107169 sampleCopy(p, &p->aBest[i], &p->current);
107170 }
107171 }
 
 
 
 
 
107172 }
107173 #endif
107174 }
 
107175 static const FuncDef statPushFuncdef = {
107176 2+IsStat4, /* nArg */
107177 SQLITE_UTF8, /* funcFlags */
107178 0, /* pUserData */
107179 0, /* pNext */
@@ -107221,10 +107939,11 @@
107221 assert( argc==2 );
107222 assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
107223 || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
107224 || eCall==STAT_GET_NDLT
107225 );
 
107226 if( eCall==STAT_GET_STAT1 )
107227 #else
107228 assert( argc==1 );
107229 #endif
107230 {
@@ -107256,11 +107975,12 @@
107256 if( zRet==0 ){
107257 sqlite3_result_error_nomem(context);
107258 return;
107259 }
107260
107261 sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
 
107262 z = zRet + sqlite3Strlen30(zRet);
107263 for(i=0; i<p->nKeyCol; i++){
107264 u64 nDistinct = p->current.anDLt[i] + 1;
107265 u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
107266 sqlite3_snprintf(24, z, " %llu", iVal);
@@ -107332,20 +108052,20 @@
107332 0, 0, /* xValue, xInverse */
107333 "stat_get", /* zName */
107334 {0}
107335 };
107336
107337 static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){
107338 #ifdef SQLITE_ENABLE_STAT4
107339 sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1);
107340 #elif SQLITE_DEBUG
107341 assert( iParam==STAT_GET_STAT1 );
107342 #else
107343 UNUSED_PARAMETER( iParam );
107344 #endif
107345 assert( regOut!=regStat4 && regOut!=regStat4+1 );
107346 sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4,
107347 &statGetFuncdef, 0);
107348 }
107349
107350 /*
107351 ** Generate code to do an analysis of all indices associated with
@@ -107367,16 +108087,15 @@
107367 int i; /* Loop counter */
107368 int jZeroRows = -1; /* Jump from here if number of rows is zero */
107369 int iDb; /* Index of database containing pTab */
107370 u8 needTableCnt = 1; /* True to count the table */
107371 int regNewRowid = iMem++; /* Rowid for the inserted record */
107372 int regStat4 = iMem++; /* Register to hold StatAccum object */
107373 int regChng = iMem++; /* Index of changed index field */
107374 #ifdef SQLITE_ENABLE_STAT4
107375 int regRowid = iMem++; /* Rowid argument passed to stat_push() */
107376 #endif
107377 int regTemp = iMem++; /* Temporary use register */
 
107378 int regTabname = iMem++; /* Register containing table name */
107379 int regIdxname = iMem++; /* Register containing index name */
107380 int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
107381 int regPrev = iMem; /* MUST BE LAST (see below) */
107382 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -107500,21 +108219,30 @@
107500 /* Invoke the stat_init() function. The arguments are:
107501 **
107502 ** (1) the number of columns in the index including the rowid
107503 ** (or for a WITHOUT ROWID table, the number of PK columns),
107504 ** (2) the number of columns in the key without the rowid/pk
107505 ** (3) the number of rows in the index,
107506 **
107507 **
107508 ** The third argument is only used for STAT4
107509 */
 
 
 
107510 #ifdef SQLITE_ENABLE_STAT4
107511 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
 
 
 
 
107512 #endif
107513 sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
107514 sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
107515 sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4,
 
 
 
 
 
107516 &statInitFuncdef, 0);
107517
107518 /* Implementation of the following:
107519 **
107520 ** Rewind csr
@@ -107521,12 +108249,10 @@
107521 ** if eof(csr) goto end_of_scan;
107522 ** regChng = 0
107523 ** goto next_push_0;
107524 **
107525 */
107526 addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
107527 VdbeCoverage(v);
107528 sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
107529 addrNextRow = sqlite3VdbeCurrentAddr(v);
107530
107531 if( nColTest>0 ){
107532 int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
@@ -107555,10 +108281,11 @@
107555 }
107556 for(i=0; i<nColTest; i++){
107557 char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
107558 sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
107559 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
 
107560 aGotoChng[i] =
107561 sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
107562 sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
107563 VdbeCoverage(v);
107564 }
@@ -107575,10 +108302,11 @@
107575 */
107576 sqlite3VdbeJumpHere(v, addrNextRow-1);
107577 for(i=0; i<nColTest; i++){
107578 sqlite3VdbeJumpHere(v, aGotoChng[i]);
107579 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
 
107580 }
107581 sqlite3VdbeResolveLabel(v, endDistinctTest);
107582 sqlite3DbFree(db, aGotoChng);
107583 }
107584
@@ -107588,34 +108316,50 @@
107588 ** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
107589 ** Next csr
107590 ** if !eof(csr) goto next_row;
107591 */
107592 #ifdef SQLITE_ENABLE_STAT4
107593 assert( regRowid==(regStat4+2) );
107594 if( HasRowid(pTab) ){
107595 sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
107596 }else{
107597 Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
107598 int j, k, regKey;
107599 regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
107600 for(j=0; j<pPk->nKeyCol; j++){
107601 k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
107602 assert( k>=0 && k<pIdx->nColumn );
107603 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
107604 VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
107605 }
107606 sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
107607 sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
 
 
107608 }
107609 #endif
107610 assert( regChng==(regStat4+1) );
107611 sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4,
107612 &statPushFuncdef, 0);
107613 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107614
107615 /* Add the entry to the stat1 table. */
107616 callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1);
107617 assert( "BBB"[0]==SQLITE_AFF_TEXT );
107618 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
107619 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
107620 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
107621 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -107623,11 +108367,11 @@
107623 #endif
107624 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
107625
107626 /* Add the entries to the stat4 table. */
107627 #ifdef SQLITE_ENABLE_STAT4
107628 {
107629 int regEq = regStat1;
107630 int regLt = regStat1+1;
107631 int regDLt = regStat1+2;
107632 int regSample = regStat1+3;
107633 int regCol = regStat1+4;
@@ -107637,16 +108381,16 @@
107637 u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
107638
107639 pParse->nMem = MAX(pParse->nMem, regCol+nCol);
107640
107641 addrNext = sqlite3VdbeCurrentAddr(v);
107642 callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid);
107643 addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
107644 VdbeCoverage(v);
107645 callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq);
107646 callStatGet(pParse, regStat4, STAT_GET_NLT, regLt);
107647 callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt);
107648 sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
107649 VdbeCoverage(v);
107650 for(i=0; i<nCol; i++){
107651 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
107652 }
@@ -113818,11 +114562,11 @@
113818 pParse->rc = rc;
113819 return 1;
113820 }
113821 db->aDb[1].pBt = pBt;
113822 assert( db->aDb[1].pSchema );
113823 if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
113824 sqlite3OomFault(db);
113825 return 1;
113826 }
113827 }
113828 return 0;
@@ -113929,11 +114673,11 @@
113929 char *p4, /* Error message */
113930 i8 p4type, /* P4_STATIC or P4_TRANSIENT */
113931 u8 p5Errmsg /* P5_ErrMsg type */
113932 ){
113933 Vdbe *v = sqlite3GetVdbe(pParse);
113934 assert( (errCode&0xff)==SQLITE_CONSTRAINT );
113935 if( onError==OE_Abort ){
113936 sqlite3MayAbort(pParse);
113937 }
113938 sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
113939 sqlite3VdbeChangeP5(v, p5Errmsg);
@@ -115642,10 +116386,11 @@
115642 VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
115643 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
115644 &iPartIdxLabel, pPrior, r1);
115645 sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
115646 pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
 
115647 sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
115648 pPrior = pIdx;
115649 }
115650 }
115651
@@ -122629,10 +123374,11 @@
122629 const char *(*filename_wal)(const char*);
122630 /* Version 3.32.0 and later */
122631 char *(*create_filename)(const char*,const char*,const char*,
122632 int,const char**);
122633 void (*free_filename)(char*);
 
122634 };
122635
122636 /*
122637 ** This is the function signature used for all extension entry points. It
122638 ** is also defined in the file "loadext.c".
@@ -122932,10 +123678,11 @@
122932 #define sqlite3_filename_journal sqlite3_api->filename_journal
122933 #define sqlite3_filename_wal sqlite3_api->filename_wal
122934 /* Version 3.32.0 and later */
122935 #define sqlite3_create_filename sqlite3_api->create_filename
122936 #define sqlite3_free_filename sqlite3_api->free_filename
 
122937 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
122938
122939 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
122940 /* This case when the file really is being compiled as a loadable
122941 ** extension */
@@ -123413,11 +124160,20 @@
123413 sqlite3_filename_journal,
123414 sqlite3_filename_wal,
123415 /* Version 3.32.0 and later */
123416 sqlite3_create_filename,
123417 sqlite3_free_filename,
 
123418 };
 
 
 
 
 
 
 
 
123419
123420 /*
123421 ** Attempt to load an SQLite extension library contained in the file
123422 ** zFile. The entry point is zProc. zProc may be 0 in which case a
123423 ** default entry point name (sqlite3_extension_init) is used. Use
@@ -123516,11 +124272,11 @@
123516 if( zAltEntry==0 ){
123517 sqlite3OsDlClose(pVfs, handle);
123518 return SQLITE_NOMEM_BKPT;
123519 }
123520 memcpy(zAltEntry, "sqlite3_", 8);
123521 for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
123522 iFile++;
123523 if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
123524 for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
123525 if( sqlite3Isalpha(c) ){
123526 zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
@@ -123820,53 +124576,54 @@
123820 ** that script and rerun it.
123821 */
123822
123823 /* The various pragma types */
123824 #define PragTyp_ACTIVATE_EXTENSIONS 0
123825 #define PragTyp_HEADER_VALUE 1
123826 #define PragTyp_AUTO_VACUUM 2
123827 #define PragTyp_FLAG 3
123828 #define PragTyp_BUSY_TIMEOUT 4
123829 #define PragTyp_CACHE_SIZE 5
123830 #define PragTyp_CACHE_SPILL 6
123831 #define PragTyp_CASE_SENSITIVE_LIKE 7
123832 #define PragTyp_COLLATION_LIST 8
123833 #define PragTyp_COMPILE_OPTIONS 9
123834 #define PragTyp_DATA_STORE_DIRECTORY 10
123835 #define PragTyp_DATABASE_LIST 11
123836 #define PragTyp_DEFAULT_CACHE_SIZE 12
123837 #define PragTyp_ENCODING 13
123838 #define PragTyp_FOREIGN_KEY_CHECK 14
123839 #define PragTyp_FOREIGN_KEY_LIST 15
123840 #define PragTyp_FUNCTION_LIST 16
123841 #define PragTyp_HARD_HEAP_LIMIT 17
123842 #define PragTyp_INCREMENTAL_VACUUM 18
123843 #define PragTyp_INDEX_INFO 19
123844 #define PragTyp_INDEX_LIST 20
123845 #define PragTyp_INTEGRITY_CHECK 21
123846 #define PragTyp_JOURNAL_MODE 22
123847 #define PragTyp_JOURNAL_SIZE_LIMIT 23
123848 #define PragTyp_LOCK_PROXY_FILE 24
123849 #define PragTyp_LOCKING_MODE 25
123850 #define PragTyp_PAGE_COUNT 26
123851 #define PragTyp_MMAP_SIZE 27
123852 #define PragTyp_MODULE_LIST 28
123853 #define PragTyp_OPTIMIZE 29
123854 #define PragTyp_PAGE_SIZE 30
123855 #define PragTyp_PRAGMA_LIST 31
123856 #define PragTyp_SECURE_DELETE 32
123857 #define PragTyp_SHRINK_MEMORY 33
123858 #define PragTyp_SOFT_HEAP_LIMIT 34
123859 #define PragTyp_SYNCHRONOUS 35
123860 #define PragTyp_TABLE_INFO 36
123861 #define PragTyp_TEMP_STORE 37
123862 #define PragTyp_TEMP_STORE_DIRECTORY 38
123863 #define PragTyp_THREADS 39
123864 #define PragTyp_WAL_AUTOCHECKPOINT 40
123865 #define PragTyp_WAL_CHECKPOINT 41
123866 #define PragTyp_LOCK_STATUS 42
123867 #define PragTyp_STATS 43
 
123868
123869 /* Property flags associated with various pragma. */
123870 #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
123871 #define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
123872 #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
@@ -123953,10 +124710,15 @@
123953 /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
123954 /* ePragFlg: */ 0,
123955 /* ColNames: */ 0, 0,
123956 /* iArg: */ 0 },
123957 #endif
 
 
 
 
 
123958 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
123959 {/* zName: */ "application_id",
123960 /* ePragTyp: */ PragTyp_HEADER_VALUE,
123961 /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
123962 /* ColNames: */ 0, 0,
@@ -124453,11 +125215,11 @@
124453 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
124454 /* ColNames: */ 0, 0,
124455 /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
124456 #endif
124457 };
124458 /* Number of pragmas: 66 on by default, 76 total. */
124459
124460 /************** End of pragma.h **********************************************/
124461 /************** Continuing where we left off in pragma.c *********************/
124462
124463 /*
@@ -124983,11 +125745,11 @@
124983 }else{
124984 /* Malloc may fail when setting the page-size, as there is an internal
124985 ** buffer that the pager module resizes using sqlite3_realloc().
124986 */
124987 db->nextPagesize = sqlite3Atoi(zRight);
124988 if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
124989 sqlite3OomFault(db);
124990 }
124991 }
124992 break;
124993 }
@@ -126157,11 +126919,10 @@
126157 sqlite3ResolvePartIdxLabel(pParse, jmp3);
126158 }
126159 }
126160 sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
126161 sqlite3VdbeJumpHere(v, loopTop-1);
126162 #ifndef SQLITE_OMIT_BTREECOUNT
126163 if( !isQuick ){
126164 sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
126165 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
126166 if( pPk==pIdx ) continue;
126167 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
@@ -126171,11 +126932,10 @@
126171 sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
126172 integrityCheckResultRow(v);
126173 sqlite3VdbeJumpHere(v, addr);
126174 }
126175 }
126176 #endif /* SQLITE_OMIT_BTREECOUNT */
126177 }
126178 }
126179 {
126180 static const int iLn = VDBE_OFFSET_LINENO(2);
126181 static const VdbeOpList endCode[] = {
@@ -126605,10 +127365,29 @@
126605 sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
126606 }
126607 returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
126608 break;
126609 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126610
126611 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
126612 /*
126613 ** Report the current state of file logs for all databases
126614 */
@@ -131404,10 +132183,11 @@
131404 if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
131405 memset(&ifNullRow, 0, sizeof(ifNullRow));
131406 ifNullRow.op = TK_IF_NULL_ROW;
131407 ifNullRow.pLeft = pCopy;
131408 ifNullRow.iTable = pSubst->iNewTable;
 
131409 pCopy = &ifNullRow;
131410 }
131411 testcase( ExprHasProperty(pCopy, EP_Subquery) );
131412 pNew = sqlite3ExprDup(db, pCopy, 0);
131413 if( pNew && pSubst->isLeftJoin ){
@@ -134568,11 +135348,10 @@
134568 VdbeComment((v, "indicate accumulator empty"));
134569 sqlite3VdbeAddOp1(v, OP_Return, regReset);
134570
134571 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
134572 else {
134573 #ifndef SQLITE_OMIT_BTREECOUNT
134574 Table *pTab;
134575 if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
134576 /* If isSimpleCount() returns a pointer to a Table structure, then
134577 ** the SQL statement is of the form:
134578 **
@@ -134604,17 +135383,19 @@
134604 **
134605 ** In practice the KeyInfo structure will not be used. It is only
134606 ** passed to keep OP_OpenRead happy.
134607 */
134608 if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
134609 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
134610 if( pIdx->bUnordered==0
134611 && pIdx->szIdxRow<pTab->szTabRow
134612 && pIdx->pPartIdxWhere==0
134613 && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
134614 ){
134615 pBest = pIdx;
 
 
134616 }
134617 }
134618 if( pBest ){
134619 iRoot = pBest->tnum;
134620 pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
@@ -134626,13 +135407,11 @@
134626 sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
134627 }
134628 sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
134629 sqlite3VdbeAddOp1(v, OP_Close, iCsr);
134630 explainSimpleCount(pParse, pTab, pBest);
134631 }else
134632 #endif /* SQLITE_OMIT_BTREECOUNT */
134633 {
134634 int regAcc = 0; /* "populate accumulators" flag */
134635
134636 /* If there are accumulator registers but no min() or max() functions
134637 ** without FILTER clauses, allocate register regAcc. Register regAcc
134638 ** will contain 0 the first time the inner loop runs, and 1 thereafter.
@@ -137852,11 +138631,11 @@
137852 db->mDbFlags = saved_mDbFlags;
137853 db->flags = saved_flags;
137854 db->nChange = saved_nChange;
137855 db->nTotalChange = saved_nTotalChange;
137856 db->mTrace = saved_mTrace;
137857 sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
137858
137859 /* Currently there is an SQL level transaction open on the vacuum
137860 ** database. No locks are held on any other files (since the main file
137861 ** was committed at the btree level). So it safe to end the transaction
137862 ** by manually setting the autoCommit flag to true and detaching the
@@ -159255,19 +160034,82 @@
159255
159256
159257 /************** End of sqliteicu.h *******************************************/
159258 /************** Continuing where we left off in main.c ***********************/
159259 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159260 #ifdef SQLITE_ENABLE_JSON1
159261 SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
159262 #endif
159263 #ifdef SQLITE_ENABLE_STMTVTAB
159264 SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
159265 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159266 #ifdef SQLITE_ENABLE_FTS5
159267 SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
159268 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159269
159270 #ifndef SQLITE_AMALGAMATION
159271 /* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
159272 ** contains the text of SQLITE_VERSION macro.
159273 */
@@ -160781,12 +161623,11 @@
160781 ** Return non-zero to retry the lock. Return zero to stop trying
160782 ** and cause SQLite to return SQLITE_BUSY.
160783 */
160784 static int sqliteDefaultBusyCallback(
160785 void *ptr, /* Database connection */
160786 int count, /* Number of times table has been busy */
160787 sqlite3_file *pFile /* The file on which the lock occurred */
160788 ){
160789 #if SQLITE_OS_WIN || HAVE_USLEEP
160790 /* This case is for systems that have support for sleeping for fractions of
160791 ** a second. Examples: All windows systems, unix systems with usleep() */
160792 static const u8 delays[] =
@@ -160796,35 +161637,10 @@
160796 # define NDELAY ArraySize(delays)
160797 sqlite3 *db = (sqlite3 *)ptr;
160798 int tmout = db->busyTimeout;
160799 int delay, prior;
160800
160801 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
160802 if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
160803 if( count ){
160804 /* If this is the second or later invocation of the busy-handler,
160805 ** but tmout==0, then code in wal.c must have disabled the blocking
160806 ** lock before the SQLITE_BUSY error was hit. In this case, no delay
160807 ** occurred while waiting for the lock, so fall through to the xSleep()
160808 ** code below to delay a while before retrying the lock.
160809 **
160810 ** Alternatively, if tmout!=0, then SQLite has already waited
160811 ** sqlite3.busyTimeout ms for a lock. In this case, return 0 to
160812 ** indicate that the lock should not be retried and the SQLITE_BUSY
160813 ** error returned to the application. */
160814 if( tmout ){
160815 tmout = 0;
160816 sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
160817 return 0;
160818 }
160819 }else{
160820 return 1;
160821 }
160822 }
160823 #else
160824 UNUSED_PARAMETER(pFile);
160825 #endif
160826 assert( count>=0 );
160827 if( count < NDELAY ){
160828 delay = delays[count];
160829 prior = totals[count];
160830 }else{
@@ -160840,11 +161656,10 @@
160840 #else
160841 /* This case for unix systems that lack usleep() support. Sleeping
160842 ** must be done in increments of whole seconds */
160843 sqlite3 *db = (sqlite3 *)ptr;
160844 int tmout = ((sqlite3 *)ptr)->busyTimeout;
160845 UNUSED_PARAMETER(pFile);
160846 if( (count+1)*1000 > tmout ){
160847 return 0;
160848 }
160849 sqlite3OsSleep(db->pVfs, 1000000);
160850 return 1;
@@ -160858,23 +161673,14 @@
160858 ** lock on VFS file pFile.
160859 **
160860 ** If this routine returns non-zero, the lock is retried. If it
160861 ** returns 0, the operation aborts with an SQLITE_BUSY error.
160862 */
160863 SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
160864 int rc;
160865 if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
160866 if( p->bExtraFileArg ){
160867 /* Add an extra parameter with the pFile pointer to the end of the
160868 ** callback argument list */
160869 int (*xTra)(void*,int,sqlite3_file*);
160870 xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
160871 rc = xTra(p->pBusyArg, p->nBusy, pFile);
160872 }else{
160873 /* Legacy style busy handler callback */
160874 rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
160875 }
160876 if( rc==0 ){
160877 p->nBusy = -1;
160878 }else{
160879 p->nBusy++;
160880 }
@@ -160895,11 +161701,10 @@
160895 #endif
160896 sqlite3_mutex_enter(db->mutex);
160897 db->busyHandler.xBusyHandler = xBusy;
160898 db->busyHandler.pBusyArg = pArg;
160899 db->busyHandler.nBusy = 0;
160900 db->busyHandler.bExtraFileArg = 0;
160901 db->busyTimeout = 0;
160902 sqlite3_mutex_leave(db->mutex);
160903 return SQLITE_OK;
160904 }
160905
@@ -160946,11 +161751,10 @@
160946 #endif
160947 if( ms>0 ){
160948 sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
160949 (void*)db);
160950 db->busyTimeout = ms;
160951 db->busyHandler.bExtraFileArg = 1;
160952 }else{
160953 sqlite3_busy_handler(db, 0, 0);
160954 }
160955 return SQLITE_OK;
160956 }
@@ -162272,10 +163076,11 @@
162272 sqlite3 *db; /* Store allocated handle here */
162273 int rc; /* Return code */
162274 int isThreadsafe; /* True for threadsafe connections */
162275 char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
162276 char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
 
162277
162278 #ifdef SQLITE_ENABLE_API_ARMOR
162279 if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
162280 #endif
162281 *ppDb = 0;
@@ -162420,10 +163225,13 @@
162420 | SQLITE_EnableQPSG
162421 #endif
162422 #if defined(SQLITE_DEFAULT_DEFENSIVE)
162423 | SQLITE_Defensive
162424 #endif
 
 
 
162425 ;
162426 sqlite3HashInit(&db->aCollSeq);
162427 #ifndef SQLITE_OMIT_VIRTUALTABLE
162428 sqlite3HashInit(&db->aModule);
162429 #endif
@@ -162512,18 +163320,15 @@
162512 */
162513 sqlite3Error(db, SQLITE_OK);
162514 sqlite3RegisterPerConnectionBuiltinFunctions(db);
162515 rc = sqlite3_errcode(db);
162516
162517 #ifdef SQLITE_ENABLE_FTS5
162518 /* Register any built-in FTS5 module before loading the automatic
162519 ** extensions. This allows automatic extensions to register FTS5
162520 ** tokenizers and auxiliary functions. */
162521 if( !db->mallocFailed && rc==SQLITE_OK ){
162522 rc = sqlite3Fts5Init(db);
162523 }
162524 #endif
162525
162526 /* Load automatic extensions - extensions that have been registered
162527 ** using the sqlite3_automatic_extension() API.
162528 */
162529 if( rc==SQLITE_OK ){
@@ -162532,66 +163337,10 @@
162532 if( rc!=SQLITE_OK ){
162533 goto opendb_out;
162534 }
162535 }
162536
162537 #ifdef SQLITE_ENABLE_FTS1
162538 if( !db->mallocFailed ){
162539 extern int sqlite3Fts1Init(sqlite3*);
162540 rc = sqlite3Fts1Init(db);
162541 }
162542 #endif
162543
162544 #ifdef SQLITE_ENABLE_FTS2
162545 if( !db->mallocFailed && rc==SQLITE_OK ){
162546 extern int sqlite3Fts2Init(sqlite3*);
162547 rc = sqlite3Fts2Init(db);
162548 }
162549 #endif
162550
162551 #ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
162552 if( !db->mallocFailed && rc==SQLITE_OK ){
162553 rc = sqlite3Fts3Init(db);
162554 }
162555 #endif
162556
162557 #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
162558 if( !db->mallocFailed && rc==SQLITE_OK ){
162559 rc = sqlite3IcuInit(db);
162560 }
162561 #endif
162562
162563 #ifdef SQLITE_ENABLE_RTREE
162564 if( !db->mallocFailed && rc==SQLITE_OK){
162565 rc = sqlite3RtreeInit(db);
162566 }
162567 #endif
162568
162569 #ifdef SQLITE_ENABLE_DBPAGE_VTAB
162570 if( !db->mallocFailed && rc==SQLITE_OK){
162571 rc = sqlite3DbpageRegister(db);
162572 }
162573 #endif
162574
162575 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
162576 if( !db->mallocFailed && rc==SQLITE_OK){
162577 rc = sqlite3DbstatRegister(db);
162578 }
162579 #endif
162580
162581 #ifdef SQLITE_ENABLE_JSON1
162582 if( !db->mallocFailed && rc==SQLITE_OK){
162583 rc = sqlite3Json1Init(db);
162584 }
162585 #endif
162586
162587 #ifdef SQLITE_ENABLE_STMTVTAB
162588 if( !db->mallocFailed && rc==SQLITE_OK){
162589 rc = sqlite3StmtVtabInit(db);
162590 }
162591 #endif
162592
162593 #ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
162594 /* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
162595 ** option gives access to internal functions by default.
162596 ** Testing use only!!! */
162597 db->mDbFlags |= DBFLAG_InternalFunc;
@@ -163076,11 +163825,11 @@
163076 *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
163077 rc = SQLITE_OK;
163078 }else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
163079 int iNew = *(int*)pArg;
163080 *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
163081 if( iNew>=0 && iNew<=254 ){
163082 sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
163083 }
163084 rc = SQLITE_OK;
163085 }else{
163086 rc = sqlite3OsFileControl(fd, op, pArg);
@@ -165357,10 +166106,11 @@
165357 SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
165358 SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
165359 SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
165360 SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
165361 SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
 
165362
165363 /* fts3_tokenizer.c */
165364 SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
165365 SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
165366 SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -166088,10 +166838,26 @@
166088 fts3Appendf(pRc, &zRet, ", ?");
166089 }
166090 sqlite3_free(zFree);
166091 return zRet;
166092 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166093
166094 /*
166095 ** This function interprets the string at (*pp) as a non-negative integer
166096 ** value. It reads the integer and sets *pnOut to the value read, then
166097 ** sets *pp to point to the byte immediately following the last byte of
@@ -166104,23 +166870,21 @@
166104 **
166105 ** This function is used when parsing the "prefix=" FTS4 parameter.
166106 */
166107 static int fts3GobbleInt(const char **pp, int *pnOut){
166108 const int MAX_NPREFIX = 10000000;
166109 const char *p; /* Iterator pointer */
166110 int nInt = 0; /* Output value */
166111
166112 for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
166113 nInt = nInt * 10 + (p[0] - '0');
166114 if( nInt>MAX_NPREFIX ){
166115 nInt = 0;
166116 break;
166117 }
166118 }
166119 if( p==*pp ) return SQLITE_ERROR;
166120 *pnOut = nInt;
166121 *pp = p;
166122 return SQLITE_OK;
166123 }
166124
166125 /*
166126 ** This function is called to allocate an array of Fts3Index structures
@@ -167298,11 +168062,13 @@
167298 static void fts3ReadNextPos(
167299 char **pp, /* IN/OUT: Pointer into position-list buffer */
167300 sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
167301 ){
167302 if( (**pp)&0xFE ){
167303 fts3GetDeltaVarint(pp, pi);
 
 
167304 *pi -= 2;
167305 }else{
167306 *pi = POSITION_LIST_END;
167307 }
167308 }
@@ -172198,14 +172964,11 @@
172198
172199 /* If this is a "NEAR" keyword, check for an explicit nearness. */
172200 if( pKey->eType==FTSQUERY_NEAR ){
172201 assert( nKey==4 );
172202 if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
172203 nNear = 0;
172204 for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
172205 nNear = nNear * 10 + (zInput[nKey] - '0');
172206 }
172207 }
172208 }
172209
172210 /* At this point this is probably a keyword. But for that to be true,
172211 ** the next byte must contain either whitespace, an open or close
@@ -178384,25 +179147,25 @@
178384 ){
178385 const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
178386 if( zText ){
178387 int i;
178388 int iMul = 1;
178389 i64 iVal = 0;
178390 for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
178391 iVal = iVal*10 + (zText[i] - '0');
178392 }
178393 *piEndBlock = iVal;
178394 while( zText[i]==' ' ) i++;
178395 iVal = 0;
178396 if( zText[i]=='-' ){
178397 i++;
178398 iMul = -1;
178399 }
178400 for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
178401 iVal = iVal*10 + (zText[i] - '0');
178402 }
178403 *pnByte = (iVal * (i64)iMul);
178404 }
178405 }
178406
178407
178408 /*
@@ -223901,11 +224664,11 @@
223901 int nArg, /* Number of args */
223902 sqlite3_value **apUnused /* Function arguments */
223903 ){
223904 assert( nArg==0 );
223905 UNUSED_PARAM2(nArg, apUnused);
223906 sqlite3_result_text(pCtx, "fts5: 2020-03-03 20:04:29 bd94d7d052734460904c687756231f8aa243a2252f07f742dd1e437aa940f536", -1, SQLITE_TRANSIENT);
223907 }
223908
223909 /*
223910 ** Return true if zName is the extension on one of the shadow tables used
223911 ** by this module.
@@ -228552,11 +229315,12 @@
228552 }
228553 case STMT_COLUMN_BUSY: {
228554 sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
228555 break;
228556 }
228557 case STMT_COLUMN_MEM: {
 
228558 i = SQLITE_STMTSTATUS_MEMUSED +
228559 STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
228560 /* Fall thru */
228561 }
228562 case STMT_COLUMN_NSCAN:
@@ -228683,12 +229447,12 @@
228683 }
228684 #endif /* SQLITE_CORE */
228685 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
228686
228687 /************** End of stmt.c ************************************************/
228688 #if __LINE__!=228688
228689 #undef SQLITE_SOURCE_ID
228690 #define SQLITE_SOURCE_ID "2020-04-20 17:35:32 2fc80ef16ce5878311ab88a0c64631813572ffbb71f75363b4619c9667e0alt2"
228691 #endif
228692 /* Return the source-id for this library */
228693 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
228694 /************************** End of sqlite3.c ******************************/
228695
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -216,10 +216,13 @@
216 "ENABLE_ATOMIC_WRITE",
217 #endif
218 #if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
219 "ENABLE_BATCH_ATOMIC_WRITE",
220 #endif
221 #if SQLITE_ENABLE_BYTECODE_VTAB
222 "ENABLE_BYTECODE_VTAB",
223 #endif
224 #if SQLITE_ENABLE_CEROD
225 "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
226 #endif
227 #if SQLITE_ENABLE_COLUMN_METADATA
228 "ENABLE_COLUMN_METADATA",
@@ -534,13 +537,10 @@
537 "OMIT_BETWEEN_OPTIMIZATION",
538 #endif
539 #if SQLITE_OMIT_BLOB_LITERAL
540 "OMIT_BLOB_LITERAL",
541 #endif
 
 
 
542 #if SQLITE_OMIT_CAST
543 "OMIT_CAST",
544 #endif
545 #if SQLITE_OMIT_CHECK
546 "OMIT_CHECK",
@@ -1162,11 +1162,11 @@
1162 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1163 ** [sqlite_version()] and [sqlite_source_id()].
1164 */
1165 #define SQLITE_VERSION "3.32.0"
1166 #define SQLITE_VERSION_NUMBER 3032000
1167 #define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff"
1168
1169 /*
1170 ** CAPI3REF: Run-Time Library Version Numbers
1171 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1172 **
@@ -1336,30 +1336,26 @@
1336 ** for the [sqlite3] object.
1337 ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
1338 ** the [sqlite3] object is successfully destroyed and all associated
1339 ** resources are deallocated.
1340 **
1341 ** Ideally, applications should [sqlite3_finalize | finalize] all
1342 ** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
1343 ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
1344 ** with the [sqlite3] object prior to attempting to close the object.
1345 ** ^If the database connection is associated with unfinalized prepared
1346 ** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
1347 ** sqlite3_close() will leave the database connection open and return
1348 ** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
1349 ** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
1350 ** it returns [SQLITE_OK] regardless, but instead of deallocating the database
1351 ** connection immediately, it marks the database connection as an unusable
1352 ** "zombie" and makes arrangements to automatically deallocate the database
1353 ** connection after all prepared statements are finalized, all BLOB handles
1354 ** are closed, and all backups have finished. The sqlite3_close_v2() interface
1355 ** is intended for use with host languages that are garbage collected, and
1356 ** where the order in which destructors are called is arbitrary.
 
 
 
 
 
 
 
 
1357 **
1358 ** ^If an [sqlite3] object is destroyed while a transaction is open,
1359 ** the transaction is automatically rolled back.
1360 **
1361 ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
@@ -1544,22 +1540,25 @@
1540 #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
1541 #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
1542 #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
1543 #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
1544 #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
1545 #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
1546 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
1547 #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
1548 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
1549 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
1550 #define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
1551 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
1552 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
1553 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
1554 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
1555 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
1556 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
1557 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
1558 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
1559 #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
1560 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
1561 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
1562 #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
1563 #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
1564 #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
@@ -2150,10 +2149,15 @@
2149 ** a single attached database that occur due to other database connections,
2150 ** but omits changes implemented by the database connection on which it is
2151 ** called. This file control is the only mechanism to detect changes that
2152 ** happen either internally or externally and that are associated with
2153 ** a particular attached database.
2154 **
2155 ** <li>[[SQLITE_FCNTL_CKPT_START]]
2156 ** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
2157 ** in wal mode before the client starts to copy pages from the wal
2158 ** file to the database file.
2159 **
2160 ** <li>[[SQLITE_FCNTL_CKPT_DONE]]
2161 ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
2162 ** in wal mode after the client has finished copying pages from the wal
2163 ** file to the database file, but before the *-shm file is updated to
@@ -2195,10 +2199,11 @@
2199 #define SQLITE_FCNTL_LOCK_TIMEOUT 34
2200 #define SQLITE_FCNTL_DATA_VERSION 35
2201 #define SQLITE_FCNTL_SIZE_LIMIT 36
2202 #define SQLITE_FCNTL_CKPT_DONE 37
2203 #define SQLITE_FCNTL_RESERVE_BYTES 38
2204 #define SQLITE_FCNTL_CKPT_START 39
2205
2206 /* deprecated names */
2207 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
2208 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
2209 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -4573,12 +4578,23 @@
4578 **
4579 ** These are utility routines, useful to [VFS|custom VFS implementations],
4580 ** that check if a database file was a URI that contained a specific query
4581 ** parameter, and if so obtains the value of that query parameter.
4582 **
4583 ** The first parameter to these interfaces (hereafter referred to
4584 ** as F) must be one of:
4585 ** <ul>
4586 ** <li> A database filename pointer created by the SQLite core and
4587 ** passed into the xOpen() method of a VFS implemention, or
4588 ** <li> A filename obtained from [sqlite3_db_filename()], or
4589 ** <li> A new filename constructed using [sqlite3_create_filename()].
4590 ** </ul>
4591 ** If the F parameter is not one of the above, then the behavior is
4592 ** undefined and probably undesirable. Older versions of SQLite were
4593 ** more tolerant of invalid F parameters than newer versions.
4594 **
4595 ** If F is a suitable filename (as described in the previous paragraph)
4596 ** and if P is the name of the query parameter, then
4597 ** sqlite3_uri_parameter(F,P) returns the value of the P
4598 ** parameter if it exists or a NULL pointer if P does not appear as a
4599 ** query parameter on F. If P is a query parameter of F and it
4600 ** has no explicit value, then sqlite3_uri_parameter(F,P) returns
@@ -4657,10 +4673,29 @@
4673 */
4674 SQLITE_API const char *sqlite3_filename_database(const char*);
4675 SQLITE_API const char *sqlite3_filename_journal(const char*);
4676 SQLITE_API const char *sqlite3_filename_wal(const char*);
4677
4678 /*
4679 ** CAPI3REF: Database File Corresponding To A Journal
4680 **
4681 ** ^If X is the name of a rollback or WAL-mode journal file that is
4682 ** passed into the xOpen method of [sqlite3_vfs], then
4683 ** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
4684 ** object that represents the main database file.
4685 **
4686 ** This routine is intended for use in custom [VFS] implementations
4687 ** only. It is not a general-purpose interface.
4688 ** The argument sqlite3_file_object(X) must be a filename pointer that
4689 ** has been passed into [sqlite3_vfs].xOpen method where the
4690 ** flags parameter to xOpen contains one of the bits
4691 ** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
4692 ** of this routine results in undefined and probably undesirable
4693 ** behavior.
4694 */
4695 SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
4696
4697 /*
4698 ** CAPI3REF: Create and Destroy VFS Filenames
4699 **
4700 ** These interfces are provided for use by [VFS shim] implementations and
4701 ** are not useful outside of that context.
@@ -4691,11 +4726,11 @@
4726 ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
4727 ** be NULL pointers, though they can be empty strings.
4728 **
4729 ** The sqlite3_free_filename(Y) routine releases a memory allocation
4730 ** previously obtained from sqlite3_create_filename(). Invoking
4731 ** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
4732 **
4733 ** If the Y parameter to sqlite3_free_filename(Y) is anything other
4734 ** than a NULL pointer or a pointer previously acquired from
4735 ** sqlite3_create_filename(), then bad things such as heap
4736 ** corruption or segfaults may occur. The value Y should be
@@ -14502,11 +14537,10 @@
14537 typedef struct BusyHandler BusyHandler;
14538 struct BusyHandler {
14539 int (*xBusyHandler)(void *,int); /* The busy callback */
14540 void *pBusyArg; /* First arg to busy callback */
14541 int nBusy; /* Incremented with each busy call */
 
14542 };
14543
14544 /*
14545 ** Name of the master database table. The master database table
14546 ** is a special table that holds the names and attributes of all
@@ -15022,13 +15056,11 @@
15056 #ifndef NDEBUG
15057 SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
15058 #endif
15059 SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
15060
 
15061 SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
 
15062
15063 #ifdef SQLITE_TEST
15064 SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
15065 SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
15066 #endif
@@ -15599,10 +15631,13 @@
15631
15632 SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
15633 SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
15634
15635 SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
15636 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
15637 SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*);
15638 #endif
15639
15640 /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
15641 ** each VDBE opcode.
15642 **
15643 ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
@@ -15884,17 +15919,25 @@
15919 SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
15920 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
15921 SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
15922 SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
15923 # ifdef SQLITE_ENABLE_SNAPSHOT
15924 SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot);
15925 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot);
15926 SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
15927 SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
15928 SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
15929 # endif
15930 #endif
15931
15932 #if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT)
15933 SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager*, int);
15934 SQLITE_PRIVATE void sqlite3PagerWalDb(Pager*, sqlite3*);
15935 #else
15936 # define sqlite3PagerWalWriteLock(y,z) SQLITE_OK
15937 # define sqlite3PagerWalDb(x,y)
15938 #endif
15939
15940 #ifdef SQLITE_DIRECT_OVERFLOW_READ
15941 SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
15942 #endif
15943
@@ -15917,15 +15960,10 @@
15960 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
15961 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
15962 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
15963 SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
15964 SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
 
 
 
 
 
15965
15966 /* Functions used to truncate the database file. */
15967 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
15968
15969 SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
@@ -16855,10 +16893,11 @@
16893 Hash aFunc; /* Hash table of connection functions */
16894 Hash aCollSeq; /* All collating sequences */
16895 BusyHandler busyHandler; /* Busy callback */
16896 Db aDbStatic[2]; /* Static space for the 2 default backends */
16897 Savepoint *pSavepoint; /* List of active savepoints */
16898 int nAnalysisLimit; /* Number of index rows to ANALYZE */
16899 int busyTimeout; /* Busy handler timeout, in msec */
16900 int nSavepoint; /* Number of non-transaction savepoints */
16901 int nStatement; /* Number of nested statement-transactions */
16902 i64 nDeferredCons; /* Net deferred constraints this transaction. */
16903 i64 nDeferredImmCons; /* Net deferred immediate constraints */
@@ -19900,11 +19939,11 @@
19939 SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*);
19940 SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
19941 SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
19942 SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
19943 SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
19944 SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
19945 SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
19946 SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
19947 SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
19948 SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
19949 SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
@@ -20636,11 +20675,12 @@
20675 /*
20676 ** VDBE_DISPLAY_P4 is true or false depending on whether or not the
20677 ** "explain" P4 display logic is enabled.
20678 */
20679 #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
20680 || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
20681 || defined(SQLITE_ENABLE_BYTECODE_VTAB)
20682 # define VDBE_DISPLAY_P4 1
20683 #else
20684 # define VDBE_DISPLAY_P4 0
20685 #endif
20686
@@ -21101,11 +21141,18 @@
21141
21142 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
21143 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
21144 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
21145 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
21146 #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
21147 SQLITE_PRIVATE int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**);
21148 SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3*,Op*);
21149 #endif
21150 #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
21151 SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*);
21152 #endif
21153 #if !defined(SQLITE_OMIT_EXPLAIN)
21154 SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
21155 #endif
21156 SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
21157 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
21158 SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -21143,11 +21190,11 @@
21190 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
21191 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
21192 #ifndef SQLITE_OMIT_WINDOWFUNC
21193 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
21194 #endif
21195 #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
21196 SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
21197 #endif
21198 SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
21199 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
21200 SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
@@ -27316,11 +27363,11 @@
27363 if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
27364 n = mem0.hardLimit;
27365 }
27366 mem0.alarmThreshold = n;
27367 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
27368 AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
27369 sqlite3_mutex_leave(mem0.mutex);
27370 excess = sqlite3_memory_used() - n;
27371 if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
27372 return priorLimit;
27373 }
@@ -27384,11 +27431,11 @@
27431 ** Return true if the heap is currently under memory pressure - in other
27432 ** words if the amount of heap used is close to the limit set by
27433 ** sqlite3_soft_heap_limit().
27434 */
27435 SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
27436 return AtomicLoad(&mem0.nearlyFull);
27437 }
27438
27439 /*
27440 ** Deinitialize the memory allocation subsystem.
27441 */
@@ -27448,21 +27495,21 @@
27495
27496 sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
27497 if( mem0.alarmThreshold>0 ){
27498 sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
27499 if( nUsed >= mem0.alarmThreshold - nFull ){
27500 AtomicStore(&mem0.nearlyFull, 1);
27501 sqlite3MallocAlarm(nFull);
27502 if( mem0.hardLimit ){
27503 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
27504 if( nUsed >= mem0.hardLimit - nFull ){
27505 *pp = 0;
27506 return;
27507 }
27508 }
27509 }else{
27510 AtomicStore(&mem0.nearlyFull, 0);
27511 }
27512 }
27513 p = sqlite3GlobalConfig.m.xMalloc(nFull);
27514 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
27515 if( p==0 && mem0.alarmThreshold>0 ){
@@ -27687,14 +27734,16 @@
27734 if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
27735 mem0.alarmThreshold-nDiff ){
27736 sqlite3MallocAlarm(nDiff);
27737 }
27738 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
27739 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
27740 if( pNew==0 && mem0.alarmThreshold>0 ){
27741 sqlite3MallocAlarm((int)nBytes);
27742 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
27743 }
27744 #endif
27745 if( pNew ){
27746 nNew = sqlite3MallocSize(pNew);
27747 sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
27748 }
27749 sqlite3_mutex_leave(mem0.mutex);
@@ -34928,20 +34977,21 @@
34977 static int osSetPosixAdvisoryLock(
34978 int h, /* The file descriptor on which to take the lock */
34979 struct flock *pLock, /* The description of the lock */
34980 unixFile *pFile /* Structure holding timeout value */
34981 ){
34982 int tm = pFile->iBusyTimeout;
34983 int rc = osFcntl(h,F_SETLK,pLock);
34984 while( rc<0 && tm>0 ){
34985 /* On systems that support some kind of blocking file lock with a timeout,
34986 ** make appropriate changes here to invoke that blocking file lock. On
34987 ** generic posix, however, there is no such API. So we simply try the
34988 ** lock once every millisecond until either the timeout expires, or until
34989 ** the lock is obtained. */
34990 usleep(1000);
34991 rc = osFcntl(h,F_SETLK,pLock);
34992 tm--;
34993 }
34994 return rc;
34995 }
34996 #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
34997
@@ -37679,17 +37729,24 @@
37729
37730 /* Locks are within range */
37731 assert( n>=1 && n<=SQLITE_SHM_NLOCK );
37732
37733 if( pShmNode->hShm>=0 ){
37734 int res;
37735 /* Initialize the locking parameters */
37736 f.l_type = lockType;
37737 f.l_whence = SEEK_SET;
37738 f.l_start = ofst;
37739 f.l_len = n;
37740 res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
37741 if( res==-1 ){
37742 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
37743 rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
37744 #else
37745 rc = SQLITE_BUSY;
37746 #endif
37747 }
37748 }
37749
37750 /* Update the global lock state and do debug tracing */
37751 #ifdef SQLITE_DEBUG
37752 { u16 mask;
@@ -38182,26 +38239,27 @@
38239 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
38240 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
38241 assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
38242 assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
38243
38244 /* Check that, if this to be a blocking lock, no locks that occur later
38245 ** in the following list than the lock being obtained are already held:
38246 **
38247 ** 1. Checkpointer lock (ofst==1).
38248 ** 2. Write lock (ofst==0).
38249 ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
 
38250 **
38251 ** In other words, if this is a blocking lock, none of the locks that
38252 ** occur later in the above list than the lock being obtained may be
38253 ** held. */
38254 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
38255 assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
38256 (ofst!=2) /* not RECOVER */
38257 && (ofst!=1 || (p->exclMask|p->sharedMask)==0)
38258 && (ofst!=0 || (p->exclMask|p->sharedMask)<3)
38259 && (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
38260 ));
38261 #endif
38262
38263 mask = (1<<(ofst+n)) - (1<<ofst);
38264 assert( n>1 || mask==(1<<ofst) );
38265 sqlite3_mutex_enter(pShmNode->pShmMutex);
@@ -51505,10 +51563,15 @@
51563 SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
51564 #endif
51565
51566 /* Return the sqlite3_file object for the WAL file */
51567 SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
51568
51569 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
51570 SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock);
51571 SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db);
51572 #endif
51573
51574 #endif /* ifndef SQLITE_OMIT_WAL */
51575 #endif /* SQLITE_WAL_H */
51576
51577 /************** End of wal.h *************************************************/
@@ -54026,13 +54089,16 @@
54089 }
54090 if( exists ){
54091 /* One of the journals pointed to by the master journal exists.
54092 ** Open it and check if it points at the master journal. If
54093 ** so, return without deleting the master journal file.
54094 ** NB: zJournal is really a MAIN_JOURNAL. But call it a
54095 ** MASTER_JOURNAL here so that the VFS will not send the zJournal
54096 ** name into sqlite3_database_file_object().
54097 */
54098 int c;
54099 int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
54100 rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
54101 if( rc!=SQLITE_OK ){
54102 goto delmaster_out;
54103 }
54104
@@ -56232,10 +56298,11 @@
56298 ** Pager object (sizeof(Pager) bytes)
56299 ** PCache object (sqlite3PcacheSize() bytes)
56300 ** Database file handle (pVfs->szOsFile bytes)
56301 ** Sub-journal file handle (journalFileSize bytes)
56302 ** Main journal file handle (journalFileSize bytes)
56303 ** Ptr back to the Pager (sizeof(Pager*) bytes)
56304 ** \0\0\0\0 database prefix (4 bytes)
56305 ** Database file name (nPathname+1 bytes)
56306 ** URI query parameters (nUriByte bytes)
56307 ** Journal filename (nPathname+8+1 bytes)
56308 ** WAL filename (nPathname+4+1 bytes)
@@ -56271,10 +56338,11 @@
56338 pPtr = (u8 *)sqlite3MallocZero(
56339 ROUND8(sizeof(*pPager)) + /* Pager structure */
56340 ROUND8(pcacheSize) + /* PCache object */
56341 ROUND8(pVfs->szOsFile) + /* The main db file */
56342 journalFileSize * 2 + /* The two journal files */
56343 sizeof(pPager) + /* Space to hold a pointer */
56344 4 + /* Database prefix */
56345 nPathname + 1 + /* database filename */
56346 nUriByte + /* query parameters */
56347 nPathname + 8 + 1 + /* Journal filename */
56348 #ifndef SQLITE_OMIT_WAL
@@ -56291,10 +56359,11 @@
56359 pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
56360 pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
56361 pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
56362 pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
56363 assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
56364 memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
56365
56366 /* Fill in the Pager.zFilename and pPager.zQueryParam fields */
56367 pPtr += 4; /* Skip zero prefix */
56368 pPager->zFilename = (char*)pPtr;
56369 if( nPathname>0 ){
@@ -56491,10 +56560,23 @@
56560
56561 *ppPager = pPager;
56562 return SQLITE_OK;
56563 }
56564
56565 /*
56566 ** Return the sqlite3_file for the main database given the name
56567 ** of the corresonding WAL or Journal name as passed into
56568 ** xOpen.
56569 */
56570 SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){
56571 Pager *pPager;
56572 while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
56573 zName--;
56574 }
56575 pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
56576 return pPager->fd;
56577 }
56578
56579
56580 /*
56581 ** This function is called after transitioning from PAGER_UNLOCK to
56582 ** PAGER_SHARED state. It tests if there is a hot journal present in
@@ -57176,11 +57258,10 @@
57258 Pager *pPager;
57259 assert( pPg!=0 );
57260 assert( pPg->pgno==1 );
57261 assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
57262 pPager = pPg->pPager;
 
57263 sqlite3PcacheRelease(pPg);
57264 pagerUnlockIfUnused(pPager);
57265 }
57266
57267 /*
@@ -58469,20 +58550,10 @@
58550 */
58551 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
58552 return pPager->fd;
58553 }
58554
 
 
 
 
 
 
 
 
 
 
58555 /*
58556 ** Return the file handle for the journal file (if it exists).
58557 ** This will be either the rollback journal or the WAL file.
58558 */
58559 SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
@@ -58892,11 +58963,10 @@
58963 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
58964 pPager->pBusyHandlerArg,
58965 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
58966 pnLog, pnCkpt
58967 );
 
58968 }
58969 return rc;
58970 }
58971
58972 SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
@@ -59057,11 +59127,35 @@
59127 }
59128 }
59129 return rc;
59130 }
59131
59132 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
59133 /*
59134 ** If pager pPager is a wal-mode database not in exclusive locking mode,
59135 ** invoke the sqlite3WalWriteLock() function on the associated Wal object
59136 ** with the same db and bLock parameters as were passed to this function.
59137 ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
59138 */
59139 SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){
59140 int rc = SQLITE_OK;
59141 if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){
59142 rc = sqlite3WalWriteLock(pPager->pWal, bLock);
59143 }
59144 return rc;
59145 }
59146
59147 /*
59148 ** Set the database handle used by the wal layer to determine if
59149 ** blocking locks are required.
59150 */
59151 SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
59152 if( pagerUseWal(pPager) ){
59153 sqlite3WalDb(pPager->pWal, db);
59154 }
59155 }
59156 #endif
59157
59158 #ifdef SQLITE_ENABLE_SNAPSHOT
59159 /*
59160 ** If this is a WAL database, obtain a snapshot handle for the snapshot
59161 ** currently open. Otherwise, return an error.
@@ -59077,11 +59171,14 @@
59171 /*
59172 ** If this is a WAL database, store a pointer to pSnapshot. Next time a
59173 ** read transaction is opened, attempt to read from the snapshot it
59174 ** identifies. If this is not a WAL database, return an error.
59175 */
59176 SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(
59177 Pager *pPager,
59178 sqlite3_snapshot *pSnapshot
59179 ){
59180 int rc = SQLITE_OK;
59181 if( pPager->pWal ){
59182 sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
59183 }else{
59184 rc = SQLITE_ERROR;
@@ -59622,10 +59719,13 @@
59719 u8 lockError; /* True if a locking error has occurred */
59720 #endif
59721 #ifdef SQLITE_ENABLE_SNAPSHOT
59722 WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
59723 #endif
59724 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
59725 sqlite3 *db;
59726 #endif
59727 };
59728
59729 /*
59730 ** Candidate values for Wal.exclusiveMode.
59731 */
@@ -59995,11 +60095,11 @@
60095 if( pWal->exclusiveMode ) return SQLITE_OK;
60096 rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
60097 SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
60098 WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
60099 walLockName(lockIdx), rc ? "failed" : "ok"));
60100 VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
60101 return rc;
60102 }
60103 static void walUnlockShared(Wal *pWal, int lockIdx){
60104 if( pWal->exclusiveMode ) return;
60105 (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
@@ -60011,11 +60111,11 @@
60111 if( pWal->exclusiveMode ) return SQLITE_OK;
60112 rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
60113 SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
60114 WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
60115 walLockName(lockIdx), n, rc ? "failed" : "ok"));
60116 VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
60117 return rc;
60118 }
60119 static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
60120 if( pWal->exclusiveMode ) return;
60121 (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
@@ -60283,15 +60383,10 @@
60383 int rc; /* Return Code */
60384 i64 nSize; /* Size of log file */
60385 u32 aFrameCksum[2] = {0, 0};
60386 int iLock; /* Lock offset to lock for checkpoint */
60387
 
 
 
 
 
60388 /* Obtain an exclusive lock on all byte in the locking range not already
60389 ** locked by the caller. The caller is guaranteed to have locked the
60390 ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
60391 ** If successful, the same bytes that are locked here are unlocked before
60392 ** this function returns.
@@ -60835,10 +60930,93 @@
60930 p = 0;
60931 }
60932 *pp = p;
60933 return rc;
60934 }
60935
60936 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
60937 /*
60938 ** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
60939 ** they are supported by the VFS, and (b) the database handle is configured
60940 ** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
60941 ** or 0 otherwise.
60942 */
60943 static int walEnableBlocking(Wal *pWal){
60944 int res = 0;
60945 if( pWal->db ){
60946 int tmout = pWal->db->busyTimeout;
60947 if( tmout ){
60948 int rc;
60949 rc = sqlite3OsFileControl(
60950 pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
60951 );
60952 res = (rc==SQLITE_OK);
60953 }
60954 }
60955 return res;
60956 }
60957
60958 /*
60959 ** Disable blocking locks.
60960 */
60961 static void walDisableBlocking(Wal *pWal){
60962 int tmout = 0;
60963 sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
60964 }
60965
60966 /*
60967 ** If parameter bLock is true, attempt to enable blocking locks, take
60968 ** the WRITER lock, and then disable blocking locks. If blocking locks
60969 ** cannot be enabled, no attempt to obtain the WRITER lock is made. Return
60970 ** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not
60971 ** an error if blocking locks can not be enabled.
60972 **
60973 ** If the bLock parameter is false and the WRITER lock is held, release it.
60974 */
60975 SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){
60976 int rc = SQLITE_OK;
60977 assert( pWal->readLock<0 || bLock==0 );
60978 if( bLock ){
60979 assert( pWal->db );
60980 if( walEnableBlocking(pWal) ){
60981 rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
60982 if( rc==SQLITE_OK ){
60983 pWal->writeLock = 1;
60984 }
60985 walDisableBlocking(pWal);
60986 }
60987 }else if( pWal->writeLock ){
60988 walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
60989 pWal->writeLock = 0;
60990 }
60991 return rc;
60992 }
60993
60994 /*
60995 ** Set the database handle used to determine if blocking locks are required.
60996 */
60997 SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
60998 pWal->db = db;
60999 }
61000
61001 /*
61002 ** Take an exclusive WRITE lock. Blocking if so configured.
61003 */
61004 static int walLockWriter(Wal *pWal){
61005 int rc;
61006 walEnableBlocking(pWal);
61007 rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
61008 walDisableBlocking(pWal);
61009 return rc;
61010 }
61011 #else
61012 # define walEnableBlocking(x) 0
61013 # define walDisableBlocking(x)
61014 # define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
61015 # define sqlite3WalDb(pWal, db)
61016 #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
61017
61018
61019 /*
61020 ** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
61021 ** n. If the attempt fails and parameter xBusy is not NULL, then it is a
61022 ** busy-handler function. Invoke it and retry the lock until either the
@@ -60853,10 +61031,16 @@
61031 ){
61032 int rc;
61033 do {
61034 rc = walLockExclusive(pWal, lockIdx, n);
61035 }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
61036 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
61037 if( rc==SQLITE_BUSY_TIMEOUT ){
61038 walDisableBlocking(pWal);
61039 rc = SQLITE_BUSY;
61040 }
61041 #endif
61042 return rc;
61043 }
61044
61045 /*
61046 ** The cache of the wal-index header must be valid to call this function.
@@ -61023,10 +61207,11 @@
61207 ** about the eventual size of the db file to the VFS layer.
61208 */
61209 if( rc==SQLITE_OK ){
61210 i64 nReq = ((i64)mxPage * szPage);
61211 i64 nSize; /* Current size of database file */
61212 sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
61213 rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
61214 if( rc==SQLITE_OK && nSize<nReq ){
61215 sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
61216 }
61217 }
@@ -61050,10 +61235,11 @@
61235 iOffset = (iDbpage-1)*(i64)szPage;
61236 testcase( IS_BIG_INT(iOffset) );
61237 rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
61238 if( rc!=SQLITE_OK ) break;
61239 }
61240 sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
61241
61242 /* If work was actually accomplished... */
61243 if( rc==SQLITE_OK ){
61244 if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
61245 i64 szDb = pWal->hdr.nPage*(i64)szPage;
@@ -61061,14 +61247,10 @@
61247 rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
61248 if( rc==SQLITE_OK ){
61249 rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
61250 }
61251 }
 
 
 
 
61252 if( rc==SQLITE_OK ){
61253 pInfo->nBackfill = mxSafeFrame;
61254 }
61255 }
61256
@@ -61334,32 +61516,36 @@
61516 badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
61517
61518 /* If the first attempt failed, it might have been due to a race
61519 ** with a writer. So get a WRITE lock and try again.
61520 */
 
61521 if( badHdr ){
61522 if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
61523 if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
61524 walUnlockShared(pWal, WAL_WRITE_LOCK);
61525 rc = SQLITE_READONLY_RECOVERY;
61526 }
61527 }else{
61528 int bWriteLock = pWal->writeLock;
61529 if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
61530 pWal->writeLock = 1;
61531 if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
61532 badHdr = walIndexTryHdr(pWal, pChanged);
61533 if( badHdr ){
61534 /* If the wal-index header is still malformed even while holding
61535 ** a WRITE lock, it can only mean that the header is corrupted and
61536 ** needs to be reconstructed. So run recovery to do exactly that.
61537 */
61538 rc = walIndexRecover(pWal);
61539 *pChanged = 1;
61540 }
61541 }
61542 if( bWriteLock==0 ){
61543 pWal->writeLock = 0;
61544 walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
61545 }
61546 }
61547 }
61548 }
61549
61550 /* If the header is read successfully, check the version number to make
61551 ** sure the wal-index was not constructed with some future format that
@@ -61907,26 +62093,38 @@
62093 ** needs to be flushed.
62094 */
62095 SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
62096 int rc; /* Return code */
62097 int cnt = 0; /* Number of TryBeginRead attempts */
62098
62099 assert( pWal->ckptLock==0 );
 
62100
62101 #ifdef SQLITE_ENABLE_SNAPSHOT
62102 int bChanged = 0;
62103 WalIndexHdr *pSnapshot = pWal->pSnapshot;
62104 if( pSnapshot ){
62105 if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
62106 bChanged = 1;
62107 }
62108
62109 /* It is possible that there is a checkpointer thread running
62110 ** concurrent with this code. If this is the case, it may be that the
62111 ** checkpointer has already determined that it will checkpoint
62112 ** snapshot X, where X is later in the wal file than pSnapshot, but
62113 ** has not yet set the pInfo->nBackfillAttempted variable to indicate
62114 ** its intent. To avoid the race condition this leads to, ensure that
62115 ** there is no checkpointer process by taking a shared CKPT lock
62116 ** before checking pInfo->nBackfillAttempted. */
62117 (void)walEnableBlocking(pWal);
62118 rc = walLockShared(pWal, WAL_CKPT_LOCK);
62119 walDisableBlocking(pWal);
62120
62121 if( rc!=SQLITE_OK ){
62122 return rc;
62123 }
62124 pWal->ckptLock = 1;
62125 }
62126 #endif
62127
62128 do{
62129 rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
62130 }while( rc==WAL_RETRY );
@@ -61933,20 +62131,10 @@
62131 testcase( (rc&0xff)==SQLITE_BUSY );
62132 testcase( (rc&0xff)==SQLITE_IOERR );
62133 testcase( rc==SQLITE_PROTOCOL );
62134 testcase( rc==SQLITE_OK );
62135
 
 
 
 
 
 
 
 
 
 
62136 #ifdef SQLITE_ENABLE_SNAPSHOT
62137 if( rc==SQLITE_OK ){
62138 if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
62139 /* At this point the client has a lock on an aReadMark[] slot holding
62140 ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
@@ -61964,52 +62152,46 @@
62152 volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
62153
62154 assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
62155 assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
62156
62157 /* Check that the wal file has not been wrapped. Assuming that it has
62158 ** not, also check that no checkpointer has attempted to checkpoint any
62159 ** frames beyond pSnapshot->mxFrame. If either of these conditions are
62160 ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
62161 ** with *pSnapshot and set *pChanged as appropriate for opening the
62162 ** snapshot. */
62163 if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
62164 && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
62165 ){
62166 assert( pWal->readLock>0 );
62167 memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
62168 *pChanged = bChanged;
62169 }else{
62170 rc = SQLITE_ERROR_SNAPSHOT;
62171 }
62172
62173 /* A client using a non-current snapshot may not ignore any frames
62174 ** from the start of the wal file. This is because, for a system
62175 ** where (minFrame < iSnapshot < maxFrame), a checkpointer may
62176 ** have omitted to checkpoint a frame earlier than minFrame in
62177 ** the file because there exists a frame after iSnapshot that
62178 ** is the same database page. */
62179 pWal->minFrame = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
62180
62181 if( rc!=SQLITE_OK ){
62182 sqlite3WalEndReadTransaction(pWal);
62183 }
62184 }
62185 }
62186
62187 /* Release the shared CKPT lock obtained above. */
62188 if( pWal->ckptLock ){
62189 assert( pSnapshot );
62190 walUnlockShared(pWal, WAL_CKPT_LOCK);
62191 pWal->ckptLock = 0;
62192 }
62193 #endif
62194 return rc;
62195 }
62196
62197 /*
@@ -62175,10 +62357,20 @@
62357 **
62358 ** There can only be a single writer active at a time.
62359 */
62360 SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
62361 int rc;
62362
62363 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
62364 /* If the write-lock is already held, then it was obtained before the
62365 ** read-transaction was even opened, making this call a no-op.
62366 ** Return early. */
62367 if( pWal->writeLock ){
62368 assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
62369 return SQLITE_OK;
62370 }
62371 #endif
62372
62373 /* Cannot start a write transaction without first holding a read
62374 ** transaction. */
62375 assert( pWal->readLock>=0 );
62376 assert( pWal->writeLock==0 && pWal->iReCksum==0 );
@@ -62751,50 +62943,57 @@
62943 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
62944 assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
62945
62946 if( pWal->readOnly ) return SQLITE_READONLY;
62947 WALTRACE(("WAL%p: checkpoint begins\n", pWal));
62948
62949 /* Enable blocking locks, if possible. If blocking locks are successfully
62950 ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
62951 sqlite3WalDb(pWal, db);
62952 (void)walEnableBlocking(pWal);
62953
62954 /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
62955 ** "checkpoint" lock on the database file.
62956 ** EVIDENCE-OF: R-10421-19736 If any other process is running a
62957 ** checkpoint operation at the same time, the lock cannot be obtained and
62958 ** SQLITE_BUSY is returned.
62959 ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
62960 ** it will not be invoked in this case.
62961 */
62962 rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
62963 testcase( rc==SQLITE_BUSY );
62964 testcase( rc!=SQLITE_OK && xBusy2!=0 );
62965 if( rc==SQLITE_OK ){
62966 pWal->ckptLock = 1;
62967
62968 /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
62969 ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
62970 ** file.
62971 **
62972 ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
62973 ** immediately, and a busy-handler is configured, it is invoked and the
62974 ** writer lock retried until either the busy-handler returns 0 or the
62975 ** lock is successfully obtained.
62976 */
62977 if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
62978 rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
62979 if( rc==SQLITE_OK ){
62980 pWal->writeLock = 1;
62981 }else if( rc==SQLITE_BUSY ){
62982 eMode2 = SQLITE_CHECKPOINT_PASSIVE;
62983 xBusy2 = 0;
62984 rc = SQLITE_OK;
62985 }
62986 }
62987 }
62988
 
 
 
 
 
 
62989
62990 /* Read the wal-index header. */
62991 if( rc==SQLITE_OK ){
62992 walDisableBlocking(pWal);
62993 rc = walIndexReadHdr(pWal, &isChanged);
62994 (void)walEnableBlocking(pWal);
62995 if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
62996 sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
62997 }
62998 }
62999
@@ -62821,16 +63020,24 @@
63020 ** next time the pager opens a snapshot on this database it knows that
63021 ** the cache needs to be reset.
63022 */
63023 memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
63024 }
63025
63026 walDisableBlocking(pWal);
63027 sqlite3WalDb(pWal, 0);
63028
63029 /* Release the locks. */
63030 sqlite3WalEndWriteTransaction(pWal);
63031 if( pWal->ckptLock ){
63032 walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
63033 pWal->ckptLock = 0;
63034 }
63035 WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
63036 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
63037 if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
63038 #endif
63039 return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
63040 }
63041
63042 /* Return the value to pass to a sqlite3_wal_hook callback, the
63043 ** number of frames in the WAL at the point of the last commit since
@@ -62943,11 +63150,14 @@
63150 return rc;
63151 }
63152
63153 /* Try to open on pSnapshot when the next read-transaction starts
63154 */
63155 SQLITE_PRIVATE void sqlite3WalSnapshotOpen(
63156 Wal *pWal,
63157 sqlite3_snapshot *pSnapshot
63158 ){
63159 pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
63160 }
63161
63162 /*
63163 ** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
@@ -63462,11 +63672,11 @@
63672 u8 incrVacuum; /* True if incr-vacuum is enabled */
63673 u8 bDoTruncate; /* True to truncate db on commit */
63674 #endif
63675 u8 inTransaction; /* Transaction state */
63676 u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
63677 u8 nReserveWanted; /* Desired number of extra bytes per page */
63678 u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
63679 u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
63680 u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
63681 u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */
63682 u16 minLeaf; /* Minimum local payload in a LEAFDATA table */
@@ -66356,12 +66566,11 @@
66566 */
66567 static int btreeInvokeBusyHandler(void *pArg){
66568 BtShared *pBt = (BtShared*)pArg;
66569 assert( pBt->db );
66570 assert( sqlite3_mutex_held(pBt->db->mutex) );
66571 return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
 
66572 }
66573
66574 /*
66575 ** Open a database file.
66576 **
@@ -66908,23 +67117,21 @@
67117 ** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
67118 ** and autovacuum mode can no longer be changed.
67119 */
67120 SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
67121 int rc = SQLITE_OK;
67122 int x;
67123 BtShared *pBt = p->pBt;
67124 assert( nReserve>=0 && nReserve<=255 );
67125 sqlite3BtreeEnter(p);
67126 pBt->nReserveWanted = nReserve;
67127 x = pBt->pageSize - pBt->usableSize;
67128 if( nReserve<x ) nReserve = x;
67129 if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
67130 sqlite3BtreeLeave(p);
67131 return SQLITE_READONLY;
67132 }
 
 
 
67133 assert( nReserve>=0 && nReserve<=255 );
67134 if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
67135 ((pageSize-1)&pageSize)==0 ){
67136 assert( (pageSize & 7)==0 );
67137 assert( !pBt->pCursor );
@@ -66965,18 +67172,22 @@
67172
67173 /*
67174 ** Return the number of bytes of space at the end of every page that
67175 ** are intentually left unused. This is the "reserved" space that is
67176 ** sometimes used by extensions.
67177 **
67178 ** The value returned is the larger of the current reserve size and
67179 ** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
67180 ** The amount of reserve can only grow - never shrink.
67181 */
67182 SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){
67183 int n1, n2;
67184 sqlite3BtreeEnter(p);
67185 n1 = (int)p->pBt->nReserveWanted;
67186 n2 = sqlite3BtreeGetReserveNoMutex(p);
67187 sqlite3BtreeLeave(p);
67188 return n1>n2 ? n1 : n2;
67189 }
67190
67191
67192 /*
67193 ** Set the maximum page count for a database if mxPage is positive.
@@ -67422,10 +67633,11 @@
67633 ** when A already has a read lock, we encourage A to give up and let B
67634 ** proceed.
67635 */
67636 SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
67637 BtShared *pBt = p->pBt;
67638 Pager *pPager = pBt->pPager;
67639 int rc = SQLITE_OK;
67640
67641 sqlite3BtreeEnter(p);
67642 btreeIntegrity(p);
67643
@@ -67437,11 +67649,11 @@
67649 goto trans_begun;
67650 }
67651 assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
67652
67653 if( (p->db->flags & SQLITE_ResetDatabase)
67654 && sqlite3PagerIsreadonly(pPager)==0
67655 ){
67656 pBt->btsFlags &= ~BTS_READ_ONLY;
67657 }
67658
67659 /* Write transactions are not possible on a read-only database */
@@ -67485,10 +67697,22 @@
67697 if( SQLITE_OK!=rc ) goto trans_begun;
67698
67699 pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
67700 if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
67701 do {
67702 sqlite3PagerWalDb(pPager, p->db);
67703
67704 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67705 /* If transitioning from no transaction directly to a write transaction,
67706 ** block for the WRITER lock first if possible. */
67707 if( pBt->pPage1==0 && wrflag ){
67708 assert( pBt->inTransaction==TRANS_NONE );
67709 rc = sqlite3PagerWalWriteLock(pPager, 1);
67710 if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
67711 }
67712 #endif
67713
67714 /* Call lockBtree() until either pBt->pPage1 is populated or
67715 ** lockBtree() returns something other than SQLITE_OK. lockBtree()
67716 ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
67717 ** reading page 1 it discovers that the page-size of the database
67718 ** file is not pBt->pageSize. In this case lockBtree() will update
@@ -67498,11 +67722,11 @@
67722
67723 if( rc==SQLITE_OK && wrflag ){
67724 if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
67725 rc = SQLITE_READONLY;
67726 }else{
67727 rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db));
67728 if( rc==SQLITE_OK ){
67729 rc = newDatabase(pBt);
67730 }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
67731 /* if there was no transaction opened when this function was
67732 ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
@@ -67511,15 +67735,19 @@
67735 }
67736 }
67737 }
67738
67739 if( rc!=SQLITE_OK ){
67740 (void)sqlite3PagerWalWriteLock(pPager, 0);
67741 unlockBtreeIfUnused(pBt);
67742 }
67743 }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
67744 btreeInvokeBusyHandler(pBt) );
67745 sqlite3PagerWalDb(pPager, 0);
67746 #ifdef SQLITE_ENABLE_SETLK_TIMEOUT
67747 if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
67748 #endif
67749
67750 if( rc==SQLITE_OK ){
67751 if( p->inTrans==TRANS_NONE ){
67752 pBt->nTransaction++;
67753 #ifndef SQLITE_OMIT_SHARED_CACHE
@@ -67567,11 +67795,11 @@
67795 if( wrflag ){
67796 /* This call makes sure that the pager has the correct number of
67797 ** open savepoints. If the second parameter is greater than 0 and
67798 ** the sub-journal is not already open, then it will be opened here.
67799 */
67800 rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint);
67801 }
67802 }
67803
67804 btreeIntegrity(p);
67805 sqlite3BtreeLeave(p);
@@ -71203,11 +71431,11 @@
71431
71432 /* Remove cells from the start and end of the page */
71433 assert( nCell>=0 );
71434 if( iOld<iNew ){
71435 int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
71436 if( NEVER(nShift>nCell) ) return SQLITE_CORRUPT_BKPT;
71437 memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
71438 nCell -= nShift;
71439 }
71440 if( iNewEnd < iOldEnd ){
71441 int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
@@ -73560,11 +73788,10 @@
73788 }
73789 sqlite3BtreeLeave(p);
73790 return rc;
73791 }
73792
 
73793 /*
73794 ** The first argument, pCur, is a cursor opened on some b-tree. Count the
73795 ** number of entries in the b-tree and write the result to *pnEntry.
73796 **
73797 ** SQLITE_OK is returned if the operation is successfully executed.
@@ -73633,11 +73860,10 @@
73860 }
73861
73862 /* An error has occurred. Return an error code. */
73863 return rc;
73864 }
 
73865
73866 /*
73867 ** Return the pager associated with a BTree. This routine is used for
73868 ** testing and debugging only.
73869 */
@@ -74684,11 +74910,11 @@
74910 ** Attempt to set the page size of the destination to match the page size
74911 ** of the source.
74912 */
74913 static int setDestPgsz(sqlite3_backup *p){
74914 int rc;
74915 rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
74916 return rc;
74917 }
74918
74919 /*
74920 ** Check that there is no open read-transaction on the b-tree passed as the
@@ -78709,24 +78935,23 @@
78935 ** "PX" -> "r[X]"
78936 ** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
78937 ** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
78938 ** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
78939 */
78940 SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
78941 sqlite3 *db, /* Optional - Oom error reporting only */
78942 const Op *pOp, /* The opcode to be commented */
78943 const char *zP4 /* Previously obtained value for P4 */
 
 
78944 ){
78945 const char *zOpName;
78946 const char *zSynopsis;
78947 int nOpName;
78948 int ii;
78949 char zAlt[50];
78950 StrAccum x;
 
78951
78952 sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
78953 zOpName = sqlite3OpcodeName(pOp->opcode);
78954 nOpName = sqlite3Strlen30(zOpName);
78955 if( zOpName[nOpName+1] ){
78956 int seenCom = 0;
78957 char c;
@@ -78789,14 +79014,16 @@
79014 sqlite3_str_appendf(&x, "; %s", pOp->zComment);
79015 }
79016 }else if( pOp->zComment ){
79017 sqlite3_str_appendall(&x, pOp->zComment);
79018 }
79019 if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
79020 sqlite3OomFault(db);
79021 }
79022 return sqlite3StrAccumFinish(&x);
79023 }
79024 #endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
79025
79026 #if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
79027 /*
79028 ** Translate the P4.pExpr value for an OP_CursorHint opcode into text
79029 ** that can be displayed in the P4 column of EXPLAIN output.
@@ -78873,15 +79100,15 @@
79100 #if VDBE_DISPLAY_P4
79101 /*
79102 ** Compute a string that describes the P4 parameter for an opcode.
79103 ** Use zTemp for any required temporary buffer space.
79104 */
79105 SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
79106 char *zP4 = 0;
79107 StrAccum x;
79108
79109 sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
79110 switch( pOp->p4type ){
79111 case P4_KEYINFO: {
79112 int j;
79113 KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
79114 assert( pKeyInfo->aSortFlags!=0 );
@@ -78961,40 +79188,36 @@
79188 int i;
79189 int *ai = pOp->p4.ai;
79190 int n = ai[0]; /* The first element of an INTARRAY is always the
79191 ** count of the number of elements to follow */
79192 for(i=1; i<=n; i++){
79193 sqlite3_str_appendf(&x, "%c%d", (i==1 ? '[' : ','), ai[i]);
79194 }
 
79195 sqlite3_str_append(&x, "]", 1);
79196 break;
79197 }
79198 case P4_SUBPROGRAM: {
79199 zP4 = "program";
79200 break;
79201 }
79202 case P4_DYNBLOB:
79203 case P4_ADVANCE: {
 
79204 break;
79205 }
79206 case P4_TABLE: {
79207 zP4 = pOp->p4.pTab->zName;
79208 break;
79209 }
79210 default: {
79211 zP4 = pOp->p4.z;
 
 
 
 
79212 }
79213 }
79214 if( zP4 ) sqlite3_str_appendall(&x, zP4);
79215 if( (x.accError & SQLITE_NOMEM)!=0 ){
79216 sqlite3OomFault(db);
79217 }
79218 return sqlite3StrAccumFinish(&x);
79219 }
79220 #endif /* VDBE_DISPLAY_P4 */
79221
79222 /*
79223 ** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
@@ -79080,28 +79303,32 @@
79303 /*
79304 ** Print a single opcode. This routine is used for debugging only.
79305 */
79306 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
79307 char *zP4;
79308 char *zCom;
79309 sqlite3 dummyDb;
79310 static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
79311 if( pOut==0 ) pOut = stdout;
79312 dummyDb.mallocFailed = 1;
79313 zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp);
79314 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
79315 zCom = sqlite3VdbeDisplayComment(0, pOp, zP4);
79316 #else
79317 zCom = 0;
79318 #endif
79319 /* NB: The sqlite3OpcodeName() function is implemented by code created
79320 ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
79321 ** information from the vdbe.c source text */
79322 fprintf(pOut, zFormat1, pc,
79323 sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3,
79324 zP4 ? zP4 : "", pOp->p5,
79325 zCom ? zCom : ""
79326 );
79327 fflush(pOut);
79328 sqlite3_free(zP4);
79329 sqlite3_free(zCom);
79330 }
79331 #endif
79332
79333 /*
79334 ** Initialize an array of N Mem element.
@@ -79188,10 +79415,125 @@
79415 assert( sqlite3VdbeFrameIsValid(pFrame) );
79416 pFrame->pParent = pFrame->v->pDelFrame;
79417 pFrame->v->pDelFrame = pFrame;
79418 }
79419
79420 #if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN)
79421 /*
79422 ** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN
79423 ** QUERY PLAN output.
79424 **
79425 ** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no
79426 ** more opcodes to be displayed.
79427 */
79428 SQLITE_PRIVATE int sqlite3VdbeNextOpcode(
79429 Vdbe *p, /* The statement being explained */
79430 Mem *pSub, /* Storage for keeping track of subprogram nesting */
79431 int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */
79432 int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */
79433 int *piAddr, /* OUT: Write index into (*paOp)[] here */
79434 Op **paOp /* OUT: Write the opcode array here */
79435 ){
79436 int nRow; /* Stop when row count reaches this */
79437 int nSub = 0; /* Number of sub-vdbes seen so far */
79438 SubProgram **apSub = 0; /* Array of sub-vdbes */
79439 int i; /* Next instruction address */
79440 int rc = SQLITE_OK; /* Result code */
79441 Op *aOp = 0; /* Opcode array */
79442 int iPc; /* Rowid. Copy of value in *piPc */
79443
79444 /* When the number of output rows reaches nRow, that means the
79445 ** listing has finished and sqlite3_step() should return SQLITE_DONE.
79446 ** nRow is the sum of the number of rows in the main program, plus
79447 ** the sum of the number of rows in all trigger subprograms encountered
79448 ** so far. The nRow value will increase as new trigger subprograms are
79449 ** encountered, but p->pc will eventually catch up to nRow.
79450 */
79451 nRow = p->nOp;
79452 if( pSub!=0 ){
79453 if( pSub->flags&MEM_Blob ){
79454 /* pSub is initiallly NULL. It is initialized to a BLOB by
79455 ** the P4_SUBPROGRAM processing logic below */
79456 nSub = pSub->n/sizeof(Vdbe*);
79457 apSub = (SubProgram **)pSub->z;
79458 }
79459 for(i=0; i<nSub; i++){
79460 nRow += apSub[i]->nOp;
79461 }
79462 }
79463 iPc = *piPc;
79464 while(1){ /* Loop exits via break */
79465 i = iPc++;
79466 if( i>=nRow ){
79467 p->rc = SQLITE_OK;
79468 rc = SQLITE_DONE;
79469 break;
79470 }
79471 if( i<p->nOp ){
79472 /* The rowid is small enough that we are still in the
79473 ** main program. */
79474 aOp = p->aOp;
79475 }else{
79476 /* We are currently listing subprograms. Figure out which one and
79477 ** pick up the appropriate opcode. */
79478 int j;
79479 i -= p->nOp;
79480 assert( apSub!=0 );
79481 assert( nSub>0 );
79482 for(j=0; i>=apSub[j]->nOp; j++){
79483 i -= apSub[j]->nOp;
79484 assert( i<apSub[j]->nOp || j+1<nSub );
79485 }
79486 aOp = apSub[j]->aOp;
79487 }
79488
79489 /* When an OP_Program opcode is encounter (the only opcode that has
79490 ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
79491 ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
79492 ** has not already been seen.
79493 */
79494 if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){
79495 int nByte = (nSub+1)*sizeof(SubProgram*);
79496 int j;
79497 for(j=0; j<nSub; j++){
79498 if( apSub[j]==aOp[i].p4.pProgram ) break;
79499 }
79500 if( j==nSub ){
79501 p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
79502 if( p->rc!=SQLITE_OK ){
79503 rc = SQLITE_ERROR;
79504 break;
79505 }
79506 apSub = (SubProgram **)pSub->z;
79507 apSub[nSub++] = aOp[i].p4.pProgram;
79508 MemSetTypeFlag(pSub, MEM_Blob);
79509 pSub->n = nSub*sizeof(SubProgram*);
79510 nRow += aOp[i].p4.pProgram->nOp;
79511 }
79512 }
79513 if( eMode==0 ) break;
79514 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
79515 if( eMode==2 ){
79516 Op *pOp = aOp + i;
79517 if( pOp->opcode==OP_OpenRead ) break;
79518 if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break;
79519 if( pOp->opcode==OP_ReopenIdx ) break;
79520 }else
79521 #endif
79522 {
79523 assert( eMode==1 );
79524 if( aOp[i].opcode==OP_Explain ) break;
79525 if( aOp[i].opcode==OP_Init && iPc>1 ) break;
79526 }
79527 }
79528 *piPc = iPc;
79529 *piAddr = i;
79530 *paOp = aOp;
79531 return rc;
79532 }
79533 #endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */
79534
79535
79536 /*
79537 ** Delete a VdbeFrame object and its contents. VdbeFrame objects are
79538 ** allocated by the OP_Program opcode in sqlite3VdbeExec().
79539 */
@@ -79228,20 +79570,18 @@
79570 ** the trigger subprograms are listed one by one.
79571 */
79572 SQLITE_PRIVATE int sqlite3VdbeList(
79573 Vdbe *p /* The VDBE */
79574 ){
 
 
 
79575 Mem *pSub = 0; /* Memory cell hold array of subprogs */
79576 sqlite3 *db = p->db; /* The database connection */
79577 int i; /* Loop counter */
79578 int rc = SQLITE_OK; /* Return code */
79579 Mem *pMem = &p->aMem[1]; /* First Mem of result set */
79580 int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
79581 Op *aOp; /* Array of opcodes */
79582 Op *pOp; /* Current opcode */
79583
79584 assert( p->explain );
79585 assert( p->magic==VDBE_MAGIC_RUN );
79586 assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
79587
@@ -79257,166 +79597,66 @@
79597 ** sqlite3_column_text16() failed. */
79598 sqlite3OomFault(db);
79599 return SQLITE_ERROR;
79600 }
79601
 
 
 
 
 
 
 
 
79602 if( bListSubprogs ){
79603 /* The first 8 memory cells are used for the result set. So we will
79604 ** commandeer the 9th cell to use as storage for an array of pointers
79605 ** to trigger subprograms. The VDBE is guaranteed to have at least 9
79606 ** cells. */
79607 assert( p->nMem>9 );
79608 pSub = &p->aMem[9];
79609 }else{
79610 pSub = 0;
79611 }
79612
79613 /* Figure out which opcode is next to display */
79614 rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);
79615
79616 if( rc==SQLITE_OK ){
79617 pOp = aOp + i;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79618 if( AtomicLoad(&db->u1.isInterrupted) ){
79619 p->rc = SQLITE_INTERRUPT;
79620 rc = SQLITE_ERROR;
79621 sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
79622 }else{
79623 char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
79624 if( p->explain==2 ){
79625 sqlite3VdbeMemSetInt64(pMem, pOp->p1);
79626 sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
79627 sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
79628 sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
79629 p->nResColumn = 4;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79630 }else{
79631 sqlite3VdbeMemSetInt64(pMem+0, i);
79632 sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
79633 -1, SQLITE_UTF8, SQLITE_STATIC);
79634 sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
79635 sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
79636 sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
79637 /* pMem+5 for p4 is done last */
79638 sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
 
 
 
 
 
 
 
 
 
79639 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
79640 {
79641 char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
79642 sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
79643 }
79644 #else
79645 sqlite3VdbeMemSetNull(pMem+7);
79646 #endif
79647 sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
79648 p->nResColumn = 8;
79649 }
79650 p->pResultSet = pMem;
79651 if( db->mallocFailed ){
79652 p->rc = SQLITE_NOMEM;
79653 rc = SQLITE_ERROR;
79654 }else{
79655 p->rc = SQLITE_OK;
79656 rc = SQLITE_ROW;
79657 }
79658 }
79659 }
79660 return rc;
79661 }
79662 #endif /* SQLITE_OMIT_EXPLAIN */
@@ -79982,12 +80222,13 @@
80222 int retryCount = 0;
80223 int nMainFile;
80224
80225 /* Select a master journal file name */
80226 nMainFile = sqlite3Strlen30(zMainFile);
80227 zMaster = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0);
80228 if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
80229 zMaster += 4;
80230 do {
80231 u32 iRandom;
80232 if( retryCount ){
80233 if( retryCount>100 ){
80234 sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
@@ -80013,11 +80254,11 @@
80254 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
80255 SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
80256 );
80257 }
80258 if( rc!=SQLITE_OK ){
80259 sqlite3DbFree(db, zMaster-4);
80260 return rc;
80261 }
80262
80263 /* Write the name of each database file in the transaction into the new
80264 ** master journal file. If an error occurs at this point close
@@ -80036,11 +80277,11 @@
80277 rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
80278 offset += sqlite3Strlen30(zFile)+1;
80279 if( rc!=SQLITE_OK ){
80280 sqlite3OsCloseFree(pMaster);
80281 sqlite3OsDelete(pVfs, zMaster, 0);
80282 sqlite3DbFree(db, zMaster-4);
80283 return rc;
80284 }
80285 }
80286 }
80287
@@ -80050,11 +80291,11 @@
80291 if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
80292 && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
80293 ){
80294 sqlite3OsCloseFree(pMaster);
80295 sqlite3OsDelete(pVfs, zMaster, 0);
80296 sqlite3DbFree(db, zMaster-4);
80297 return rc;
80298 }
80299
80300 /* Sync all the db files involved in the transaction. The same call
80301 ** sets the master journal pointer in each individual journal. If
@@ -80073,20 +80314,20 @@
80314 }
80315 }
80316 sqlite3OsCloseFree(pMaster);
80317 assert( rc!=SQLITE_BUSY );
80318 if( rc!=SQLITE_OK ){
80319 sqlite3DbFree(db, zMaster-4);
80320 return rc;
80321 }
80322
80323 /* Delete the master journal file. This commits the transaction. After
80324 ** doing this the directory is synced again before any individual
80325 ** transaction files are deleted.
80326 */
80327 rc = sqlite3OsDelete(pVfs, zMaster, 1);
80328 sqlite3DbFree(db, zMaster-4);
80329 zMaster = 0;
80330 if( rc ){
80331 return rc;
80332 }
80333
@@ -87998,32 +88239,38 @@
88239 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
88240 REGISTER_TRACE(pOp->p3, pOut);
88241 break;
88242 }
88243
88244 /* Opcode: Count P1 P2 p3 * *
88245 ** Synopsis: r[P2]=count()
88246 **
88247 ** Store the number of entries (an integer value) in the table or index
88248 ** opened by cursor P1 in register P2.
88249 **
88250 ** If P3==0, then an exact count is obtained, which involves visiting
88251 ** every btree page of the table. But if P3 is non-zero, an estimate
88252 ** is returned based on the current cursor position.
88253 */
 
88254 case OP_Count: { /* out2 */
88255 i64 nEntry;
88256 BtCursor *pCrsr;
88257
88258 assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
88259 pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
88260 assert( pCrsr );
88261 if( pOp->p3 ){
88262 nEntry = sqlite3BtreeRowCountEst(pCrsr);
88263 }else{
88264 nEntry = 0; /* Not needed. Only used to silence a warning. */
88265 rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
88266 if( rc ) goto abort_due_to_error;
88267 }
88268 pOut = out2Prerelease(p, pOp);
88269 pOut->u.i = nEntry;
88270 goto check_for_interrupt;
88271 }
 
88272
88273 /* Opcode: Savepoint P1 * * P4 *
88274 **
88275 ** Open, release or rollback the savepoint named by parameter P4, depending
88276 ** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
@@ -90457,16 +90704,23 @@
90704 rc = sqlite3VdbeSorterWrite(pC, pIn2);
90705 if( rc) goto abort_due_to_error;
90706 break;
90707 }
90708
90709 /* Opcode: IdxDelete P1 P2 P3 * P5
90710 ** Synopsis: key=r[P2@P3]
90711 **
90712 ** The content of P3 registers starting at register P2 form
90713 ** an unpacked index key. This opcode removes that entry from the
90714 ** index opened by cursor P1.
90715 **
90716 ** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
90717 ** if no matching index entry is found. This happens when running
90718 ** an UPDATE or DELETE statement and the index entry to be updated
90719 ** or deleted is not found. For some uses of IdxDelete
90720 ** (example: the EXCEPT operator) it does not matter that no matching
90721 ** entry is found. For those cases, P5 is zero.
90722 */
90723 case OP_IdxDelete: {
90724 VdbeCursor *pC;
90725 BtCursor *pCrsr;
90726 int res;
@@ -90479,20 +90733,22 @@
90733 assert( pC!=0 );
90734 assert( pC->eCurType==CURTYPE_BTREE );
90735 sqlite3VdbeIncrWriteCounter(p, pC);
90736 pCrsr = pC->uc.pCursor;
90737 assert( pCrsr!=0 );
 
90738 r.pKeyInfo = pC->pKeyInfo;
90739 r.nField = (u16)pOp->p3;
90740 r.default_rc = 0;
90741 r.aMem = &aMem[pOp->p2];
90742 rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
90743 if( rc ) goto abort_due_to_error;
90744 if( res==0 ){
90745 rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
90746 if( rc ) goto abort_due_to_error;
90747 }else if( pOp->p5 ){
90748 rc = SQLITE_CORRUPT_INDEX;
90749 goto abort_due_to_error;
90750 }
90751 assert( pC->deferredMoveto==0 );
90752 pC->cacheStatus = CACHE_STALE;
90753 pC->seekResult = 0;
90754 break;
@@ -96093,10 +96349,435 @@
96349 *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
96350 return SQLITE_OK;
96351 }
96352
96353 /************** End of vdbesort.c ********************************************/
96354 /************** Begin file vdbevtab.c ****************************************/
96355 /*
96356 ** 2020-03-23
96357 **
96358 ** The author disclaims copyright to this source code. In place of
96359 ** a legal notice, here is a blessing:
96360 **
96361 ** May you do good and not evil.
96362 ** May you find forgiveness for yourself and forgive others.
96363 ** May you share freely, never taking more than you give.
96364 **
96365 *************************************************************************
96366 **
96367 ** This file implements virtual-tables for examining the bytecode content
96368 ** of a prepared statement.
96369 */
96370 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
96371 /* #include "sqliteInt.h" */
96372 /* #include "vdbeInt.h" */
96373
96374 /* An instance of the bytecode() table-valued function.
96375 */
96376 typedef struct bytecodevtab bytecodevtab;
96377 struct bytecodevtab {
96378 sqlite3_vtab base; /* Base class - must be first */
96379 sqlite3 *db; /* Database connection */
96380 int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */
96381 };
96382
96383 /* A cursor for scanning through the bytecode
96384 */
96385 typedef struct bytecodevtab_cursor bytecodevtab_cursor;
96386 struct bytecodevtab_cursor {
96387 sqlite3_vtab_cursor base; /* Base class - must be first */
96388 sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */
96389 int iRowid; /* The rowid of the output table */
96390 int iAddr; /* Address */
96391 int needFinalize; /* Cursors owns pStmt and must finalize it */
96392 int showSubprograms; /* Provide a listing of subprograms */
96393 Op *aOp; /* Operand array */
96394 char *zP4; /* Rendered P4 value */
96395 const char *zType; /* tables_used.type */
96396 const char *zSchema; /* tables_used.schema */
96397 const char *zName; /* tables_used.name */
96398 Mem sub; /* Subprograms */
96399 };
96400
96401 /*
96402 ** Create a new bytecode() table-valued function.
96403 */
96404 static int bytecodevtabConnect(
96405 sqlite3 *db,
96406 void *pAux,
96407 int argc, const char *const*argv,
96408 sqlite3_vtab **ppVtab,
96409 char **pzErr
96410 ){
96411 bytecodevtab *pNew;
96412 int rc;
96413 int isTabUsed = pAux!=0;
96414 const char *azSchema[2] = {
96415 /* bytecode() schema */
96416 "CREATE TABLE x("
96417 "addr INT,"
96418 "opcode TEXT,"
96419 "p1 INT,"
96420 "p2 INT,"
96421 "p3 INT,"
96422 "p4 TEXT,"
96423 "p5 INT,"
96424 "comment TEXT,"
96425 "subprog TEXT,"
96426 "stmt HIDDEN"
96427 ");",
96428
96429 /* Tables_used() schema */
96430 "CREATE TABLE x("
96431 "type TEXT,"
96432 "schema TEXT,"
96433 "name TEXT,"
96434 "wr INT,"
96435 "subprog TEXT,"
96436 "stmt HIDDEN"
96437 ");"
96438 };
96439
96440 rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
96441 if( rc==SQLITE_OK ){
96442 pNew = sqlite3_malloc( sizeof(*pNew) );
96443 *ppVtab = (sqlite3_vtab*)pNew;
96444 if( pNew==0 ) return SQLITE_NOMEM;
96445 memset(pNew, 0, sizeof(*pNew));
96446 pNew->db = db;
96447 pNew->bTablesUsed = isTabUsed*2;
96448 }
96449 return rc;
96450 }
96451
96452 /*
96453 ** This method is the destructor for bytecodevtab objects.
96454 */
96455 static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
96456 bytecodevtab *p = (bytecodevtab*)pVtab;
96457 sqlite3_free(p);
96458 return SQLITE_OK;
96459 }
96460
96461 /*
96462 ** Constructor for a new bytecodevtab_cursor object.
96463 */
96464 static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
96465 bytecodevtab *pVTab = (bytecodevtab*)p;
96466 bytecodevtab_cursor *pCur;
96467 pCur = sqlite3_malloc( sizeof(*pCur) );
96468 if( pCur==0 ) return SQLITE_NOMEM;
96469 memset(pCur, 0, sizeof(*pCur));
96470 sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
96471 *ppCursor = &pCur->base;
96472 return SQLITE_OK;
96473 }
96474
96475 /*
96476 ** Clear all internal content from a bytecodevtab cursor.
96477 */
96478 static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
96479 sqlite3_free(pCur->zP4);
96480 pCur->zP4 = 0;
96481 sqlite3VdbeMemRelease(&pCur->sub);
96482 sqlite3VdbeMemSetNull(&pCur->sub);
96483 if( pCur->needFinalize ){
96484 sqlite3_finalize(pCur->pStmt);
96485 }
96486 pCur->pStmt = 0;
96487 pCur->needFinalize = 0;
96488 pCur->zType = 0;
96489 pCur->zSchema = 0;
96490 pCur->zName = 0;
96491 }
96492
96493 /*
96494 ** Destructor for a bytecodevtab_cursor.
96495 */
96496 static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
96497 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96498 bytecodevtabCursorClear(pCur);
96499 sqlite3_free(pCur);
96500 return SQLITE_OK;
96501 }
96502
96503
96504 /*
96505 ** Advance a bytecodevtab_cursor to its next row of output.
96506 */
96507 static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
96508 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96509 bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
96510 int rc;
96511 if( pCur->zP4 ){
96512 sqlite3_free(pCur->zP4);
96513 pCur->zP4 = 0;
96514 }
96515 if( pCur->zName ){
96516 pCur->zName = 0;
96517 pCur->zType = 0;
96518 pCur->zSchema = 0;
96519 }
96520 rc = sqlite3VdbeNextOpcode(
96521 (Vdbe*)pCur->pStmt,
96522 pCur->showSubprograms ? &pCur->sub : 0,
96523 pTab->bTablesUsed,
96524 &pCur->iRowid,
96525 &pCur->iAddr,
96526 &pCur->aOp);
96527 if( rc!=SQLITE_OK ){
96528 sqlite3VdbeMemSetNull(&pCur->sub);
96529 pCur->aOp = 0;
96530 }
96531 return SQLITE_OK;
96532 }
96533
96534 /*
96535 ** Return TRUE if the cursor has been moved off of the last
96536 ** row of output.
96537 */
96538 static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
96539 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96540 return pCur->aOp==0;
96541 }
96542
96543 /*
96544 ** Return values of columns for the row at which the bytecodevtab_cursor
96545 ** is currently pointing.
96546 */
96547 static int bytecodevtabColumn(
96548 sqlite3_vtab_cursor *cur, /* The cursor */
96549 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
96550 int i /* Which column to return */
96551 ){
96552 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96553 bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
96554 Op *pOp = pCur->aOp + pCur->iAddr;
96555 if( pVTab->bTablesUsed ){
96556 if( i==4 ){
96557 i = 8;
96558 }else{
96559 if( i<=2 && pCur->zType==0 ){
96560 Schema *pSchema;
96561 HashElem *k;
96562 int iDb = pOp->p3;
96563 int iRoot = pOp->p2;
96564 sqlite3 *db = pVTab->db;
96565 pSchema = db->aDb[iDb].pSchema;
96566 pCur->zSchema = db->aDb[iDb].zDbSName;
96567 for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
96568 Table *pTab = (Table*)sqliteHashData(k);
96569 if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
96570 pCur->zName = pTab->zName;
96571 pCur->zType = "table";
96572 break;
96573 }
96574 }
96575 if( pCur->zName==0 ){
96576 for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
96577 Index *pIdx = (Index*)sqliteHashData(k);
96578 if( pIdx->tnum==iRoot ){
96579 pCur->zName = pIdx->zName;
96580 pCur->zType = "index";
96581 }
96582 }
96583 }
96584 }
96585 i += 10;
96586 }
96587 }
96588 switch( i ){
96589 case 0: /* addr */
96590 sqlite3_result_int(ctx, pCur->iAddr);
96591 break;
96592 case 1: /* opcode */
96593 sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
96594 -1, SQLITE_STATIC);
96595 break;
96596 case 2: /* p1 */
96597 sqlite3_result_int(ctx, pOp->p1);
96598 break;
96599 case 3: /* p2 */
96600 sqlite3_result_int(ctx, pOp->p2);
96601 break;
96602 case 4: /* p3 */
96603 sqlite3_result_int(ctx, pOp->p3);
96604 break;
96605 case 5: /* p4 */
96606 case 7: /* comment */
96607 if( pCur->zP4==0 ){
96608 pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
96609 }
96610 if( i==5 ){
96611 sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
96612 }else{
96613 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
96614 char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
96615 sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
96616 #endif
96617 }
96618 break;
96619 case 6: /* p5 */
96620 sqlite3_result_int(ctx, pOp->p5);
96621 break;
96622 case 8: { /* subprog */
96623 Op *aOp = pCur->aOp;
96624 assert( aOp[0].opcode==OP_Init );
96625 assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
96626 if( pCur->iRowid==pCur->iAddr+1 ){
96627 break; /* Result is NULL for the main program */
96628 }else if( aOp[0].p4.z!=0 ){
96629 sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
96630 }else{
96631 sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
96632 }
96633 break;
96634 }
96635 case 10: /* tables_used.type */
96636 sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
96637 break;
96638 case 11: /* tables_used.schema */
96639 sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
96640 break;
96641 case 12: /* tables_used.name */
96642 sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
96643 break;
96644 case 13: /* tables_used.wr */
96645 sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
96646 break;
96647 }
96648 return SQLITE_OK;
96649 }
96650
96651 /*
96652 ** Return the rowid for the current row. In this implementation, the
96653 ** rowid is the same as the output value.
96654 */
96655 static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
96656 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
96657 *pRowid = pCur->iRowid;
96658 return SQLITE_OK;
96659 }
96660
96661 /*
96662 ** Initialize a cursor.
96663 **
96664 ** idxNum==0 means show all subprograms
96665 ** idxNum==1 means show only the main bytecode and omit subprograms.
96666 */
96667 static int bytecodevtabFilter(
96668 sqlite3_vtab_cursor *pVtabCursor,
96669 int idxNum, const char *idxStr,
96670 int argc, sqlite3_value **argv
96671 ){
96672 bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
96673 bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
96674 int rc = SQLITE_OK;
96675
96676 bytecodevtabCursorClear(pCur);
96677 pCur->iRowid = 0;
96678 pCur->iAddr = 0;
96679 pCur->showSubprograms = idxNum==0;
96680 assert( argc==1 );
96681 if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
96682 const char *zSql = (const char*)sqlite3_value_text(argv[0]);
96683 if( zSql==0 ){
96684 rc = SQLITE_NOMEM;
96685 }else{
96686 rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
96687 pCur->needFinalize = 1;
96688 }
96689 }else{
96690 pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
96691 }
96692 if( pCur->pStmt==0 ){
96693 pVTab->base.zErrMsg = sqlite3_mprintf(
96694 "argument to %s() is not a valid SQL statement",
96695 pVTab->bTablesUsed ? "tables_used" : "bytecode"
96696 );
96697 rc = SQLITE_ERROR;
96698 }else{
96699 bytecodevtabNext(pVtabCursor);
96700 }
96701 return rc;
96702 }
96703
96704 /*
96705 ** We must have a single stmt=? constraint that will be passed through
96706 ** into the xFilter method. If there is no valid stmt=? constraint,
96707 ** then return an SQLITE_CONSTRAINT error.
96708 */
96709 static int bytecodevtabBestIndex(
96710 sqlite3_vtab *tab,
96711 sqlite3_index_info *pIdxInfo
96712 ){
96713 int i;
96714 int rc = SQLITE_CONSTRAINT;
96715 struct sqlite3_index_constraint *p;
96716 bytecodevtab *pVTab = (bytecodevtab*)tab;
96717 int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
96718 pIdxInfo->estimatedCost = (double)100;
96719 pIdxInfo->estimatedRows = 100;
96720 pIdxInfo->idxNum = 0;
96721 for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
96722 if( p->usable==0 ) continue;
96723 if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
96724 rc = SQLITE_OK;
96725 pIdxInfo->aConstraintUsage[i].omit = 1;
96726 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
96727 }
96728 if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
96729 pIdxInfo->aConstraintUsage[i].omit = 1;
96730 pIdxInfo->idxNum = 1;
96731 }
96732 }
96733 return rc;
96734 }
96735
96736 /*
96737 ** This following structure defines all the methods for the
96738 ** virtual table.
96739 */
96740 static sqlite3_module bytecodevtabModule = {
96741 /* iVersion */ 0,
96742 /* xCreate */ 0,
96743 /* xConnect */ bytecodevtabConnect,
96744 /* xBestIndex */ bytecodevtabBestIndex,
96745 /* xDisconnect */ bytecodevtabDisconnect,
96746 /* xDestroy */ 0,
96747 /* xOpen */ bytecodevtabOpen,
96748 /* xClose */ bytecodevtabClose,
96749 /* xFilter */ bytecodevtabFilter,
96750 /* xNext */ bytecodevtabNext,
96751 /* xEof */ bytecodevtabEof,
96752 /* xColumn */ bytecodevtabColumn,
96753 /* xRowid */ bytecodevtabRowid,
96754 /* xUpdate */ 0,
96755 /* xBegin */ 0,
96756 /* xSync */ 0,
96757 /* xCommit */ 0,
96758 /* xRollback */ 0,
96759 /* xFindMethod */ 0,
96760 /* xRename */ 0,
96761 /* xSavepoint */ 0,
96762 /* xRelease */ 0,
96763 /* xRollbackTo */ 0,
96764 /* xShadowName */ 0
96765 };
96766
96767
96768 SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
96769 int rc;
96770 rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
96771 if( rc==SQLITE_OK ){
96772 rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
96773 }
96774 return rc;
96775 }
96776 #endif /* SQLITE_ENABLE_BYTECODE_VTAB */
96777
96778 /************** End of vdbevtab.c ********************************************/
96779 /************** Begin file memjournal.c **************************************/
96780 /*
96781 ** 2008 October 7
96782 **
96783 ** The author disclaims copyright to this source code. In place of
@@ -98739,11 +99420,11 @@
99420 ** SELECT * FROM t1 WHERE (select a from t1);
99421 */
99422 SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
99423 int op;
99424 while( ExprHasProperty(pExpr, EP_Skip) ){
99425 assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
99426 pExpr = pExpr->pLeft;
99427 assert( pExpr!=0 );
99428 }
99429 op = pExpr->op;
99430 if( op==TK_SELECT ){
@@ -98806,11 +99487,11 @@
99487 /*
99488 ** Skip over any TK_COLLATE operators.
99489 */
99490 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
99491 while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
99492 assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
99493 pExpr = pExpr->pLeft;
99494 }
99495 return pExpr;
99496 }
99497
@@ -98825,11 +99506,11 @@
99506 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
99507 assert( pExpr->x.pList->nExpr>0 );
99508 assert( pExpr->op==TK_FUNCTION );
99509 pExpr = pExpr->x.pList->a[0].pExpr;
99510 }else{
99511 assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
99512 pExpr = pExpr->pLeft;
99513 }
99514 }
99515 return pExpr;
99516 }
@@ -103176,11 +103857,11 @@
103857 assert( pExpr->affExpr==OE_Rollback
103858 || pExpr->affExpr==OE_Abort
103859 || pExpr->affExpr==OE_Fail
103860 || pExpr->affExpr==OE_Ignore
103861 );
103862 if( !pParse->pTriggerTab && !pParse->nested ){
103863 sqlite3ErrorMsg(pParse,
103864 "RAISE() may only be used within a trigger-program");
103865 return 0;
103866 }
103867 if( pExpr->affExpr==OE_Abort ){
@@ -103190,12 +103871,13 @@
103871 if( pExpr->affExpr==OE_Ignore ){
103872 sqlite3VdbeAddOp4(
103873 v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
103874 VdbeCoverage(v);
103875 }else{
103876 sqlite3HaltConstraint(pParse,
103877 pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
103878 pExpr->affExpr, pExpr->u.zToken, 0, 0);
103879 }
103880
103881 break;
103882 }
103883 #endif
@@ -104946,10 +105628,26 @@
105628 exit_rename_table:
105629 sqlite3SrcListDelete(db, pSrc);
105630 sqlite3DbFree(db, zName);
105631 db->mDbFlags = savedDbFlags;
105632 }
105633
105634 /*
105635 ** Write code that will raise an error if the table described by
105636 ** zDb and zTab is not empty.
105637 */
105638 static void sqlite3ErrorIfNotEmpty(
105639 Parse *pParse, /* Parsing context */
105640 const char *zDb, /* Schema holding the table */
105641 const char *zTab, /* Table to check for empty */
105642 const char *zErr /* Error message text */
105643 ){
105644 sqlite3NestedParse(pParse,
105645 "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
105646 zErr, zDb, zTab
105647 );
105648 }
105649
105650 /*
105651 ** This function is called after an "ALTER TABLE ... ADD" statement
105652 ** has been parsed. Argument pColDef contains the text of the new
105653 ** column definition.
@@ -104999,11 +105697,12 @@
105697 if( pCol->colFlags & COLFLAG_PRIMKEY ){
105698 sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
105699 return;
105700 }
105701 if( pNew->pIndex ){
105702 sqlite3ErrorMsg(pParse,
105703 "Cannot add a UNIQUE column");
105704 return;
105705 }
105706 if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
105707 /* If the default value for the new column was specified with a
105708 ** literal NULL, then set pDflt to 0. This simplifies checking
@@ -105012,19 +105711,18 @@
105711 assert( pDflt==0 || pDflt->op==TK_SPAN );
105712 if( pDflt && pDflt->pLeft->op==TK_NULL ){
105713 pDflt = 0;
105714 }
105715 if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
105716 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
105717 "Cannot add a REFERENCES column with non-NULL default value");
 
105718 }
105719 if( pCol->notNull && !pDflt ){
105720 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
105721 "Cannot add a NOT NULL column with default value NULL");
 
105722 }
105723
105724
105725 /* Ensure the default expression is something that sqlite3ValueFromExpr()
105726 ** can handle (i.e. not CURRENT_TIME etc.)
105727 */
105728 if( pDflt ){
@@ -105035,18 +105733,17 @@
105733 if( rc!=SQLITE_OK ){
105734 assert( db->mallocFailed == 1 );
105735 return;
105736 }
105737 if( !pVal ){
105738 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
105739 "Cannot add a column with non-constant default");
105740 }
105741 sqlite3ValueFree(pVal);
105742 }
105743 }else if( pCol->colFlags & COLFLAG_STORED ){
105744 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
 
105745 }
105746
105747
105748 /* Modify the CREATE TABLE statement. */
105749 zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
@@ -106605,10 +107302,15 @@
107302 sqlite3 *db = pParse->db;
107303 Db *pDb;
107304 Vdbe *v = sqlite3GetVdbe(pParse);
107305 int aRoot[ArraySize(aTable)];
107306 u8 aCreateTbl[ArraySize(aTable)];
107307 #ifdef SQLITE_ENABLE_STAT4
107308 const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
107309 #else
107310 const int nToOpen = 1;
107311 #endif
107312
107313 if( v==0 ) return;
107314 assert( sqlite3BtreeHoldsAllMutexes(db) );
107315 assert( sqlite3VdbeDb(v)==db );
107316 pDb = &db->aDb[iDb];
@@ -106617,12 +107319,13 @@
107319 ** if they do already exist.
107320 */
107321 for(i=0; i<ArraySize(aTable); i++){
107322 const char *zTab = aTable[i].zName;
107323 Table *pStat;
107324 aCreateTbl[i] = 0;
107325 if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
107326 if( i<nToOpen ){
107327 /* The sqlite_statN table does not exist. Create it. Note that a
107328 ** side-effect of the CREATE TABLE statement is to leave the rootpage
107329 ** of the new table in register pParse->regRoot. This is important
107330 ** because the OpenWrite opcode below will be needing it. */
107331 sqlite3NestedParse(pParse,
@@ -106634,11 +107337,10 @@
107337 }else{
107338 /* The table already exists. If zWhere is not NULL, delete all entries
107339 ** associated with the table zWhere. If zWhere is NULL, delete the
107340 ** entire contents of the table. */
107341 aRoot[i] = pStat->tnum;
 
107342 sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
107343 if( zWhere ){
107344 sqlite3NestedParse(pParse,
107345 "DELETE FROM %Q.%s WHERE %s=%Q",
107346 pDb->zDbSName, zTab, zWhereType, zWhere
@@ -106653,11 +107355,11 @@
107355 }
107356 }
107357 }
107358
107359 /* Open the sqlite_stat[134] tables for writing. */
107360 for(i=0; i<nToOpen; i++){
107361 assert( i<ArraySize(aTable) );
107362 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
107363 sqlite3VdbeChangeP5(v, aCreateTbl[i]);
107364 VdbeComment((v, aTable[i].zName));
107365 }
@@ -106692,13 +107394,16 @@
107394 u32 iHash; /* Tiebreaker hash */
107395 #endif
107396 };
107397 struct StatAccum {
107398 sqlite3 *db; /* Database connection, for malloc() */
107399 tRowcnt nEst; /* Estimated number of rows */
107400 tRowcnt nRow; /* Number of rows visited so far */
107401 int nLimit; /* Analysis row-scan limit */
107402 int nCol; /* Number of columns in index + pk/rowid */
107403 int nKeyCol; /* Number of index columns w/o the pk/rowid */
107404 u8 nSkipAhead; /* Number of times of skip-ahead */
107405 StatSample current; /* Current row as a StatSample */
107406 #ifdef SQLITE_ENABLE_STAT4
107407 tRowcnt nPSample; /* How often to do a periodic sample */
107408 int mxSample; /* Maximum number of samples to accumulate */
107409 u32 iPrn; /* Pseudo-random number used for sampling */
@@ -106774,31 +107479,32 @@
107479 ** Reclaim all memory of a StatAccum structure.
107480 */
107481 static void statAccumDestructor(void *pOld){
107482 StatAccum *p = (StatAccum*)pOld;
107483 #ifdef SQLITE_ENABLE_STAT4
107484 if( p->mxSample ){
107485 int i;
107486 for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
107487 for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
107488 sampleClear(p->db, &p->current);
107489 }
107490 #endif
107491 sqlite3DbFree(p->db, p);
107492 }
107493
107494 /*
107495 ** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
107496 ** are:
107497 ** N: The number of columns in the index including the rowid/pk (note 1)
107498 ** K: The number of columns in the index excluding the rowid/pk.
107499 ** C: Estimated number of rows in the index
107500 ** L: A limit on the number of rows to scan, or 0 for no-limit
107501 **
107502 ** Note 1: In the special case of the covering index that implements a
107503 ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
107504 ** total number of columns in the table.
107505 **
 
 
107506 ** For indexes on ordinary rowid tables, N==K+1. But for indexes on
107507 ** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
107508 ** PRIMARY KEY of the table. The covering index that implements the
107509 ** original WITHOUT ROWID table as N==K as a special case.
107510 **
@@ -106815,13 +107521,14 @@
107521 StatAccum *p;
107522 int nCol; /* Number of columns in index being sampled */
107523 int nKeyCol; /* Number of key columns */
107524 int nColUp; /* nCol rounded up for alignment */
107525 int n; /* Bytes of space to allocate */
107526 sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
107527 #ifdef SQLITE_ENABLE_STAT4
107528 /* Maximum number of samples. 0 if STAT4 data is not collected */
107529 int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
107530 #endif
107531
107532 /* Decode the three function arguments */
107533 UNUSED_PARAMETER(argc);
107534 nCol = sqlite3_value_int(argv[0]);
@@ -106832,39 +107539,43 @@
107539 assert( nKeyCol>0 );
107540
107541 /* Allocate the space required for the StatAccum object */
107542 n = sizeof(*p)
107543 + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
107544 + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
107545 #ifdef SQLITE_ENABLE_STAT4
107546 if( mxSample ){
107547 n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
107548 + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
107549 + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
107550 }
107551 #endif
 
107552 db = sqlite3_context_db_handle(context);
107553 p = sqlite3DbMallocZero(db, n);
107554 if( p==0 ){
107555 sqlite3_result_error_nomem(context);
107556 return;
107557 }
107558
107559 p->db = db;
107560 p->nEst = sqlite3_value_int64(argv[2]);
107561 p->nRow = 0;
107562 p->nLimit = sqlite3_value_int64(argv[3]);
107563 p->nCol = nCol;
107564 p->nKeyCol = nKeyCol;
107565 p->nSkipAhead = 0;
107566 p->current.anDLt = (tRowcnt*)&p[1];
107567 p->current.anEq = &p->current.anDLt[nColUp];
107568
107569 #ifdef SQLITE_ENABLE_STAT4
107570 p->mxSample = p->nLimit==0 ? mxSample : 0;
107571 if( mxSample ){
107572 u8 *pSpace; /* Allocated space not yet assigned */
107573 int i; /* Used to iterate through p->aSample[] */
107574
107575 p->iGet = -1;
107576 p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
 
107577 p->current.anLt = &p->current.anEq[nColUp];
107578 p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
107579
107580 /* Set up the StatAccum.a[] and aBest[] arrays */
107581 p->a = (struct StatSample*)&p->current.anLt[nColUp];
@@ -106888,11 +107599,11 @@
107599 ** (given by the 3rd parameter) is never used and can be any positive
107600 ** value. */
107601 sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
107602 }
107603 static const FuncDef statInitFuncdef = {
107604 4, /* nArg */
107605 SQLITE_UTF8, /* funcFlags */
107606 0, /* pUserData */
107607 0, /* pNext */
107608 statInit, /* xSFunc */
107609 0, /* xFinalize */
@@ -107092,14 +107803,17 @@
107803 ** P Pointer to the StatAccum object created by stat_init()
107804 ** C Index of left-most column to differ from previous row
107805 ** R Rowid for the current row. Might be a key record for
107806 ** WITHOUT ROWID tables.
107807 **
107808 ** The purpose of this routine is to collect statistical data and/or
107809 ** samples from the index being analyzed into the StatAccum object.
107810 ** The stat_get() SQL function will be used afterwards to
107811 ** retrieve the information gathered.
107812 **
107813 ** This SQL function usually returns NULL, but might return an integer
107814 ** if it wants the byte-code to do special processing.
107815 **
107816 ** The R parameter is only used for STAT4
107817 */
107818 static void statPush(
107819 sqlite3_context *context,
@@ -107121,11 +107835,11 @@
107835 /* This is the first call to this function. Do initialization. */
107836 for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
107837 }else{
107838 /* Second and subsequent calls get processed here */
107839 #ifdef SQLITE_ENABLE_STAT4
107840 if( p->mxSample ) samplePushPrevious(p, iChng);
107841 #endif
107842
107843 /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
107844 ** to the current row of the index. */
107845 for(i=0; i<iChng; i++){
@@ -107132,30 +107846,29 @@
107846 p->current.anEq[i]++;
107847 }
107848 for(i=iChng; i<p->nCol; i++){
107849 p->current.anDLt[i]++;
107850 #ifdef SQLITE_ENABLE_STAT4
107851 if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
107852 #endif
107853 p->current.anEq[i] = 1;
107854 }
107855 }
107856
107857 p->nRow++;
107858 #ifdef SQLITE_ENABLE_STAT4
107859 if( p->mxSample ){
107860 tRowcnt nLt;
107861 if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
107862 sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
107863 }else{
107864 sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
107865 sqlite3_value_blob(argv[2]));
107866 }
107867 p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
107868
107869 nLt = p->current.anLt[p->nCol-1];
 
 
107870 /* Check if this is to be a periodic sample. If so, add it. */
107871 if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
107872 p->current.isPSample = 1;
107873 p->current.iCol = 0;
107874 sampleInsert(p, &p->current, p->nCol-1);
@@ -107167,13 +107880,18 @@
107880 p->current.iCol = i;
107881 if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
107882 sampleCopy(p, &p->aBest[i], &p->current);
107883 }
107884 }
107885 }else
107886 #endif
107887 if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
107888 p->nSkipAhead++;
107889 sqlite3_result_int(context, p->current.anDLt[0]>0);
107890 }
 
107891 }
107892
107893 static const FuncDef statPushFuncdef = {
107894 2+IsStat4, /* nArg */
107895 SQLITE_UTF8, /* funcFlags */
107896 0, /* pUserData */
107897 0, /* pNext */
@@ -107221,10 +107939,11 @@
107939 assert( argc==2 );
107940 assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
107941 || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
107942 || eCall==STAT_GET_NDLT
107943 );
107944 assert( eCall==STAT_GET_STAT1 || p->mxSample );
107945 if( eCall==STAT_GET_STAT1 )
107946 #else
107947 assert( argc==1 );
107948 #endif
107949 {
@@ -107256,11 +107975,12 @@
107975 if( zRet==0 ){
107976 sqlite3_result_error_nomem(context);
107977 return;
107978 }
107979
107980 sqlite3_snprintf(24, zRet, "%llu",
107981 p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
107982 z = zRet + sqlite3Strlen30(zRet);
107983 for(i=0; i<p->nKeyCol; i++){
107984 u64 nDistinct = p->current.anDLt[i] + 1;
107985 u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
107986 sqlite3_snprintf(24, z, " %llu", iVal);
@@ -107332,20 +108052,20 @@
108052 0, 0, /* xValue, xInverse */
108053 "stat_get", /* zName */
108054 {0}
108055 };
108056
108057 static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
108058 #ifdef SQLITE_ENABLE_STAT4
108059 sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
108060 #elif SQLITE_DEBUG
108061 assert( iParam==STAT_GET_STAT1 );
108062 #else
108063 UNUSED_PARAMETER( iParam );
108064 #endif
108065 assert( regOut!=regStat && regOut!=regStat+1 );
108066 sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
108067 &statGetFuncdef, 0);
108068 }
108069
108070 /*
108071 ** Generate code to do an analysis of all indices associated with
@@ -107367,16 +108087,15 @@
108087 int i; /* Loop counter */
108088 int jZeroRows = -1; /* Jump from here if number of rows is zero */
108089 int iDb; /* Index of database containing pTab */
108090 u8 needTableCnt = 1; /* True to count the table */
108091 int regNewRowid = iMem++; /* Rowid for the inserted record */
108092 int regStat = iMem++; /* Register to hold StatAccum object */
108093 int regChng = iMem++; /* Index of changed index field */
 
108094 int regRowid = iMem++; /* Rowid argument passed to stat_push() */
 
108095 int regTemp = iMem++; /* Temporary use register */
108096 int regTemp2 = iMem++; /* Second temporary use register */
108097 int regTabname = iMem++; /* Register containing table name */
108098 int regIdxname = iMem++; /* Register containing index name */
108099 int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
108100 int regPrev = iMem; /* MUST BE LAST (see below) */
108101 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -107500,21 +108219,30 @@
108219 /* Invoke the stat_init() function. The arguments are:
108220 **
108221 ** (1) the number of columns in the index including the rowid
108222 ** (or for a WITHOUT ROWID table, the number of PK columns),
108223 ** (2) the number of columns in the key without the rowid/pk
108224 ** (3) estimated number of rows in the index,
 
 
 
108225 */
108226 sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
108227 assert( regRowid==regStat+2 );
108228 sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
108229 #ifdef SQLITE_ENABLE_STAT4
108230 if( OptimizationEnabled(db, SQLITE_Stat4) ){
108231 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
108232 addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
108233 VdbeCoverage(v);
108234 }else
108235 #endif
108236 {
108237 addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
108238 VdbeCoverage(v);
108239 sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
108240 }
108241 assert( regTemp2==regStat+4 );
108242 sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
108243 sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
108244 &statInitFuncdef, 0);
108245
108246 /* Implementation of the following:
108247 **
108248 ** Rewind csr
@@ -107521,12 +108249,10 @@
108249 ** if eof(csr) goto end_of_scan;
108250 ** regChng = 0
108251 ** goto next_push_0;
108252 **
108253 */
 
 
108254 sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
108255 addrNextRow = sqlite3VdbeCurrentAddr(v);
108256
108257 if( nColTest>0 ){
108258 int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
@@ -107555,10 +108281,11 @@
108281 }
108282 for(i=0; i<nColTest; i++){
108283 char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
108284 sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
108285 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
108286 VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
108287 aGotoChng[i] =
108288 sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
108289 sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
108290 VdbeCoverage(v);
108291 }
@@ -107575,10 +108302,11 @@
108302 */
108303 sqlite3VdbeJumpHere(v, addrNextRow-1);
108304 for(i=0; i<nColTest; i++){
108305 sqlite3VdbeJumpHere(v, aGotoChng[i]);
108306 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
108307 VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
108308 }
108309 sqlite3VdbeResolveLabel(v, endDistinctTest);
108310 sqlite3DbFree(db, aGotoChng);
108311 }
108312
@@ -107588,34 +108316,50 @@
108316 ** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
108317 ** Next csr
108318 ** if !eof(csr) goto next_row;
108319 */
108320 #ifdef SQLITE_ENABLE_STAT4
108321 if( OptimizationEnabled(db, SQLITE_Stat4) ){
108322 assert( regRowid==(regStat+2) );
108323 if( HasRowid(pTab) ){
108324 sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
108325 }else{
108326 Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
108327 int j, k, regKey;
108328 regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
108329 for(j=0; j<pPk->nKeyCol; j++){
108330 k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
108331 assert( k>=0 && k<pIdx->nColumn );
108332 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
108333 VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
108334 }
108335 sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
108336 sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
108337 }
108338 }
108339 #endif
108340 assert( regChng==(regStat+1) );
108341 {
108342 sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
108343 &statPushFuncdef, 0);
108344 if( db->nAnalysisLimit ){
108345 int j1, j2, j3;
108346 j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
108347 j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
108348 j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
108349 VdbeCoverage(v);
108350 sqlite3VdbeJumpHere(v, j1);
108351 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
108352 sqlite3VdbeJumpHere(v, j2);
108353 sqlite3VdbeJumpHere(v, j3);
108354 }else{
108355 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
108356 }
108357 }
108358
108359 /* Add the entry to the stat1 table. */
108360 callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
108361 assert( "BBB"[0]==SQLITE_AFF_TEXT );
108362 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
108363 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
108364 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
108365 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -107623,11 +108367,11 @@
108367 #endif
108368 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
108369
108370 /* Add the entries to the stat4 table. */
108371 #ifdef SQLITE_ENABLE_STAT4
108372 if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
108373 int regEq = regStat1;
108374 int regLt = regStat1+1;
108375 int regDLt = regStat1+2;
108376 int regSample = regStat1+3;
108377 int regCol = regStat1+4;
@@ -107637,16 +108381,16 @@
108381 u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
108382
108383 pParse->nMem = MAX(pParse->nMem, regCol+nCol);
108384
108385 addrNext = sqlite3VdbeCurrentAddr(v);
108386 callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
108387 addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
108388 VdbeCoverage(v);
108389 callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
108390 callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
108391 callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
108392 sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
108393 VdbeCoverage(v);
108394 for(i=0; i<nCol; i++){
108395 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
108396 }
@@ -113818,11 +114562,11 @@
114562 pParse->rc = rc;
114563 return 1;
114564 }
114565 db->aDb[1].pBt = pBt;
114566 assert( db->aDb[1].pSchema );
114567 if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){
114568 sqlite3OomFault(db);
114569 return 1;
114570 }
114571 }
114572 return 0;
@@ -113929,11 +114673,11 @@
114673 char *p4, /* Error message */
114674 i8 p4type, /* P4_STATIC or P4_TRANSIENT */
114675 u8 p5Errmsg /* P5_ErrMsg type */
114676 ){
114677 Vdbe *v = sqlite3GetVdbe(pParse);
114678 assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
114679 if( onError==OE_Abort ){
114680 sqlite3MayAbort(pParse);
114681 }
114682 sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
114683 sqlite3VdbeChangeP5(v, p5Errmsg);
@@ -115642,10 +116386,11 @@
116386 VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
116387 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
116388 &iPartIdxLabel, pPrior, r1);
116389 sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
116390 pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
116391 sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */
116392 sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
116393 pPrior = pIdx;
116394 }
116395 }
116396
@@ -122629,10 +123374,11 @@
123374 const char *(*filename_wal)(const char*);
123375 /* Version 3.32.0 and later */
123376 char *(*create_filename)(const char*,const char*,const char*,
123377 int,const char**);
123378 void (*free_filename)(char*);
123379 sqlite3_file *(*database_file_object)(const char*);
123380 };
123381
123382 /*
123383 ** This is the function signature used for all extension entry points. It
123384 ** is also defined in the file "loadext.c".
@@ -122932,10 +123678,11 @@
123678 #define sqlite3_filename_journal sqlite3_api->filename_journal
123679 #define sqlite3_filename_wal sqlite3_api->filename_wal
123680 /* Version 3.32.0 and later */
123681 #define sqlite3_create_filename sqlite3_api->create_filename
123682 #define sqlite3_free_filename sqlite3_api->free_filename
123683 #define sqlite3_database_file_object sqlite3_api->database_file_object
123684 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
123685
123686 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
123687 /* This case when the file really is being compiled as a loadable
123688 ** extension */
@@ -123413,11 +124160,20 @@
124160 sqlite3_filename_journal,
124161 sqlite3_filename_wal,
124162 /* Version 3.32.0 and later */
124163 sqlite3_create_filename,
124164 sqlite3_free_filename,
124165 sqlite3_database_file_object,
124166 };
124167
124168 /* True if x is the directory separator character
124169 */
124170 #if SQLITE_OS_WIN
124171 # define DirSep(X) ((X)=='/'||(X)=='\\')
124172 #else
124173 # define DirSep(X) ((X)=='/')
124174 #endif
124175
124176 /*
124177 ** Attempt to load an SQLite extension library contained in the file
124178 ** zFile. The entry point is zProc. zProc may be 0 in which case a
124179 ** default entry point name (sqlite3_extension_init) is used. Use
@@ -123516,11 +124272,11 @@
124272 if( zAltEntry==0 ){
124273 sqlite3OsDlClose(pVfs, handle);
124274 return SQLITE_NOMEM_BKPT;
124275 }
124276 memcpy(zAltEntry, "sqlite3_", 8);
124277 for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){}
124278 iFile++;
124279 if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
124280 for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
124281 if( sqlite3Isalpha(c) ){
124282 zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
@@ -123820,53 +124576,54 @@
124576 ** that script and rerun it.
124577 */
124578
124579 /* The various pragma types */
124580 #define PragTyp_ACTIVATE_EXTENSIONS 0
124581 #define PragTyp_ANALYSIS_LIMIT 1
124582 #define PragTyp_HEADER_VALUE 2
124583 #define PragTyp_AUTO_VACUUM 3
124584 #define PragTyp_FLAG 4
124585 #define PragTyp_BUSY_TIMEOUT 5
124586 #define PragTyp_CACHE_SIZE 6
124587 #define PragTyp_CACHE_SPILL 7
124588 #define PragTyp_CASE_SENSITIVE_LIKE 8
124589 #define PragTyp_COLLATION_LIST 9
124590 #define PragTyp_COMPILE_OPTIONS 10
124591 #define PragTyp_DATA_STORE_DIRECTORY 11
124592 #define PragTyp_DATABASE_LIST 12
124593 #define PragTyp_DEFAULT_CACHE_SIZE 13
124594 #define PragTyp_ENCODING 14
124595 #define PragTyp_FOREIGN_KEY_CHECK 15
124596 #define PragTyp_FOREIGN_KEY_LIST 16
124597 #define PragTyp_FUNCTION_LIST 17
124598 #define PragTyp_HARD_HEAP_LIMIT 18
124599 #define PragTyp_INCREMENTAL_VACUUM 19
124600 #define PragTyp_INDEX_INFO 20
124601 #define PragTyp_INDEX_LIST 21
124602 #define PragTyp_INTEGRITY_CHECK 22
124603 #define PragTyp_JOURNAL_MODE 23
124604 #define PragTyp_JOURNAL_SIZE_LIMIT 24
124605 #define PragTyp_LOCK_PROXY_FILE 25
124606 #define PragTyp_LOCKING_MODE 26
124607 #define PragTyp_PAGE_COUNT 27
124608 #define PragTyp_MMAP_SIZE 28
124609 #define PragTyp_MODULE_LIST 29
124610 #define PragTyp_OPTIMIZE 30
124611 #define PragTyp_PAGE_SIZE 31
124612 #define PragTyp_PRAGMA_LIST 32
124613 #define PragTyp_SECURE_DELETE 33
124614 #define PragTyp_SHRINK_MEMORY 34
124615 #define PragTyp_SOFT_HEAP_LIMIT 35
124616 #define PragTyp_SYNCHRONOUS 36
124617 #define PragTyp_TABLE_INFO 37
124618 #define PragTyp_TEMP_STORE 38
124619 #define PragTyp_TEMP_STORE_DIRECTORY 39
124620 #define PragTyp_THREADS 40
124621 #define PragTyp_WAL_AUTOCHECKPOINT 41
124622 #define PragTyp_WAL_CHECKPOINT 42
124623 #define PragTyp_LOCK_STATUS 43
124624 #define PragTyp_STATS 44
124625
124626 /* Property flags associated with various pragma. */
124627 #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
124628 #define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
124629 #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
@@ -123953,10 +124710,15 @@
124710 /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
124711 /* ePragFlg: */ 0,
124712 /* ColNames: */ 0, 0,
124713 /* iArg: */ 0 },
124714 #endif
124715 {/* zName: */ "analysis_limit",
124716 /* ePragTyp: */ PragTyp_ANALYSIS_LIMIT,
124717 /* ePragFlg: */ PragFlg_Result0,
124718 /* ColNames: */ 0, 0,
124719 /* iArg: */ 0 },
124720 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
124721 {/* zName: */ "application_id",
124722 /* ePragTyp: */ PragTyp_HEADER_VALUE,
124723 /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
124724 /* ColNames: */ 0, 0,
@@ -124453,11 +125215,11 @@
125215 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
125216 /* ColNames: */ 0, 0,
125217 /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
125218 #endif
125219 };
125220 /* Number of pragmas: 67 on by default, 77 total. */
125221
125222 /************** End of pragma.h **********************************************/
125223 /************** Continuing where we left off in pragma.c *********************/
125224
125225 /*
@@ -124983,11 +125745,11 @@
125745 }else{
125746 /* Malloc may fail when setting the page-size, as there is an internal
125747 ** buffer that the pager module resizes using sqlite3_realloc().
125748 */
125749 db->nextPagesize = sqlite3Atoi(zRight);
125750 if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){
125751 sqlite3OomFault(db);
125752 }
125753 }
125754 break;
125755 }
@@ -126157,11 +126919,10 @@
126919 sqlite3ResolvePartIdxLabel(pParse, jmp3);
126920 }
126921 }
126922 sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
126923 sqlite3VdbeJumpHere(v, loopTop-1);
 
126924 if( !isQuick ){
126925 sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
126926 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
126927 if( pPk==pIdx ) continue;
126928 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
@@ -126171,11 +126932,10 @@
126932 sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
126933 integrityCheckResultRow(v);
126934 sqlite3VdbeJumpHere(v, addr);
126935 }
126936 }
 
126937 }
126938 }
126939 {
126940 static const int iLn = VDBE_OFFSET_LINENO(2);
126941 static const VdbeOpList endCode[] = {
@@ -126605,10 +127365,29 @@
127365 sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
127366 }
127367 returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
127368 break;
127369 }
127370
127371 /*
127372 ** PRAGMA analysis_limit
127373 ** PRAGMA analysis_limit = N
127374 **
127375 ** Configure the maximum number of rows that ANALYZE will examine
127376 ** in each index that it looks at. Return the new limit.
127377 */
127378 case PragTyp_ANALYSIS_LIMIT: {
127379 sqlite3_int64 N;
127380 if( zRight
127381 && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
127382 && N>=0
127383 ){
127384 db->nAnalysisLimit = (int)(N&0x7fffffff);
127385 }
127386 returnSingleInt(v, db->nAnalysisLimit);
127387 break;
127388 }
127389
127390 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
127391 /*
127392 ** Report the current state of file logs for all databases
127393 */
@@ -131404,10 +132183,11 @@
132183 if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
132184 memset(&ifNullRow, 0, sizeof(ifNullRow));
132185 ifNullRow.op = TK_IF_NULL_ROW;
132186 ifNullRow.pLeft = pCopy;
132187 ifNullRow.iTable = pSubst->iNewTable;
132188 ifNullRow.flags = EP_Skip;
132189 pCopy = &ifNullRow;
132190 }
132191 testcase( ExprHasProperty(pCopy, EP_Subquery) );
132192 pNew = sqlite3ExprDup(db, pCopy, 0);
132193 if( pNew && pSubst->isLeftJoin ){
@@ -134568,11 +135348,10 @@
135348 VdbeComment((v, "indicate accumulator empty"));
135349 sqlite3VdbeAddOp1(v, OP_Return, regReset);
135350
135351 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
135352 else {
 
135353 Table *pTab;
135354 if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
135355 /* If isSimpleCount() returns a pointer to a Table structure, then
135356 ** the SQL statement is of the form:
135357 **
@@ -134604,17 +135383,19 @@
135383 **
135384 ** In practice the KeyInfo structure will not be used. It is only
135385 ** passed to keep OP_OpenRead happy.
135386 */
135387 if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
135388 if( !p->pSrc->a[0].fg.notIndexed ){
135389 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
135390 if( pIdx->bUnordered==0
135391 && pIdx->szIdxRow<pTab->szTabRow
135392 && pIdx->pPartIdxWhere==0
135393 && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
135394 ){
135395 pBest = pIdx;
135396 }
135397 }
135398 }
135399 if( pBest ){
135400 iRoot = pBest->tnum;
135401 pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
@@ -134626,13 +135407,11 @@
135407 sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
135408 }
135409 sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
135410 sqlite3VdbeAddOp1(v, OP_Close, iCsr);
135411 explainSimpleCount(pParse, pTab, pBest);
135412 }else{
 
 
135413 int regAcc = 0; /* "populate accumulators" flag */
135414
135415 /* If there are accumulator registers but no min() or max() functions
135416 ** without FILTER clauses, allocate register regAcc. Register regAcc
135417 ** will contain 0 the first time the inner loop runs, and 1 thereafter.
@@ -137852,11 +138631,11 @@
138631 db->mDbFlags = saved_mDbFlags;
138632 db->flags = saved_flags;
138633 db->nChange = saved_nChange;
138634 db->nTotalChange = saved_nTotalChange;
138635 db->mTrace = saved_mTrace;
138636 sqlite3BtreeSetPageSize(pMain, -1, 0, 1);
138637
138638 /* Currently there is an SQL level transaction open on the vacuum
138639 ** database. No locks are held on any other files (since the main file
138640 ** was committed at the btree level). So it safe to end the transaction
138641 ** by manually setting the autoCommit flag to true and detaching the
@@ -159255,19 +160034,82 @@
160034
160035
160036 /************** End of sqliteicu.h *******************************************/
160037 /************** Continuing where we left off in main.c ***********************/
160038 #endif
160039
160040 /*
160041 ** This is an extension initializer that is a no-op and always
160042 ** succeeds, except that it fails if the fault-simulation is set
160043 ** to 500.
160044 */
160045 static int sqlite3TestExtInit(sqlite3 *db){
160046 (void)db;
160047 return sqlite3FaultSim(500);
160048 }
160049
160050
160051 /*
160052 ** Forward declarations of external module initializer functions
160053 ** for modules that need them.
160054 */
160055 #ifdef SQLITE_ENABLE_FTS1
160056 SQLITE_PRIVATE int sqlite3Fts1Init(sqlite3*);
160057 #endif
160058 #ifdef SQLITE_ENABLE_FTS2
160059 SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*);
160060 #endif
160061 #ifdef SQLITE_ENABLE_FTS5
160062 SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
160063 #endif
160064 #ifdef SQLITE_ENABLE_JSON1
160065 SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
160066 #endif
160067 #ifdef SQLITE_ENABLE_STMTVTAB
160068 SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
160069 #endif
160070
160071 /*
160072 ** An array of pointers to extension initializer functions for
160073 ** built-in extensions.
160074 */
160075 static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
160076 #ifdef SQLITE_ENABLE_FTS1
160077 sqlite3Fts1Init,
160078 #endif
160079 #ifdef SQLITE_ENABLE_FTS2
160080 sqlite3Fts2Init,
160081 #endif
160082 #ifdef SQLITE_ENABLE_FTS3
160083 sqlite3Fts3Init,
160084 #endif
160085 #ifdef SQLITE_ENABLE_FTS5
160086 sqlite3Fts5Init,
160087 #endif
160088 #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
160089 sqlite3IcuInit,
160090 #endif
160091 #ifdef SQLITE_ENABLE_RTREE
160092 sqlite3RtreeInit,
160093 #endif
160094 #ifdef SQLITE_ENABLE_DBPAGE_VTAB
160095 sqlite3DbpageRegister,
160096 #endif
160097 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
160098 sqlite3DbstatRegister,
160099 #endif
160100 sqlite3TestExtInit,
160101 #ifdef SQLITE_ENABLE_JSON1
160102 sqlite3Json1Init,
160103 #endif
160104 #ifdef SQLITE_ENABLE_STMTVTAB
160105 sqlite3StmtVtabInit,
160106 #endif
160107 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
160108 sqlite3VdbeBytecodeVtabInit,
160109 #endif
160110 };
160111
160112 #ifndef SQLITE_AMALGAMATION
160113 /* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
160114 ** contains the text of SQLITE_VERSION macro.
160115 */
@@ -160781,12 +161623,11 @@
161623 ** Return non-zero to retry the lock. Return zero to stop trying
161624 ** and cause SQLite to return SQLITE_BUSY.
161625 */
161626 static int sqliteDefaultBusyCallback(
161627 void *ptr, /* Database connection */
161628 int count /* Number of times table has been busy */
 
161629 ){
161630 #if SQLITE_OS_WIN || HAVE_USLEEP
161631 /* This case is for systems that have support for sleeping for fractions of
161632 ** a second. Examples: All windows systems, unix systems with usleep() */
161633 static const u8 delays[] =
@@ -160796,35 +161637,10 @@
161637 # define NDELAY ArraySize(delays)
161638 sqlite3 *db = (sqlite3 *)ptr;
161639 int tmout = db->busyTimeout;
161640 int delay, prior;
161641
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161642 assert( count>=0 );
161643 if( count < NDELAY ){
161644 delay = delays[count];
161645 prior = totals[count];
161646 }else{
@@ -160840,11 +161656,10 @@
161656 #else
161657 /* This case for unix systems that lack usleep() support. Sleeping
161658 ** must be done in increments of whole seconds */
161659 sqlite3 *db = (sqlite3 *)ptr;
161660 int tmout = ((sqlite3 *)ptr)->busyTimeout;
 
161661 if( (count+1)*1000 > tmout ){
161662 return 0;
161663 }
161664 sqlite3OsSleep(db->pVfs, 1000000);
161665 return 1;
@@ -160858,23 +161673,14 @@
161673 ** lock on VFS file pFile.
161674 **
161675 ** If this routine returns non-zero, the lock is retried. If it
161676 ** returns 0, the operation aborts with an SQLITE_BUSY error.
161677 */
161678 SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
161679 int rc;
161680 if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
161681 rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
 
 
 
 
 
 
 
 
 
161682 if( rc==0 ){
161683 p->nBusy = -1;
161684 }else{
161685 p->nBusy++;
161686 }
@@ -160895,11 +161701,10 @@
161701 #endif
161702 sqlite3_mutex_enter(db->mutex);
161703 db->busyHandler.xBusyHandler = xBusy;
161704 db->busyHandler.pBusyArg = pArg;
161705 db->busyHandler.nBusy = 0;
 
161706 db->busyTimeout = 0;
161707 sqlite3_mutex_leave(db->mutex);
161708 return SQLITE_OK;
161709 }
161710
@@ -160946,11 +161751,10 @@
161751 #endif
161752 if( ms>0 ){
161753 sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
161754 (void*)db);
161755 db->busyTimeout = ms;
 
161756 }else{
161757 sqlite3_busy_handler(db, 0, 0);
161758 }
161759 return SQLITE_OK;
161760 }
@@ -162272,10 +163076,11 @@
163076 sqlite3 *db; /* Store allocated handle here */
163077 int rc; /* Return code */
163078 int isThreadsafe; /* True for threadsafe connections */
163079 char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
163080 char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
163081 int i; /* Loop counter */
163082
163083 #ifdef SQLITE_ENABLE_API_ARMOR
163084 if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
163085 #endif
163086 *ppDb = 0;
@@ -162420,10 +163225,13 @@
163225 | SQLITE_EnableQPSG
163226 #endif
163227 #if defined(SQLITE_DEFAULT_DEFENSIVE)
163228 | SQLITE_Defensive
163229 #endif
163230 #if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE)
163231 | SQLITE_LegacyAlter
163232 #endif
163233 ;
163234 sqlite3HashInit(&db->aCollSeq);
163235 #ifndef SQLITE_OMIT_VIRTUALTABLE
163236 sqlite3HashInit(&db->aModule);
163237 #endif
@@ -162512,18 +163320,15 @@
163320 */
163321 sqlite3Error(db, SQLITE_OK);
163322 sqlite3RegisterPerConnectionBuiltinFunctions(db);
163323 rc = sqlite3_errcode(db);
163324
163325
163326 /* Load compiled-in extensions */
163327 for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
163328 rc = sqlite3BuiltinExtensions[i](db);
163329 }
 
 
 
163330
163331 /* Load automatic extensions - extensions that have been registered
163332 ** using the sqlite3_automatic_extension() API.
163333 */
163334 if( rc==SQLITE_OK ){
@@ -162532,66 +163337,10 @@
163337 if( rc!=SQLITE_OK ){
163338 goto opendb_out;
163339 }
163340 }
163341
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163342 #ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
163343 /* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
163344 ** option gives access to internal functions by default.
163345 ** Testing use only!!! */
163346 db->mDbFlags |= DBFLAG_InternalFunc;
@@ -163076,11 +163825,11 @@
163825 *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
163826 rc = SQLITE_OK;
163827 }else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
163828 int iNew = *(int*)pArg;
163829 *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
163830 if( iNew>=0 && iNew<=255 ){
163831 sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
163832 }
163833 rc = SQLITE_OK;
163834 }else{
163835 rc = sqlite3OsFileControl(fd, op, pArg);
@@ -165357,10 +166106,11 @@
166106 SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
166107 SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
166108 SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
166109 SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
166110 SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
166111 SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut);
166112
166113 /* fts3_tokenizer.c */
166114 SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
166115 SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
166116 SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -166088,10 +166838,26 @@
166838 fts3Appendf(pRc, &zRet, ", ?");
166839 }
166840 sqlite3_free(zFree);
166841 return zRet;
166842 }
166843
166844 /*
166845 ** Buffer z contains a positive integer value encoded as utf-8 text.
166846 ** Decode this value and store it in *pnOut, returning the number of bytes
166847 ** consumed. If an overflow error occurs return a negative value.
166848 */
166849 SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut){
166850 u64 iVal = 0;
166851 int i;
166852 for(i=0; z[i]>='0' && z[i]<='9'; i++){
166853 iVal = iVal*10 + (z[i] - '0');
166854 if( iVal>0x7FFFFFFF ) return -1;
166855 }
166856 *pnOut = (int)iVal;
166857 return i;
166858 }
166859
166860 /*
166861 ** This function interprets the string at (*pp) as a non-negative integer
166862 ** value. It reads the integer and sets *pnOut to the value read, then
166863 ** sets *pp to point to the byte immediately following the last byte of
@@ -166104,23 +166870,21 @@
166870 **
166871 ** This function is used when parsing the "prefix=" FTS4 parameter.
166872 */
166873 static int fts3GobbleInt(const char **pp, int *pnOut){
166874 const int MAX_NPREFIX = 10000000;
 
166875 int nInt = 0; /* Output value */
166876 int nByte;
166877 nByte = sqlite3Fts3ReadInt(*pp, &nInt);
166878 if( nInt>MAX_NPREFIX ){
166879 nInt = 0;
166880 }
166881 if( nByte==0 ){
166882 return SQLITE_ERROR;
166883 }
 
166884 *pnOut = nInt;
166885 *pp += nByte;
166886 return SQLITE_OK;
166887 }
166888
166889 /*
166890 ** This function is called to allocate an array of Fts3Index structures
@@ -167298,11 +168062,13 @@
168062 static void fts3ReadNextPos(
168063 char **pp, /* IN/OUT: Pointer into position-list buffer */
168064 sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
168065 ){
168066 if( (**pp)&0xFE ){
168067 int iVal;
168068 *pp += fts3GetVarint32((*pp), &iVal);
168069 *pi += iVal;
168070 *pi -= 2;
168071 }else{
168072 *pi = POSITION_LIST_END;
168073 }
168074 }
@@ -172198,14 +172964,11 @@
172964
172965 /* If this is a "NEAR" keyword, check for an explicit nearness. */
172966 if( pKey->eType==FTSQUERY_NEAR ){
172967 assert( nKey==4 );
172968 if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
172969 nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
 
 
 
172970 }
172971 }
172972
172973 /* At this point this is probably a keyword. But for that to be true,
172974 ** the next byte must contain either whitespace, an open or close
@@ -178384,25 +179147,25 @@
179147 ){
179148 const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
179149 if( zText ){
179150 int i;
179151 int iMul = 1;
179152 u64 iVal = 0;
179153 for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
179154 iVal = iVal*10 + (zText[i] - '0');
179155 }
179156 *piEndBlock = (i64)iVal;
179157 while( zText[i]==' ' ) i++;
179158 iVal = 0;
179159 if( zText[i]=='-' ){
179160 i++;
179161 iMul = -1;
179162 }
179163 for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
179164 iVal = iVal*10 + (zText[i] - '0');
179165 }
179166 *pnByte = ((i64)iVal * (i64)iMul);
179167 }
179168 }
179169
179170
179171 /*
@@ -223901,11 +224664,11 @@
224664 int nArg, /* Number of args */
224665 sqlite3_value **apUnused /* Function arguments */
224666 ){
224667 assert( nArg==0 );
224668 UNUSED_PARAM2(nArg, apUnused);
224669 sqlite3_result_text(pCtx, "fts5: 2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff", -1, SQLITE_TRANSIENT);
224670 }
224671
224672 /*
224673 ** Return true if zName is the extension on one of the shadow tables used
224674 ** by this module.
@@ -228552,11 +229315,12 @@
229315 }
229316 case STMT_COLUMN_BUSY: {
229317 sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
229318 break;
229319 }
229320 default: {
229321 assert( i==STMT_COLUMN_MEM );
229322 i = SQLITE_STMTSTATUS_MEMUSED +
229323 STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
229324 /* Fall thru */
229325 }
229326 case STMT_COLUMN_NSCAN:
@@ -228683,12 +229447,12 @@
229447 }
229448 #endif /* SQLITE_CORE */
229449 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
229450
229451 /************** End of stmt.c ************************************************/
229452 #if __LINE__!=229452
229453 #undef SQLITE_SOURCE_ID
229454 #define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f96alt2"
229455 #endif
229456 /* Return the source-id for this library */
229457 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
229458 /************************** End of sqlite3.c ******************************/
229459
+58 -23
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -123,11 +123,11 @@
123123
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124124
** [sqlite_version()] and [sqlite_source_id()].
125125
*/
126126
#define SQLITE_VERSION "3.32.0"
127127
#define SQLITE_VERSION_NUMBER 3032000
128
-#define SQLITE_SOURCE_ID "2020-04-20 17:35:32 2fc80ef16ce5878311ab88a0c64631813572ffbb71f75363b4619c9667e0926b"
128
+#define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff"
129129
130130
/*
131131
** CAPI3REF: Run-Time Library Version Numbers
132132
** KEYWORDS: sqlite3_version sqlite3_sourceid
133133
**
@@ -297,30 +297,26 @@
297297
** for the [sqlite3] object.
298298
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
299299
** the [sqlite3] object is successfully destroyed and all associated
300300
** resources are deallocated.
301301
**
302
+** Ideally, applications should [sqlite3_finalize | finalize] all
303
+** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
304
+** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
305
+** with the [sqlite3] object prior to attempting to close the object.
302306
** ^If the database connection is associated with unfinalized prepared
303
-** statements or unfinished sqlite3_backup objects then sqlite3_close()
304
-** will leave the database connection open and return [SQLITE_BUSY].
305
-** ^If sqlite3_close_v2() is called with unfinalized prepared statements
306
-** and/or unfinished sqlite3_backups, then the database connection becomes
307
-** an unusable "zombie" which will automatically be deallocated when the
308
-** last prepared statement is finalized or the last sqlite3_backup is
309
-** finished. The sqlite3_close_v2() interface is intended for use with
310
-** host languages that are garbage collected, and where the order in which
311
-** destructors are called is arbitrary.
312
-**
313
-** Applications should [sqlite3_finalize | finalize] all [prepared statements],
314
-** [sqlite3_blob_close | close] all [BLOB handles], and
315
-** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
316
-** with the [sqlite3] object prior to attempting to close the object. ^If
317
-** sqlite3_close_v2() is called on a [database connection] that still has
318
-** outstanding [prepared statements], [BLOB handles], and/or
319
-** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
320
-** of resources is deferred until all [prepared statements], [BLOB handles],
321
-** and [sqlite3_backup] objects are also destroyed.
307
+** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
308
+** sqlite3_close() will leave the database connection open and return
309
+** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
310
+** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
311
+** it returns [SQLITE_OK] regardless, but instead of deallocating the database
312
+** connection immediately, it marks the database connection as an unusable
313
+** "zombie" and makes arrangements to automatically deallocate the database
314
+** connection after all prepared statements are finalized, all BLOB handles
315
+** are closed, and all backups have finished. The sqlite3_close_v2() interface
316
+** is intended for use with host languages that are garbage collected, and
317
+** where the order in which destructors are called is arbitrary.
322318
**
323319
** ^If an [sqlite3] object is destroyed while a transaction is open,
324320
** the transaction is automatically rolled back.
325321
**
326322
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
@@ -505,22 +501,25 @@
505501
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
506502
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
507503
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
508504
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
509505
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
506
+#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
510507
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
511508
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
512509
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
513510
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
511
+#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
514512
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
515513
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
516514
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
517515
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
518516
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
519517
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
520518
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
521519
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
520
+#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
522521
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
523522
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
524523
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
525524
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
526525
#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
@@ -1111,10 +1110,15 @@
11111110
** a single attached database that occur due to other database connections,
11121111
** but omits changes implemented by the database connection on which it is
11131112
** called. This file control is the only mechanism to detect changes that
11141113
** happen either internally or externally and that are associated with
11151114
** a particular attached database.
1115
+**
1116
+** <li>[[SQLITE_FCNTL_CKPT_START]]
1117
+** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
1118
+** in wal mode before the client starts to copy pages from the wal
1119
+** file to the database file.
11161120
**
11171121
** <li>[[SQLITE_FCNTL_CKPT_DONE]]
11181122
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
11191123
** in wal mode after the client has finished copying pages from the wal
11201124
** file to the database file, but before the *-shm file is updated to
@@ -1156,10 +1160,11 @@
11561160
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
11571161
#define SQLITE_FCNTL_DATA_VERSION 35
11581162
#define SQLITE_FCNTL_SIZE_LIMIT 36
11591163
#define SQLITE_FCNTL_CKPT_DONE 37
11601164
#define SQLITE_FCNTL_RESERVE_BYTES 38
1165
+#define SQLITE_FCNTL_CKPT_START 39
11611166
11621167
/* deprecated names */
11631168
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
11641169
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
11651170
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3534,12 +3539,23 @@
35343539
**
35353540
** These are utility routines, useful to [VFS|custom VFS implementations],
35363541
** that check if a database file was a URI that contained a specific query
35373542
** parameter, and if so obtains the value of that query parameter.
35383543
**
3539
-** If F is the database filename pointer passed into the xOpen() method of
3540
-** a VFS implementation or it is the return value of [sqlite3_db_filename()]
3544
+** The first parameter to these interfaces (hereafter referred to
3545
+** as F) must be one of:
3546
+** <ul>
3547
+** <li> A database filename pointer created by the SQLite core and
3548
+** passed into the xOpen() method of a VFS implemention, or
3549
+** <li> A filename obtained from [sqlite3_db_filename()], or
3550
+** <li> A new filename constructed using [sqlite3_create_filename()].
3551
+** </ul>
3552
+** If the F parameter is not one of the above, then the behavior is
3553
+** undefined and probably undesirable. Older versions of SQLite were
3554
+** more tolerant of invalid F parameters than newer versions.
3555
+**
3556
+** If F is a suitable filename (as described in the previous paragraph)
35413557
** and if P is the name of the query parameter, then
35423558
** sqlite3_uri_parameter(F,P) returns the value of the P
35433559
** parameter if it exists or a NULL pointer if P does not appear as a
35443560
** query parameter on F. If P is a query parameter of F and it
35453561
** has no explicit value, then sqlite3_uri_parameter(F,P) returns
@@ -3618,10 +3634,29 @@
36183634
*/
36193635
SQLITE_API const char *sqlite3_filename_database(const char*);
36203636
SQLITE_API const char *sqlite3_filename_journal(const char*);
36213637
SQLITE_API const char *sqlite3_filename_wal(const char*);
36223638
3639
+/*
3640
+** CAPI3REF: Database File Corresponding To A Journal
3641
+**
3642
+** ^If X is the name of a rollback or WAL-mode journal file that is
3643
+** passed into the xOpen method of [sqlite3_vfs], then
3644
+** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
3645
+** object that represents the main database file.
3646
+**
3647
+** This routine is intended for use in custom [VFS] implementations
3648
+** only. It is not a general-purpose interface.
3649
+** The argument sqlite3_file_object(X) must be a filename pointer that
3650
+** has been passed into [sqlite3_vfs].xOpen method where the
3651
+** flags parameter to xOpen contains one of the bits
3652
+** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
3653
+** of this routine results in undefined and probably undesirable
3654
+** behavior.
3655
+*/
3656
+SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
3657
+
36233658
/*
36243659
** CAPI3REF: Create and Destroy VFS Filenames
36253660
**
36263661
** These interfces are provided for use by [VFS shim] implementations and
36273662
** are not useful outside of that context.
@@ -3652,11 +3687,11 @@
36523687
** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
36533688
** be NULL pointers, though they can be empty strings.
36543689
**
36553690
** The sqlite3_free_filename(Y) routine releases a memory allocation
36563691
** previously obtained from sqlite3_create_filename(). Invoking
3657
-** sqlite3_free_filename(Y) is a NULL pointer is a harmless no-op.
3692
+** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
36583693
**
36593694
** If the Y parameter to sqlite3_free_filename(Y) is anything other
36603695
** than a NULL pointer or a pointer previously acquired from
36613696
** sqlite3_create_filename(), then bad things such as heap
36623697
** corruption or segfaults may occur. The value Y should be
36633698
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -123,11 +123,11 @@
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.32.0"
127 #define SQLITE_VERSION_NUMBER 3032000
128 #define SQLITE_SOURCE_ID "2020-04-20 17:35:32 2fc80ef16ce5878311ab88a0c64631813572ffbb71f75363b4619c9667e0926b"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
@@ -297,30 +297,26 @@
297 ** for the [sqlite3] object.
298 ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
299 ** the [sqlite3] object is successfully destroyed and all associated
300 ** resources are deallocated.
301 **
 
 
 
 
302 ** ^If the database connection is associated with unfinalized prepared
303 ** statements or unfinished sqlite3_backup objects then sqlite3_close()
304 ** will leave the database connection open and return [SQLITE_BUSY].
305 ** ^If sqlite3_close_v2() is called with unfinalized prepared statements
306 ** and/or unfinished sqlite3_backups, then the database connection becomes
307 ** an unusable "zombie" which will automatically be deallocated when the
308 ** last prepared statement is finalized or the last sqlite3_backup is
309 ** finished. The sqlite3_close_v2() interface is intended for use with
310 ** host languages that are garbage collected, and where the order in which
311 ** destructors are called is arbitrary.
312 **
313 ** Applications should [sqlite3_finalize | finalize] all [prepared statements],
314 ** [sqlite3_blob_close | close] all [BLOB handles], and
315 ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
316 ** with the [sqlite3] object prior to attempting to close the object. ^If
317 ** sqlite3_close_v2() is called on a [database connection] that still has
318 ** outstanding [prepared statements], [BLOB handles], and/or
319 ** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
320 ** of resources is deferred until all [prepared statements], [BLOB handles],
321 ** and [sqlite3_backup] objects are also destroyed.
322 **
323 ** ^If an [sqlite3] object is destroyed while a transaction is open,
324 ** the transaction is automatically rolled back.
325 **
326 ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
@@ -505,22 +501,25 @@
505 #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
506 #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
507 #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
508 #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
509 #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
 
510 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
511 #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
512 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
513 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
 
514 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
515 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
516 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
517 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
518 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
519 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
520 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
521 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
 
522 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
523 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
524 #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
525 #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
526 #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
@@ -1111,10 +1110,15 @@
1111 ** a single attached database that occur due to other database connections,
1112 ** but omits changes implemented by the database connection on which it is
1113 ** called. This file control is the only mechanism to detect changes that
1114 ** happen either internally or externally and that are associated with
1115 ** a particular attached database.
 
 
 
 
 
1116 **
1117 ** <li>[[SQLITE_FCNTL_CKPT_DONE]]
1118 ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
1119 ** in wal mode after the client has finished copying pages from the wal
1120 ** file to the database file, but before the *-shm file is updated to
@@ -1156,10 +1160,11 @@
1156 #define SQLITE_FCNTL_LOCK_TIMEOUT 34
1157 #define SQLITE_FCNTL_DATA_VERSION 35
1158 #define SQLITE_FCNTL_SIZE_LIMIT 36
1159 #define SQLITE_FCNTL_CKPT_DONE 37
1160 #define SQLITE_FCNTL_RESERVE_BYTES 38
 
1161
1162 /* deprecated names */
1163 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1164 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1165 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3534,12 +3539,23 @@
3534 **
3535 ** These are utility routines, useful to [VFS|custom VFS implementations],
3536 ** that check if a database file was a URI that contained a specific query
3537 ** parameter, and if so obtains the value of that query parameter.
3538 **
3539 ** If F is the database filename pointer passed into the xOpen() method of
3540 ** a VFS implementation or it is the return value of [sqlite3_db_filename()]
 
 
 
 
 
 
 
 
 
 
 
3541 ** and if P is the name of the query parameter, then
3542 ** sqlite3_uri_parameter(F,P) returns the value of the P
3543 ** parameter if it exists or a NULL pointer if P does not appear as a
3544 ** query parameter on F. If P is a query parameter of F and it
3545 ** has no explicit value, then sqlite3_uri_parameter(F,P) returns
@@ -3618,10 +3634,29 @@
3618 */
3619 SQLITE_API const char *sqlite3_filename_database(const char*);
3620 SQLITE_API const char *sqlite3_filename_journal(const char*);
3621 SQLITE_API const char *sqlite3_filename_wal(const char*);
3622
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3623 /*
3624 ** CAPI3REF: Create and Destroy VFS Filenames
3625 **
3626 ** These interfces are provided for use by [VFS shim] implementations and
3627 ** are not useful outside of that context.
@@ -3652,11 +3687,11 @@
3652 ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
3653 ** be NULL pointers, though they can be empty strings.
3654 **
3655 ** The sqlite3_free_filename(Y) routine releases a memory allocation
3656 ** previously obtained from sqlite3_create_filename(). Invoking
3657 ** sqlite3_free_filename(Y) is a NULL pointer is a harmless no-op.
3658 **
3659 ** If the Y parameter to sqlite3_free_filename(Y) is anything other
3660 ** than a NULL pointer or a pointer previously acquired from
3661 ** sqlite3_create_filename(), then bad things such as heap
3662 ** corruption or segfaults may occur. The value Y should be
3663
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -123,11 +123,11 @@
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.32.0"
127 #define SQLITE_VERSION_NUMBER 3032000
128 #define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
@@ -297,30 +297,26 @@
297 ** for the [sqlite3] object.
298 ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
299 ** the [sqlite3] object is successfully destroyed and all associated
300 ** resources are deallocated.
301 **
302 ** Ideally, applications should [sqlite3_finalize | finalize] all
303 ** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
304 ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
305 ** with the [sqlite3] object prior to attempting to close the object.
306 ** ^If the database connection is associated with unfinalized prepared
307 ** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
308 ** sqlite3_close() will leave the database connection open and return
309 ** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
310 ** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
311 ** it returns [SQLITE_OK] regardless, but instead of deallocating the database
312 ** connection immediately, it marks the database connection as an unusable
313 ** "zombie" and makes arrangements to automatically deallocate the database
314 ** connection after all prepared statements are finalized, all BLOB handles
315 ** are closed, and all backups have finished. The sqlite3_close_v2() interface
316 ** is intended for use with host languages that are garbage collected, and
317 ** where the order in which destructors are called is arbitrary.
 
 
 
 
 
 
 
 
318 **
319 ** ^If an [sqlite3] object is destroyed while a transaction is open,
320 ** the transaction is automatically rolled back.
321 **
322 ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
@@ -505,22 +501,25 @@
501 #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
502 #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
503 #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
504 #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
505 #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
506 #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
507 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
508 #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
509 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
510 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
511 #define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
512 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
513 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
514 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
515 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
516 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
517 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
518 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
519 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
520 #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
521 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
522 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
523 #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
524 #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
525 #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
@@ -1111,10 +1110,15 @@
1110 ** a single attached database that occur due to other database connections,
1111 ** but omits changes implemented by the database connection on which it is
1112 ** called. This file control is the only mechanism to detect changes that
1113 ** happen either internally or externally and that are associated with
1114 ** a particular attached database.
1115 **
1116 ** <li>[[SQLITE_FCNTL_CKPT_START]]
1117 ** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
1118 ** in wal mode before the client starts to copy pages from the wal
1119 ** file to the database file.
1120 **
1121 ** <li>[[SQLITE_FCNTL_CKPT_DONE]]
1122 ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
1123 ** in wal mode after the client has finished copying pages from the wal
1124 ** file to the database file, but before the *-shm file is updated to
@@ -1156,10 +1160,11 @@
1160 #define SQLITE_FCNTL_LOCK_TIMEOUT 34
1161 #define SQLITE_FCNTL_DATA_VERSION 35
1162 #define SQLITE_FCNTL_SIZE_LIMIT 36
1163 #define SQLITE_FCNTL_CKPT_DONE 37
1164 #define SQLITE_FCNTL_RESERVE_BYTES 38
1165 #define SQLITE_FCNTL_CKPT_START 39
1166
1167 /* deprecated names */
1168 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1169 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1170 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3534,12 +3539,23 @@
3539 **
3540 ** These are utility routines, useful to [VFS|custom VFS implementations],
3541 ** that check if a database file was a URI that contained a specific query
3542 ** parameter, and if so obtains the value of that query parameter.
3543 **
3544 ** The first parameter to these interfaces (hereafter referred to
3545 ** as F) must be one of:
3546 ** <ul>
3547 ** <li> A database filename pointer created by the SQLite core and
3548 ** passed into the xOpen() method of a VFS implemention, or
3549 ** <li> A filename obtained from [sqlite3_db_filename()], or
3550 ** <li> A new filename constructed using [sqlite3_create_filename()].
3551 ** </ul>
3552 ** If the F parameter is not one of the above, then the behavior is
3553 ** undefined and probably undesirable. Older versions of SQLite were
3554 ** more tolerant of invalid F parameters than newer versions.
3555 **
3556 ** If F is a suitable filename (as described in the previous paragraph)
3557 ** and if P is the name of the query parameter, then
3558 ** sqlite3_uri_parameter(F,P) returns the value of the P
3559 ** parameter if it exists or a NULL pointer if P does not appear as a
3560 ** query parameter on F. If P is a query parameter of F and it
3561 ** has no explicit value, then sqlite3_uri_parameter(F,P) returns
@@ -3618,10 +3634,29 @@
3634 */
3635 SQLITE_API const char *sqlite3_filename_database(const char*);
3636 SQLITE_API const char *sqlite3_filename_journal(const char*);
3637 SQLITE_API const char *sqlite3_filename_wal(const char*);
3638
3639 /*
3640 ** CAPI3REF: Database File Corresponding To A Journal
3641 **
3642 ** ^If X is the name of a rollback or WAL-mode journal file that is
3643 ** passed into the xOpen method of [sqlite3_vfs], then
3644 ** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
3645 ** object that represents the main database file.
3646 **
3647 ** This routine is intended for use in custom [VFS] implementations
3648 ** only. It is not a general-purpose interface.
3649 ** The argument sqlite3_file_object(X) must be a filename pointer that
3650 ** has been passed into [sqlite3_vfs].xOpen method where the
3651 ** flags parameter to xOpen contains one of the bits
3652 ** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
3653 ** of this routine results in undefined and probably undesirable
3654 ** behavior.
3655 */
3656 SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
3657
3658 /*
3659 ** CAPI3REF: Create and Destroy VFS Filenames
3660 **
3661 ** These interfces are provided for use by [VFS shim] implementations and
3662 ** are not useful outside of that context.
@@ -3652,11 +3687,11 @@
3687 ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
3688 ** be NULL pointers, though they can be empty strings.
3689 **
3690 ** The sqlite3_free_filename(Y) routine releases a memory allocation
3691 ** previously obtained from sqlite3_create_filename(). Invoking
3692 ** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
3693 **
3694 ** If the Y parameter to sqlite3_free_filename(Y) is anything other
3695 ** than a NULL pointer or a pointer previously acquired from
3696 ** sqlite3_create_filename(), then bad things such as heap
3697 ** corruption or segfaults may occur. The value Y should be
3698
+2 -1
--- src/style.c
+++ src/style.c
@@ -707,11 +707,11 @@
707707
708708
/*
709709
** Generate code to load a single javascript file
710710
*/
711711
void style_load_one_js_file(const char *zFile){
712
- @ <script src='%R/builtin/%s(zFile)?id=%S(MANIFEST_UUID)'></script>
712
+ @ <script src='%R/builtin/%s(zFile)?id=%S(fossil_exe_id())'></script>
713713
}
714714
715715
/*
716716
** All extra JS files to load.
717717
*/
@@ -1259,10 +1259,11 @@
12591259
@ anonymous-adds = %s(find_anon_capabilities(zCap))<br />
12601260
}
12611261
@ g.zRepositoryName = %h(g.zRepositoryName)<br />
12621262
@ load_average() = %f(load_average())<br />
12631263
@ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
1264
+ @ fossil_exe_id() = %h(fossil_exe_id())<br />
12641265
@ <hr />
12651266
P("HTTP_USER_AGENT");
12661267
cgi_print_all(showAll, 0);
12671268
if( showAll && blob_size(&g.httpHeader)>0 ){
12681269
@ <hr />
12691270
12701271
ADDED src/terminal.c
--- src/style.c
+++ src/style.c
@@ -707,11 +707,11 @@
707
708 /*
709 ** Generate code to load a single javascript file
710 */
711 void style_load_one_js_file(const char *zFile){
712 @ <script src='%R/builtin/%s(zFile)?id=%S(MANIFEST_UUID)'></script>
713 }
714
715 /*
716 ** All extra JS files to load.
717 */
@@ -1259,10 +1259,11 @@
1259 @ anonymous-adds = %s(find_anon_capabilities(zCap))<br />
1260 }
1261 @ g.zRepositoryName = %h(g.zRepositoryName)<br />
1262 @ load_average() = %f(load_average())<br />
1263 @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
 
1264 @ <hr />
1265 P("HTTP_USER_AGENT");
1266 cgi_print_all(showAll, 0);
1267 if( showAll && blob_size(&g.httpHeader)>0 ){
1268 @ <hr />
1269
1270 DDED src/terminal.c
--- src/style.c
+++ src/style.c
@@ -707,11 +707,11 @@
707
708 /*
709 ** Generate code to load a single javascript file
710 */
711 void style_load_one_js_file(const char *zFile){
712 @ <script src='%R/builtin/%s(zFile)?id=%S(fossil_exe_id())'></script>
713 }
714
715 /*
716 ** All extra JS files to load.
717 */
@@ -1259,10 +1259,11 @@
1259 @ anonymous-adds = %s(find_anon_capabilities(zCap))<br />
1260 }
1261 @ g.zRepositoryName = %h(g.zRepositoryName)<br />
1262 @ load_average() = %f(load_average())<br />
1263 @ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
1264 @ fossil_exe_id() = %h(fossil_exe_id())<br />
1265 @ <hr />
1266 P("HTTP_USER_AGENT");
1267 cgi_print_all(showAll, 0);
1268 if( showAll && blob_size(&g.httpHeader)>0 ){
1269 @ <hr />
1270
1271 DDED src/terminal.c
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -0,0 +1,9 @@
1
+COMMAND: test-terminal-size
2
+**
3
+** Show the size of the terminal window from which the command is launched
4
+** as two integers, the width in characters and the height in lines.
5
+**
6
+** If the size cannot be determined, two zeros are shown.
7
+*/
8
+void test_terminal_size_cmd(void* Technically, this infosuch is supported; set;
9
+ fossil_print("%d %d\nchar *zNoC!=-1!=-1
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -0,0 +1,9 @@
1 COMMAND: test-terminal-size
2 **
3 ** Show the size of the terminal window from which the command is launched
4 ** as two integers, the width in characters and the height in lines.
5 **
6 ** If the size cannot be determined, two zeros are shown.
7 */
8 void test_terminal_size_cmd(void* Technically, this infosuch is supported; set;
9 fossil_print("%d %d\nchar *zNoC!=-1!=-1
+12 -1
--- src/timeline.c
+++ src/timeline.c
@@ -1312,11 +1312,11 @@
13121312
){
13131313
if( zChng==0 || zChng[0]==0 ) return;
13141314
blob_append_sql(pSql," AND event.objid IN ("
13151315
"SELECT mlink.mid FROM mlink, filename"
13161316
" WHERE mlink.fnid=filename.fnid AND %s)",
1317
- glob_expr("filename.name", zChng));
1317
+ glob_expr("filename.name", mprintf("\"%s\"", zChng)));
13181318
}
13191319
static void addFileGlobDescription(
13201320
const char *zChng, /* The filename GLOB list */
13211321
Blob *pDescription /* Result description */
13221322
){
@@ -1742,10 +1742,11 @@
17421742
|| (bisectLocal && !g.perm.Setup)
17431743
){
17441744
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
17451745
return;
17461746
}
1747
+ etag_check(ETAG_QUERY|ETAG_COOKIE|ETAG_DATA, 0);
17471748
cookie_read_parameter("y","y");
17481749
zType = P("y");
17491750
if( zType==0 ){
17501751
zType = g.perm.Read ? "ci" : "all";
17511752
cgi_set_parameter("y", zType);
@@ -2200,10 +2201,17 @@
22002201
"CREATE TEMP TABLE selected_nodes(rid INTEGER PRIMARY KEY);"
22012202
"INSERT OR IGNORE INTO selected_nodes"
22022203
" SELECT tagxref.rid FROM tagxref NATURAL JOIN tag"
22032204
" WHERE %s AND tagtype>0", zTagSql/*safe-for-%s*/
22042205
);
2206
+ if( zMark ){
2207
+ /* If the t=release option is used with m=UUID, then also
2208
+ ** include the UUID check-in in the display list */
2209
+ int ridMark = name_to_rid(zMark);
2210
+ db_multi_exec(
2211
+ "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark);
2212
+ }
22052213
if( !related ){
22062214
blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
22072215
}else{
22082216
db_multi_exec(
22092217
"CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
@@ -2426,10 +2434,13 @@
24262434
blob_appendf(&desc, " related to tags matching %h", zMatchDesc);
24272435
}else{
24282436
blob_appendf(&desc, " with tags matching %h", zMatchDesc);
24292437
}
24302438
}
2439
+ if( zMark ){
2440
+ blob_appendf(&desc," plus check-in \"%h\"", zMark);
2441
+ }
24312442
tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
24322443
}
24332444
addFileGlobDescription(zChng, &desc);
24342445
if( rAfter>0.0 ){
24352446
if( rBefore>0.0 ){
24362447
--- src/timeline.c
+++ src/timeline.c
@@ -1312,11 +1312,11 @@
1312 ){
1313 if( zChng==0 || zChng[0]==0 ) return;
1314 blob_append_sql(pSql," AND event.objid IN ("
1315 "SELECT mlink.mid FROM mlink, filename"
1316 " WHERE mlink.fnid=filename.fnid AND %s)",
1317 glob_expr("filename.name", zChng));
1318 }
1319 static void addFileGlobDescription(
1320 const char *zChng, /* The filename GLOB list */
1321 Blob *pDescription /* Result description */
1322 ){
@@ -1742,10 +1742,11 @@
1742 || (bisectLocal && !g.perm.Setup)
1743 ){
1744 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
1745 return;
1746 }
 
1747 cookie_read_parameter("y","y");
1748 zType = P("y");
1749 if( zType==0 ){
1750 zType = g.perm.Read ? "ci" : "all";
1751 cgi_set_parameter("y", zType);
@@ -2200,10 +2201,17 @@
2200 "CREATE TEMP TABLE selected_nodes(rid INTEGER PRIMARY KEY);"
2201 "INSERT OR IGNORE INTO selected_nodes"
2202 " SELECT tagxref.rid FROM tagxref NATURAL JOIN tag"
2203 " WHERE %s AND tagtype>0", zTagSql/*safe-for-%s*/
2204 );
 
 
 
 
 
 
 
2205 if( !related ){
2206 blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
2207 }else{
2208 db_multi_exec(
2209 "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
@@ -2426,10 +2434,13 @@
2426 blob_appendf(&desc, " related to tags matching %h", zMatchDesc);
2427 }else{
2428 blob_appendf(&desc, " with tags matching %h", zMatchDesc);
2429 }
2430 }
 
 
 
2431 tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
2432 }
2433 addFileGlobDescription(zChng, &desc);
2434 if( rAfter>0.0 ){
2435 if( rBefore>0.0 ){
2436
--- src/timeline.c
+++ src/timeline.c
@@ -1312,11 +1312,11 @@
1312 ){
1313 if( zChng==0 || zChng[0]==0 ) return;
1314 blob_append_sql(pSql," AND event.objid IN ("
1315 "SELECT mlink.mid FROM mlink, filename"
1316 " WHERE mlink.fnid=filename.fnid AND %s)",
1317 glob_expr("filename.name", mprintf("\"%s\"", zChng)));
1318 }
1319 static void addFileGlobDescription(
1320 const char *zChng, /* The filename GLOB list */
1321 Blob *pDescription /* Result description */
1322 ){
@@ -1742,10 +1742,11 @@
1742 || (bisectLocal && !g.perm.Setup)
1743 ){
1744 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
1745 return;
1746 }
1747 etag_check(ETAG_QUERY|ETAG_COOKIE|ETAG_DATA, 0);
1748 cookie_read_parameter("y","y");
1749 zType = P("y");
1750 if( zType==0 ){
1751 zType = g.perm.Read ? "ci" : "all";
1752 cgi_set_parameter("y", zType);
@@ -2200,10 +2201,17 @@
2201 "CREATE TEMP TABLE selected_nodes(rid INTEGER PRIMARY KEY);"
2202 "INSERT OR IGNORE INTO selected_nodes"
2203 " SELECT tagxref.rid FROM tagxref NATURAL JOIN tag"
2204 " WHERE %s AND tagtype>0", zTagSql/*safe-for-%s*/
2205 );
2206 if( zMark ){
2207 /* If the t=release option is used with m=UUID, then also
2208 ** include the UUID check-in in the display list */
2209 int ridMark = name_to_rid(zMark);
2210 db_multi_exec(
2211 "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark);
2212 }
2213 if( !related ){
2214 blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
2215 }else{
2216 db_multi_exec(
2217 "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
@@ -2426,10 +2434,13 @@
2434 blob_appendf(&desc, " related to tags matching %h", zMatchDesc);
2435 }else{
2436 blob_appendf(&desc, " with tags matching %h", zMatchDesc);
2437 }
2438 }
2439 if( zMark ){
2440 blob_appendf(&desc," plus check-in \"%h\"", zMark);
2441 }
2442 tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
2443 }
2444 addFileGlobDescription(zChng, &desc);
2445 if( rAfter>0.0 ){
2446 if( rBefore>0.0 ){
2447
--- src/unversioned.c
+++ src/unversioned.c
@@ -524,10 +524,11 @@
524524
int showDel = 0;
525525
char zSzName[100];
526526
527527
login_check_credentials();
528528
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
529
+ etag_check(ETAG_DATA,0);
529530
style_header("Unversioned Files");
530531
if( !db_table_exists("repository","unversioned") ){
531532
@ No unversioned files on this server
532533
style_footer();
533534
return;
@@ -636,10 +637,11 @@
636637
Blob json;
637638
638639
login_check_credentials();
639640
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
640641
cgi_set_content_type("text/json");
642
+ etag_check(ETAG_DATA,0);
641643
if( !db_table_exists("repository","unversioned") ){
642644
blob_init(&json, "[]", -1);
643645
cgi_set_content(&json);
644646
return;
645647
}
646648
647649
ADDED test/subdir with spaces/filename with spaces.txt
--- src/unversioned.c
+++ src/unversioned.c
@@ -524,10 +524,11 @@
524 int showDel = 0;
525 char zSzName[100];
526
527 login_check_credentials();
528 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
529 style_header("Unversioned Files");
530 if( !db_table_exists("repository","unversioned") ){
531 @ No unversioned files on this server
532 style_footer();
533 return;
@@ -636,10 +637,11 @@
636 Blob json;
637
638 login_check_credentials();
639 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
640 cgi_set_content_type("text/json");
 
641 if( !db_table_exists("repository","unversioned") ){
642 blob_init(&json, "[]", -1);
643 cgi_set_content(&json);
644 return;
645 }
646
647 DDED test/subdir with spaces/filename with spaces.txt
--- src/unversioned.c
+++ src/unversioned.c
@@ -524,10 +524,11 @@
524 int showDel = 0;
525 char zSzName[100];
526
527 login_check_credentials();
528 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
529 etag_check(ETAG_DATA,0);
530 style_header("Unversioned Files");
531 if( !db_table_exists("repository","unversioned") ){
532 @ No unversioned files on this server
533 style_footer();
534 return;
@@ -636,10 +637,11 @@
637 Blob json;
638
639 login_check_credentials();
640 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
641 cgi_set_content_type("text/json");
642 etag_check(ETAG_DATA,0);
643 if( !db_table_exists("repository","unversioned") ){
644 blob_init(&json, "[]", -1);
645 cgi_set_content(&json);
646 return;
647 }
648
649 DDED test/subdir with spaces/filename with spaces.txt
--- a/test/subdir with spaces/filename with spaces.txt
+++ b/test/subdir with spaces/filename with spaces.txt
@@ -0,0 +1,2 @@
1
+This file has a name that contains spaces. It is used to help verify
2
+that fossil can handle filenames that contain spaces.
--- a/test/subdir with spaces/filename with spaces.txt
+++ b/test/subdir with spaces/filename with spaces.txt
@@ -0,0 +1,2 @@
 
 
--- a/test/subdir with spaces/filename with spaces.txt
+++ b/test/subdir with spaces/filename with spaces.txt
@@ -0,0 +1,2 @@
1 This file has a name that contains spaces. It is used to help verify
2 that fossil can handle filenames that contain spaces.
+10 -4
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
2828
2929
SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -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_TRUSTED_SCHEMA=0
3030
3131
SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -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_TRUSTED_SCHEMA=0 -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 backlink_.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 deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.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
33
+SRC = add_.c alerts_.c allrepo_.c attach_.c backlink_.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 deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.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 terminal_.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)\backlink$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)\deltafunc$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)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$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
35
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$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)\deltafunc$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)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$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)\terminal$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 backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file finfo foci forum fshell fusefs fuzz 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 > $@
54
+ +echo add alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file finfo foci forum fshell fusefs fuzz 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 terminal 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 >> $@
@@ -830,10 +830,16 @@
830830
$(OBJDIR)\tar$O : tar_.c tar.h
831831
$(TCC) -o$@ -c tar_.c
832832
833833
tar_.c : $(SRCDIR)\tar.c
834834
+translate$E $** > $@
835
+
836
+$(OBJDIR)\terminal$O : terminal_.c terminal.h
837
+ $(TCC) -o$@ -c terminal_.c
838
+
839
+terminal_.c : $(SRCDIR)\terminal.c
840
+ +translate$E $** > $@
835841
836842
$(OBJDIR)\th_main$O : th_main_.c th_main.h
837843
$(TCC) -o$@ -c th_main_.c
838844
839845
th_main_.c : $(SRCDIR)\th_main.c
@@ -970,7 +976,7 @@
970976
971977
zip_.c : $(SRCDIR)\zip.c
972978
+translate$E $** > $@
973979
974980
headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
975
- +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.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 deltafunc_.c:deltafunc.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 extcgi_.c:extcgi.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 fuzz_.c:fuzz.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
981
+ +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.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 deltafunc_.c:deltafunc.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 extcgi_.c:extcgi.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 fuzz_.c:fuzz.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 terminal_.c:terminal.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
976982
@copy /Y nul: headers
977983
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -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_TRUSTED_SCHEMA=0
30
31 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -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_TRUSTED_SCHEMA=0 -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 backlink_.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 deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.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)\backlink$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)\deltafunc$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)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$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 backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file finfo foci forum fshell fusefs fuzz 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 >> $@
@@ -830,10 +830,16 @@
830 $(OBJDIR)\tar$O : tar_.c tar.h
831 $(TCC) -o$@ -c tar_.c
832
833 tar_.c : $(SRCDIR)\tar.c
834 +translate$E $** > $@
 
 
 
 
 
 
835
836 $(OBJDIR)\th_main$O : th_main_.c th_main.h
837 $(TCC) -o$@ -c th_main_.c
838
839 th_main_.c : $(SRCDIR)\th_main.c
@@ -970,7 +976,7 @@
970
971 zip_.c : $(SRCDIR)\zip.c
972 +translate$E $** > $@
973
974 headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
975 +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.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 deltafunc_.c:deltafunc.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 extcgi_.c:extcgi.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 fuzz_.c:fuzz.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
976 @copy /Y nul: headers
977
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
28
29 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -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_TRUSTED_SCHEMA=0
30
31 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -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_TRUSTED_SCHEMA=0 -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 backlink_.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 deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.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 terminal_.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)\backlink$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)\deltafunc$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)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$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)\terminal$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 backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file finfo foci forum fshell fusefs fuzz 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 terminal 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 >> $@
@@ -830,10 +830,16 @@
830 $(OBJDIR)\tar$O : tar_.c tar.h
831 $(TCC) -o$@ -c tar_.c
832
833 tar_.c : $(SRCDIR)\tar.c
834 +translate$E $** > $@
835
836 $(OBJDIR)\terminal$O : terminal_.c terminal.h
837 $(TCC) -o$@ -c terminal_.c
838
839 terminal_.c : $(SRCDIR)\terminal.c
840 +translate$E $** > $@
841
842 $(OBJDIR)\th_main$O : th_main_.c th_main.h
843 $(TCC) -o$@ -c th_main_.c
844
845 th_main_.c : $(SRCDIR)\th_main.c
@@ -970,7 +976,7 @@
976
977 zip_.c : $(SRCDIR)\zip.c
978 +translate$E $** > $@
979
980 headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
981 +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.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 deltafunc_.c:deltafunc.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 extcgi_.c:extcgi.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 fuzz_.c:fuzz.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 terminal_.c:terminal.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
982 @copy /Y nul: headers
983
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -553,10 +553,11 @@
553553
$(SRCDIR)/statrep.c \
554554
$(SRCDIR)/style.c \
555555
$(SRCDIR)/sync.c \
556556
$(SRCDIR)/tag.c \
557557
$(SRCDIR)/tar.c \
558
+ $(SRCDIR)/terminal.c \
558559
$(SRCDIR)/th_main.c \
559560
$(SRCDIR)/timeline.c \
560561
$(SRCDIR)/tkt.c \
561562
$(SRCDIR)/tktsetup.c \
562563
$(SRCDIR)/undo.c \
@@ -786,10 +787,11 @@
786787
$(OBJDIR)/statrep_.c \
787788
$(OBJDIR)/style_.c \
788789
$(OBJDIR)/sync_.c \
789790
$(OBJDIR)/tag_.c \
790791
$(OBJDIR)/tar_.c \
792
+ $(OBJDIR)/terminal_.c \
791793
$(OBJDIR)/th_main_.c \
792794
$(OBJDIR)/timeline_.c \
793795
$(OBJDIR)/tkt_.c \
794796
$(OBJDIR)/tktsetup_.c \
795797
$(OBJDIR)/undo_.c \
@@ -928,10 +930,11 @@
928930
$(OBJDIR)/statrep.o \
929931
$(OBJDIR)/style.o \
930932
$(OBJDIR)/sync.o \
931933
$(OBJDIR)/tag.o \
932934
$(OBJDIR)/tar.o \
935
+ $(OBJDIR)/terminal.o \
933936
$(OBJDIR)/th_main.o \
934937
$(OBJDIR)/timeline.o \
935938
$(OBJDIR)/tkt.o \
936939
$(OBJDIR)/tktsetup.o \
937940
$(OBJDIR)/undo.o \
@@ -1290,10 +1293,11 @@
12901293
$(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
12911294
$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
12921295
$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
12931296
$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
12941297
$(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
1298
+ $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \
12951299
$(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
12961300
$(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
12971301
$(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
12981302
$(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
12991303
$(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -2257,10 +2261,18 @@
22572261
22582262
$(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
22592263
$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
22602264
22612265
$(OBJDIR)/tar.h: $(OBJDIR)/headers
2266
+
2267
+$(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(TRANSLATE)
2268
+ $(TRANSLATE) $(SRCDIR)/terminal.c >$@
2269
+
2270
+$(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h
2271
+ $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c
2272
+
2273
+$(OBJDIR)/terminal.h: $(OBJDIR)/headers
22622274
22632275
$(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE)
22642276
$(TRANSLATE) $(SRCDIR)/th_main.c >$@
22652277
22662278
$(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
22672279
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -553,10 +553,11 @@
553 $(SRCDIR)/statrep.c \
554 $(SRCDIR)/style.c \
555 $(SRCDIR)/sync.c \
556 $(SRCDIR)/tag.c \
557 $(SRCDIR)/tar.c \
 
558 $(SRCDIR)/th_main.c \
559 $(SRCDIR)/timeline.c \
560 $(SRCDIR)/tkt.c \
561 $(SRCDIR)/tktsetup.c \
562 $(SRCDIR)/undo.c \
@@ -786,10 +787,11 @@
786 $(OBJDIR)/statrep_.c \
787 $(OBJDIR)/style_.c \
788 $(OBJDIR)/sync_.c \
789 $(OBJDIR)/tag_.c \
790 $(OBJDIR)/tar_.c \
 
791 $(OBJDIR)/th_main_.c \
792 $(OBJDIR)/timeline_.c \
793 $(OBJDIR)/tkt_.c \
794 $(OBJDIR)/tktsetup_.c \
795 $(OBJDIR)/undo_.c \
@@ -928,10 +930,11 @@
928 $(OBJDIR)/statrep.o \
929 $(OBJDIR)/style.o \
930 $(OBJDIR)/sync.o \
931 $(OBJDIR)/tag.o \
932 $(OBJDIR)/tar.o \
 
933 $(OBJDIR)/th_main.o \
934 $(OBJDIR)/timeline.o \
935 $(OBJDIR)/tkt.o \
936 $(OBJDIR)/tktsetup.o \
937 $(OBJDIR)/undo.o \
@@ -1290,10 +1293,11 @@
1290 $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
1291 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
1292 $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
1293 $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
1294 $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
 
1295 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
1296 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
1297 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
1298 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
1299 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -2257,10 +2261,18 @@
2257
2258 $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
2259 $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
2260
2261 $(OBJDIR)/tar.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
2262
2263 $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE)
2264 $(TRANSLATE) $(SRCDIR)/th_main.c >$@
2265
2266 $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
2267
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -553,10 +553,11 @@
553 $(SRCDIR)/statrep.c \
554 $(SRCDIR)/style.c \
555 $(SRCDIR)/sync.c \
556 $(SRCDIR)/tag.c \
557 $(SRCDIR)/tar.c \
558 $(SRCDIR)/terminal.c \
559 $(SRCDIR)/th_main.c \
560 $(SRCDIR)/timeline.c \
561 $(SRCDIR)/tkt.c \
562 $(SRCDIR)/tktsetup.c \
563 $(SRCDIR)/undo.c \
@@ -786,10 +787,11 @@
787 $(OBJDIR)/statrep_.c \
788 $(OBJDIR)/style_.c \
789 $(OBJDIR)/sync_.c \
790 $(OBJDIR)/tag_.c \
791 $(OBJDIR)/tar_.c \
792 $(OBJDIR)/terminal_.c \
793 $(OBJDIR)/th_main_.c \
794 $(OBJDIR)/timeline_.c \
795 $(OBJDIR)/tkt_.c \
796 $(OBJDIR)/tktsetup_.c \
797 $(OBJDIR)/undo_.c \
@@ -928,10 +930,11 @@
930 $(OBJDIR)/statrep.o \
931 $(OBJDIR)/style.o \
932 $(OBJDIR)/sync.o \
933 $(OBJDIR)/tag.o \
934 $(OBJDIR)/tar.o \
935 $(OBJDIR)/terminal.o \
936 $(OBJDIR)/th_main.o \
937 $(OBJDIR)/timeline.o \
938 $(OBJDIR)/tkt.o \
939 $(OBJDIR)/tktsetup.o \
940 $(OBJDIR)/undo.o \
@@ -1290,10 +1293,11 @@
1293 $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
1294 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
1295 $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
1296 $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
1297 $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
1298 $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \
1299 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
1300 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
1301 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
1302 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
1303 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -2257,10 +2261,18 @@
2261
2262 $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
2263 $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
2264
2265 $(OBJDIR)/tar.h: $(OBJDIR)/headers
2266
2267 $(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(TRANSLATE)
2268 $(TRANSLATE) $(SRCDIR)/terminal.c >$@
2269
2270 $(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h
2271 $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c
2272
2273 $(OBJDIR)/terminal.h: $(OBJDIR)/headers
2274
2275 $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE)
2276 $(TRANSLATE) $(SRCDIR)/th_main.c >$@
2277
2278 $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
2279
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -553,10 +553,11 @@
553553
$(SRCDIR)/statrep.c \
554554
$(SRCDIR)/style.c \
555555
$(SRCDIR)/sync.c \
556556
$(SRCDIR)/tag.c \
557557
$(SRCDIR)/tar.c \
558
+ $(SRCDIR)/terminal.c \
558559
$(SRCDIR)/th_main.c \
559560
$(SRCDIR)/timeline.c \
560561
$(SRCDIR)/tkt.c \
561562
$(SRCDIR)/tktsetup.c \
562563
$(SRCDIR)/undo.c \
@@ -786,10 +787,11 @@
786787
$(OBJDIR)/statrep_.c \
787788
$(OBJDIR)/style_.c \
788789
$(OBJDIR)/sync_.c \
789790
$(OBJDIR)/tag_.c \
790791
$(OBJDIR)/tar_.c \
792
+ $(OBJDIR)/terminal_.c \
791793
$(OBJDIR)/th_main_.c \
792794
$(OBJDIR)/timeline_.c \
793795
$(OBJDIR)/tkt_.c \
794796
$(OBJDIR)/tktsetup_.c \
795797
$(OBJDIR)/undo_.c \
@@ -928,10 +930,11 @@
928930
$(OBJDIR)/statrep.o \
929931
$(OBJDIR)/style.o \
930932
$(OBJDIR)/sync.o \
931933
$(OBJDIR)/tag.o \
932934
$(OBJDIR)/tar.o \
935
+ $(OBJDIR)/terminal.o \
933936
$(OBJDIR)/th_main.o \
934937
$(OBJDIR)/timeline.o \
935938
$(OBJDIR)/tkt.o \
936939
$(OBJDIR)/tktsetup.o \
937940
$(OBJDIR)/undo.o \
@@ -1290,10 +1293,11 @@
12901293
$(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
12911294
$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
12921295
$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
12931296
$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
12941297
$(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
1298
+ $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \
12951299
$(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
12961300
$(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
12971301
$(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
12981302
$(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
12991303
$(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -2257,10 +2261,18 @@
22572261
22582262
$(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
22592263
$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
22602264
22612265
$(OBJDIR)/tar.h: $(OBJDIR)/headers
2266
+
2267
+$(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(TRANSLATE)
2268
+ $(TRANSLATE) $(SRCDIR)/terminal.c >$@
2269
+
2270
+$(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h
2271
+ $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c
2272
+
2273
+$(OBJDIR)/terminal.h: $(OBJDIR)/headers
22622274
22632275
$(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE)
22642276
$(TRANSLATE) $(SRCDIR)/th_main.c >$@
22652277
22662278
$(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
22672279
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -553,10 +553,11 @@
553 $(SRCDIR)/statrep.c \
554 $(SRCDIR)/style.c \
555 $(SRCDIR)/sync.c \
556 $(SRCDIR)/tag.c \
557 $(SRCDIR)/tar.c \
 
558 $(SRCDIR)/th_main.c \
559 $(SRCDIR)/timeline.c \
560 $(SRCDIR)/tkt.c \
561 $(SRCDIR)/tktsetup.c \
562 $(SRCDIR)/undo.c \
@@ -786,10 +787,11 @@
786 $(OBJDIR)/statrep_.c \
787 $(OBJDIR)/style_.c \
788 $(OBJDIR)/sync_.c \
789 $(OBJDIR)/tag_.c \
790 $(OBJDIR)/tar_.c \
 
791 $(OBJDIR)/th_main_.c \
792 $(OBJDIR)/timeline_.c \
793 $(OBJDIR)/tkt_.c \
794 $(OBJDIR)/tktsetup_.c \
795 $(OBJDIR)/undo_.c \
@@ -928,10 +930,11 @@
928 $(OBJDIR)/statrep.o \
929 $(OBJDIR)/style.o \
930 $(OBJDIR)/sync.o \
931 $(OBJDIR)/tag.o \
932 $(OBJDIR)/tar.o \
 
933 $(OBJDIR)/th_main.o \
934 $(OBJDIR)/timeline.o \
935 $(OBJDIR)/tkt.o \
936 $(OBJDIR)/tktsetup.o \
937 $(OBJDIR)/undo.o \
@@ -1290,10 +1293,11 @@
1290 $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
1291 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
1292 $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
1293 $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
1294 $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
 
1295 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
1296 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
1297 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
1298 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
1299 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -2257,10 +2261,18 @@
2257
2258 $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
2259 $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
2260
2261 $(OBJDIR)/tar.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
2262
2263 $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE)
2264 $(TRANSLATE) $(SRCDIR)/th_main.c >$@
2265
2266 $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
2267
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -553,10 +553,11 @@
553 $(SRCDIR)/statrep.c \
554 $(SRCDIR)/style.c \
555 $(SRCDIR)/sync.c \
556 $(SRCDIR)/tag.c \
557 $(SRCDIR)/tar.c \
558 $(SRCDIR)/terminal.c \
559 $(SRCDIR)/th_main.c \
560 $(SRCDIR)/timeline.c \
561 $(SRCDIR)/tkt.c \
562 $(SRCDIR)/tktsetup.c \
563 $(SRCDIR)/undo.c \
@@ -786,10 +787,11 @@
787 $(OBJDIR)/statrep_.c \
788 $(OBJDIR)/style_.c \
789 $(OBJDIR)/sync_.c \
790 $(OBJDIR)/tag_.c \
791 $(OBJDIR)/tar_.c \
792 $(OBJDIR)/terminal_.c \
793 $(OBJDIR)/th_main_.c \
794 $(OBJDIR)/timeline_.c \
795 $(OBJDIR)/tkt_.c \
796 $(OBJDIR)/tktsetup_.c \
797 $(OBJDIR)/undo_.c \
@@ -928,10 +930,11 @@
930 $(OBJDIR)/statrep.o \
931 $(OBJDIR)/style.o \
932 $(OBJDIR)/sync.o \
933 $(OBJDIR)/tag.o \
934 $(OBJDIR)/tar.o \
935 $(OBJDIR)/terminal.o \
936 $(OBJDIR)/th_main.o \
937 $(OBJDIR)/timeline.o \
938 $(OBJDIR)/tkt.o \
939 $(OBJDIR)/tktsetup.o \
940 $(OBJDIR)/undo.o \
@@ -1290,10 +1293,11 @@
1293 $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \
1294 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
1295 $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
1296 $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
1297 $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \
1298 $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \
1299 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
1300 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
1301 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
1302 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
1303 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
@@ -2257,10 +2261,18 @@
2261
2262 $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h
2263 $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c
2264
2265 $(OBJDIR)/tar.h: $(OBJDIR)/headers
2266
2267 $(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(TRANSLATE)
2268 $(TRANSLATE) $(SRCDIR)/terminal.c >$@
2269
2270 $(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h
2271 $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c
2272
2273 $(OBJDIR)/terminal.h: $(OBJDIR)/headers
2274
2275 $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE)
2276 $(TRANSLATE) $(SRCDIR)/th_main.c >$@
2277
2278 $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h
2279
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -461,10 +461,11 @@
461461
statrep_.c \
462462
style_.c \
463463
sync_.c \
464464
tag_.c \
465465
tar_.c \
466
+ terminal_.c \
466467
th_main_.c \
467468
timeline_.c \
468469
tkt_.c \
469470
tktsetup_.c \
470471
undo_.c \
@@ -695,10 +696,11 @@
695696
$(OX)\statrep$O \
696697
$(OX)\style$O \
697698
$(OX)\sync$O \
698699
$(OX)\tag$O \
699700
$(OX)\tar$O \
701
+ $(OX)\terminal$O \
700702
$(OX)\th$O \
701703
$(OX)\th_lang$O \
702704
$(OX)\th_main$O \
703705
$(OX)\th_tcl$O \
704706
$(OX)\timeline$O \
@@ -899,10 +901,11 @@
899901
echo $(OX)\statrep.obj >> $@
900902
echo $(OX)\style.obj >> $@
901903
echo $(OX)\sync.obj >> $@
902904
echo $(OX)\tag.obj >> $@
903905
echo $(OX)\tar.obj >> $@
906
+ echo $(OX)\terminal.obj >> $@
904907
echo $(OX)\th.obj >> $@
905908
echo $(OX)\th_lang.obj >> $@
906909
echo $(OX)\th_main.obj >> $@
907910
echo $(OX)\th_tcl.obj >> $@
908911
echo $(OX)\timeline.obj >> $@
@@ -1744,10 +1747,16 @@
17441747
$(OX)\tar$O : tar_.c tar.h
17451748
$(TCC) /Fo$@ -c tar_.c
17461749
17471750
tar_.c : $(SRCDIR)\tar.c
17481751
translate$E $** > $@
1752
+
1753
+$(OX)\terminal$O : terminal_.c terminal.h
1754
+ $(TCC) /Fo$@ -c terminal_.c
1755
+
1756
+terminal_.c : $(SRCDIR)\terminal.c
1757
+ translate$E $** > $@
17491758
17501759
$(OX)\th_main$O : th_main_.c th_main.h
17511760
$(TCC) /Fo$@ -c th_main_.c
17521761
17531762
th_main_.c : $(SRCDIR)\th_main.c
@@ -2004,10 +2013,11 @@
20042013
statrep_.c:statrep.h \
20052014
style_.c:style.h \
20062015
sync_.c:sync.h \
20072016
tag_.c:tag.h \
20082017
tar_.c:tar.h \
2018
+ terminal_.c:terminal.h \
20092019
th_main_.c:th_main.h \
20102020
timeline_.c:timeline.h \
20112021
tkt_.c:tkt.h \
20122022
tktsetup_.c:tktsetup.h \
20132023
undo_.c:undo.h \
20142024
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -461,10 +461,11 @@
461 statrep_.c \
462 style_.c \
463 sync_.c \
464 tag_.c \
465 tar_.c \
 
466 th_main_.c \
467 timeline_.c \
468 tkt_.c \
469 tktsetup_.c \
470 undo_.c \
@@ -695,10 +696,11 @@
695 $(OX)\statrep$O \
696 $(OX)\style$O \
697 $(OX)\sync$O \
698 $(OX)\tag$O \
699 $(OX)\tar$O \
 
700 $(OX)\th$O \
701 $(OX)\th_lang$O \
702 $(OX)\th_main$O \
703 $(OX)\th_tcl$O \
704 $(OX)\timeline$O \
@@ -899,10 +901,11 @@
899 echo $(OX)\statrep.obj >> $@
900 echo $(OX)\style.obj >> $@
901 echo $(OX)\sync.obj >> $@
902 echo $(OX)\tag.obj >> $@
903 echo $(OX)\tar.obj >> $@
 
904 echo $(OX)\th.obj >> $@
905 echo $(OX)\th_lang.obj >> $@
906 echo $(OX)\th_main.obj >> $@
907 echo $(OX)\th_tcl.obj >> $@
908 echo $(OX)\timeline.obj >> $@
@@ -1744,10 +1747,16 @@
1744 $(OX)\tar$O : tar_.c tar.h
1745 $(TCC) /Fo$@ -c tar_.c
1746
1747 tar_.c : $(SRCDIR)\tar.c
1748 translate$E $** > $@
 
 
 
 
 
 
1749
1750 $(OX)\th_main$O : th_main_.c th_main.h
1751 $(TCC) /Fo$@ -c th_main_.c
1752
1753 th_main_.c : $(SRCDIR)\th_main.c
@@ -2004,10 +2013,11 @@
2004 statrep_.c:statrep.h \
2005 style_.c:style.h \
2006 sync_.c:sync.h \
2007 tag_.c:tag.h \
2008 tar_.c:tar.h \
 
2009 th_main_.c:th_main.h \
2010 timeline_.c:timeline.h \
2011 tkt_.c:tkt.h \
2012 tktsetup_.c:tktsetup.h \
2013 undo_.c:undo.h \
2014
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -461,10 +461,11 @@
461 statrep_.c \
462 style_.c \
463 sync_.c \
464 tag_.c \
465 tar_.c \
466 terminal_.c \
467 th_main_.c \
468 timeline_.c \
469 tkt_.c \
470 tktsetup_.c \
471 undo_.c \
@@ -695,10 +696,11 @@
696 $(OX)\statrep$O \
697 $(OX)\style$O \
698 $(OX)\sync$O \
699 $(OX)\tag$O \
700 $(OX)\tar$O \
701 $(OX)\terminal$O \
702 $(OX)\th$O \
703 $(OX)\th_lang$O \
704 $(OX)\th_main$O \
705 $(OX)\th_tcl$O \
706 $(OX)\timeline$O \
@@ -899,10 +901,11 @@
901 echo $(OX)\statrep.obj >> $@
902 echo $(OX)\style.obj >> $@
903 echo $(OX)\sync.obj >> $@
904 echo $(OX)\tag.obj >> $@
905 echo $(OX)\tar.obj >> $@
906 echo $(OX)\terminal.obj >> $@
907 echo $(OX)\th.obj >> $@
908 echo $(OX)\th_lang.obj >> $@
909 echo $(OX)\th_main.obj >> $@
910 echo $(OX)\th_tcl.obj >> $@
911 echo $(OX)\timeline.obj >> $@
@@ -1744,10 +1747,16 @@
1747 $(OX)\tar$O : tar_.c tar.h
1748 $(TCC) /Fo$@ -c tar_.c
1749
1750 tar_.c : $(SRCDIR)\tar.c
1751 translate$E $** > $@
1752
1753 $(OX)\terminal$O : terminal_.c terminal.h
1754 $(TCC) /Fo$@ -c terminal_.c
1755
1756 terminal_.c : $(SRCDIR)\terminal.c
1757 translate$E $** > $@
1758
1759 $(OX)\th_main$O : th_main_.c th_main.h
1760 $(TCC) /Fo$@ -c th_main_.c
1761
1762 th_main_.c : $(SRCDIR)\th_main.c
@@ -2004,10 +2013,11 @@
2013 statrep_.c:statrep.h \
2014 style_.c:style.h \
2015 sync_.c:sync.h \
2016 tag_.c:tag.h \
2017 tar_.c:tar.h \
2018 terminal_.c:terminal.h \
2019 th_main_.c:th_main.h \
2020 timeline_.c:timeline.h \
2021 tkt_.c:tkt.h \
2022 tktsetup_.c:tktsetup.h \
2023 undo_.c:undo.h \
2024
--- www/changes.wiki
+++ www/changes.wiki
@@ -55,10 +55,12 @@
5555
* Security: Fossil now puts the Content-Security-Policy in the
5656
HTTP reply header, in addition to also leaving it in the
5757
HTML &lt;head&gt; section, so that it is always available, even
5858
if a custom skin overrides the HTML &lt;head&gt; and omits
5959
the CSP in the process.
60
+ * Output of the [/help?cmd=diff|fossil diff -y] command automatically
61
+ adjusts according to the terminal width.
6062
* The Content-Security-Policy is now set using the
6163
[/help?cmd=default-csp|default-csp setting].
6264
* Merge conflicts caused via the [/help?cmd=merge|merge] and
6365
[/help?cmd=update|update] commands no longer leave temporary
6466
files behind unless the new <tt>--keep-merge-files</tt> flag
6567
--- www/changes.wiki
+++ www/changes.wiki
@@ -55,10 +55,12 @@
55 * Security: Fossil now puts the Content-Security-Policy in the
56 HTTP reply header, in addition to also leaving it in the
57 HTML &lt;head&gt; section, so that it is always available, even
58 if a custom skin overrides the HTML &lt;head&gt; and omits
59 the CSP in the process.
 
 
60 * The Content-Security-Policy is now set using the
61 [/help?cmd=default-csp|default-csp setting].
62 * Merge conflicts caused via the [/help?cmd=merge|merge] and
63 [/help?cmd=update|update] commands no longer leave temporary
64 files behind unless the new <tt>--keep-merge-files</tt> flag
65
--- www/changes.wiki
+++ www/changes.wiki
@@ -55,10 +55,12 @@
55 * Security: Fossil now puts the Content-Security-Policy in the
56 HTTP reply header, in addition to also leaving it in the
57 HTML &lt;head&gt; section, so that it is always available, even
58 if a custom skin overrides the HTML &lt;head&gt; and omits
59 the CSP in the process.
60 * Output of the [/help?cmd=diff|fossil diff -y] command automatically
61 adjusts according to the terminal width.
62 * The Content-Security-Policy is now set using the
63 [/help?cmd=default-csp|default-csp setting].
64 * Merge conflicts caused via the [/help?cmd=merge|merge] and
65 [/help?cmd=update|update] commands no longer leave temporary
66 files behind unless the new <tt>--keep-merge-files</tt> flag
67

Keyboard Shortcuts

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