Fossil SCM

merge trunk

baruch 2014-10-21 09:27 svn-import merge
Commit 154abe4d478d6ed78147b031da2fd07c98c98728
82 files changed +1 +19 -8 +8 -8 +36 -1 +2 -2 +2 -2 +9 -9 +4 -3 +20 -17 +20 -17 +1 -1 +14 +2 -2 +36 -28 +2 -2 +34 -35 +34 -35 +10 -10 +10 -10 +11 -11 +69 -71 +27 -27 +2 -4 +2 -2 +12 -12 +2 -2 +6 -8 +7 -7 +2 -2 +6 -7 +1 -1 +1 -1 +2 -2 +9 -11 +9 -9 +5 -6 +3 -2 +1 -1 +13 -13 +9 -7 +8 -1 +65 -11 +5 -6 +4 -4 +3 -3 +4 -4 +10 -10 +18 -14 +9 -8 +5 -7 +10 -10 +2 -2 +109 -35 +14 -2 +9 -9 +2 -2 +4 +1210 -975 +16 -18 +7 -7 +47 -24 +9 -1 +7 -6 +139 -108 +21 -23 +7 -7 +9 -8 +5 -3 +3 -3 +9 +9 +2 -2 +5 -14 +4 -4 +33 -27 +17 -12 +8 -4 +9 -3 +9 -3 +40 -3 +41 -1 +1 -1
+1
--- auto.def
+++ auto.def
@@ -278,10 +278,11 @@
278278
}
279279
}
280280
cc-check-function-in-lib iconv iconv
281281
cc-check-functions utime
282282
cc-check-functions usleep
283
+cc-check-functions strchrnul
283284
284285
# Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
285286
if {![cc-check-functions getloadavg]} {
286287
define FOSSIL_OMIT_LOAD_AVERAGE 1
287288
msg-result "Load average support unavailable"
288289
--- auto.def
+++ auto.def
@@ -278,10 +278,11 @@
278 }
279 }
280 cc-check-function-in-lib iconv iconv
281 cc-check-functions utime
282 cc-check-functions usleep
 
283
284 # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
285 if {![cc-check-functions getloadavg]} {
286 define FOSSIL_OMIT_LOAD_AVERAGE 1
287 msg-result "Load average support unavailable"
288
--- auto.def
+++ auto.def
@@ -278,10 +278,11 @@
278 }
279 }
280 cc-check-function-in-lib iconv iconv
281 cc-check-functions utime
282 cc-check-functions usleep
283 cc-check-functions strchrnul
284
285 # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
286 if {![cc-check-functions getloadavg]} {
287 define FOSSIL_OMIT_LOAD_AVERAGE 1
288 msg-result "Load average support unavailable"
289
+19 -8
--- src/allrepo.c
+++ src/allrepo.c
@@ -98,10 +98,12 @@
9898
** carefully review the local checkouts to be operated upon
9999
** and the --whatif option to carefully review the files to
100100
** be deleted beforehand is highly recommended. The command
101101
** line options supported by the clean command itself, if any
102102
** are present, are passed along verbatim.
103
+**
104
+** dbstat Run the "dbstat" command on all repositories.
103105
**
104106
** extras Shows "extra" files from all local checkouts. The command
105107
** line options supported by the extra command itself, if any
106108
** are present, are passed along verbatim.
107109
**
@@ -129,11 +131,11 @@
129131
** sync Run a "sync" on all repositories. Only the --verbose
130132
** option is supported.
131133
**
132134
** setting Run the "setting", "set", or "unset" commands on all
133135
** set repositories. These command are particularly useful in
134
-** unset conjunection with the "max-loadavg" setting which cannot
136
+** unset conjunction with the "max-loadavg" setting which cannot
135137
** otherwise be set globally.
136138
**
137139
** Repositories are automatically added to the set of known repositories
138140
** when one of the following commands are run against the repository:
139141
** clone, info, pull, push, or sync. Even previously ignored repositories
@@ -190,10 +192,16 @@
190192
collect_argument_value(&extra, "keep");
191193
collect_argument(&extra, "temp",0);
192194
collect_argument(&extra, "verbose","v");
193195
collect_argument(&extra, "whatif",0);
194196
useCheckouts = 1;
197
+ }else if( strncmp(zCmd, "dbstat", n)==0 ){
198
+ zCmd = "dbstat --omit-version-info -R";
199
+ showLabel = 1;
200
+ quiet = 1;
201
+ collect_argument(&extra, "brief", "b");
202
+ collect_argument(&extra, "db-check", 0);
195203
}else if( strncmp(zCmd, "extras", n)==0 ){
196204
if( showFile ){
197205
zCmd = "extras --chdir";
198206
}else{
199207
zCmd = "extras --header --chdir";
@@ -249,19 +257,22 @@
249257
int j;
250258
useCheckouts = find_option("ckout","c",0)!=0;
251259
verify_all_options();
252260
db_begin_transaction();
253261
for(j=3; j<g.argc; j++){
254
- char *zSql = mprintf("DELETE FROM global_config"
255
- " WHERE name GLOB '%s:%q'",
256
- useCheckouts?"ckout":"repo", g.argv[j]);
262
+ Blob sql;
263
+ blob_zero(&sql);
264
+ blob_append_sql(&sql,
265
+ "DELETE FROM global_config WHERE name GLOB '%s:%q'",
266
+ useCheckouts?"ckout":"repo", g.argv[j]
267
+ );
257268
if( dryRunFlag ){
258
- fossil_print("%s\n", zSql);
269
+ fossil_print("%s\n", blob_sql_text(&sql));
259270
}else{
260
- db_multi_exec("%s", zSql);
271
+ db_multi_exec("%s", blob_sql_text(&sql));
261272
}
262
- fossil_free(zSql);
273
+ blob_reset(&sql);
263274
}
264275
db_end_transaction(0);
265276
return;
266277
}else if( strncmp(zCmd, "info", n)==0 ){
267278
zCmd = "info";
@@ -338,9 +349,9 @@
338349
if( nToDel>0 ){
339350
const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
340351
if( dryRunFlag ){
341352
fossil_print("%s\n", zSql);
342353
}else{
343
- db_multi_exec(zSql);
354
+ db_multi_exec("%s", zSql /*safe-for-%s*/ );
344355
}
345356
}
346357
}
347358
--- src/allrepo.c
+++ src/allrepo.c
@@ -98,10 +98,12 @@
98 ** carefully review the local checkouts to be operated upon
99 ** and the --whatif option to carefully review the files to
100 ** be deleted beforehand is highly recommended. The command
101 ** line options supported by the clean command itself, if any
102 ** are present, are passed along verbatim.
 
 
103 **
104 ** extras Shows "extra" files from all local checkouts. The command
105 ** line options supported by the extra command itself, if any
106 ** are present, are passed along verbatim.
107 **
@@ -129,11 +131,11 @@
129 ** sync Run a "sync" on all repositories. Only the --verbose
130 ** option is supported.
131 **
132 ** setting Run the "setting", "set", or "unset" commands on all
133 ** set repositories. These command are particularly useful in
134 ** unset conjunection with the "max-loadavg" setting which cannot
135 ** otherwise be set globally.
136 **
137 ** Repositories are automatically added to the set of known repositories
138 ** when one of the following commands are run against the repository:
139 ** clone, info, pull, push, or sync. Even previously ignored repositories
@@ -190,10 +192,16 @@
190 collect_argument_value(&extra, "keep");
191 collect_argument(&extra, "temp",0);
192 collect_argument(&extra, "verbose","v");
193 collect_argument(&extra, "whatif",0);
194 useCheckouts = 1;
 
 
 
 
 
 
195 }else if( strncmp(zCmd, "extras", n)==0 ){
196 if( showFile ){
197 zCmd = "extras --chdir";
198 }else{
199 zCmd = "extras --header --chdir";
@@ -249,19 +257,22 @@
249 int j;
250 useCheckouts = find_option("ckout","c",0)!=0;
251 verify_all_options();
252 db_begin_transaction();
253 for(j=3; j<g.argc; j++){
254 char *zSql = mprintf("DELETE FROM global_config"
255 " WHERE name GLOB '%s:%q'",
256 useCheckouts?"ckout":"repo", g.argv[j]);
 
 
 
257 if( dryRunFlag ){
258 fossil_print("%s\n", zSql);
259 }else{
260 db_multi_exec("%s", zSql);
261 }
262 fossil_free(zSql);
263 }
264 db_end_transaction(0);
265 return;
266 }else if( strncmp(zCmd, "info", n)==0 ){
267 zCmd = "info";
@@ -338,9 +349,9 @@
338 if( nToDel>0 ){
339 const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
340 if( dryRunFlag ){
341 fossil_print("%s\n", zSql);
342 }else{
343 db_multi_exec(zSql);
344 }
345 }
346 }
347
--- src/allrepo.c
+++ src/allrepo.c
@@ -98,10 +98,12 @@
98 ** carefully review the local checkouts to be operated upon
99 ** and the --whatif option to carefully review the files to
100 ** be deleted beforehand is highly recommended. The command
101 ** line options supported by the clean command itself, if any
102 ** are present, are passed along verbatim.
103 **
104 ** dbstat Run the "dbstat" command on all repositories.
105 **
106 ** extras Shows "extra" files from all local checkouts. The command
107 ** line options supported by the extra command itself, if any
108 ** are present, are passed along verbatim.
109 **
@@ -129,11 +131,11 @@
131 ** sync Run a "sync" on all repositories. Only the --verbose
132 ** option is supported.
133 **
134 ** setting Run the "setting", "set", or "unset" commands on all
135 ** set repositories. These command are particularly useful in
136 ** unset conjunction with the "max-loadavg" setting which cannot
137 ** otherwise be set globally.
138 **
139 ** Repositories are automatically added to the set of known repositories
140 ** when one of the following commands are run against the repository:
141 ** clone, info, pull, push, or sync. Even previously ignored repositories
@@ -190,10 +192,16 @@
192 collect_argument_value(&extra, "keep");
193 collect_argument(&extra, "temp",0);
194 collect_argument(&extra, "verbose","v");
195 collect_argument(&extra, "whatif",0);
196 useCheckouts = 1;
197 }else if( strncmp(zCmd, "dbstat", n)==0 ){
198 zCmd = "dbstat --omit-version-info -R";
199 showLabel = 1;
200 quiet = 1;
201 collect_argument(&extra, "brief", "b");
202 collect_argument(&extra, "db-check", 0);
203 }else if( strncmp(zCmd, "extras", n)==0 ){
204 if( showFile ){
205 zCmd = "extras --chdir";
206 }else{
207 zCmd = "extras --header --chdir";
@@ -249,19 +257,22 @@
257 int j;
258 useCheckouts = find_option("ckout","c",0)!=0;
259 verify_all_options();
260 db_begin_transaction();
261 for(j=3; j<g.argc; j++){
262 Blob sql;
263 blob_zero(&sql);
264 blob_append_sql(&sql,
265 "DELETE FROM global_config WHERE name GLOB '%s:%q'",
266 useCheckouts?"ckout":"repo", g.argv[j]
267 );
268 if( dryRunFlag ){
269 fossil_print("%s\n", blob_sql_text(&sql));
270 }else{
271 db_multi_exec("%s", blob_sql_text(&sql));
272 }
273 blob_reset(&sql);
274 }
275 db_end_transaction(0);
276 return;
277 }else if( strncmp(zCmd, "info", n)==0 ){
278 zCmd = "info";
@@ -338,9 +349,9 @@
349 if( nToDel>0 ){
350 const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
351 if( dryRunFlag ){
352 fossil_print("%s\n", zSql);
353 }else{
354 db_multi_exec("%s", zSql /*safe-for-%s*/ );
355 }
356 }
357 }
358
+8 -8
--- src/attach.c
+++ src/attach.c
@@ -40,31 +40,31 @@
4040
Stmt q;
4141
4242
if( zPage && zTkt ) zTkt = 0;
4343
login_check_credentials();
4444
blob_zero(&sql);
45
- blob_appendf(&sql,
45
+ blob_append_sql(&sql,
4646
"SELECT datetime(mtime%s), src, target, filename,"
4747
" comment, user,"
4848
" (SELECT uuid FROM blob WHERE rid=attachid), attachid"
4949
" FROM attachment",
5050
timeline_utc()
5151
);
5252
if( zPage ){
5353
if( g.perm.RdWiki==0 ) login_needed();
5454
style_header("Attachments To %h", zPage);
55
- blob_appendf(&sql, " WHERE target=%Q", zPage);
55
+ blob_append_sql(&sql, " WHERE target=%Q", zPage);
5656
}else if( zTkt ){
5757
if( g.perm.RdTkt==0 ) login_needed();
5858
style_header("Attachments To Ticket %S", zTkt);
59
- blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt);
59
+ blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt);
6060
}else{
6161
if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
6262
style_header("All Attachments");
6363
}
64
- blob_appendf(&sql, " ORDER BY mtime DESC");
65
- db_prepare(&q, "%s", blob_str(&sql));
64
+ blob_append_sql(&sql, " ORDER BY mtime DESC");
65
+ db_prepare(&q, "%s", blob_sql_text(&sql));
6666
@ <ol>
6767
while( db_step(&q)==SQLITE_ROW ){
6868
const char *zDate = db_column_text(&q, 0);
6969
const char *zSrc = db_column_text(&q, 1);
7070
const char *zTarget = db_column_text(&q, 2);
@@ -377,11 +377,11 @@
377377
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
378378
#if 0
379379
/* Shunning here needs to get both the attachment control artifact and
380380
** the object that is attached. */
381381
if( g.perm.Admin ){
382
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
382
+ if( db_exists("SELECT 1 FROM shun WHERE uuid='%q'", zUuid) ){
383383
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
384384
g.zTop, zUuid);
385385
}else{
386386
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
387387
g.zTop, zUuid);
@@ -390,17 +390,17 @@
390390
#endif
391391
pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
392392
if( pAttach==0 ) fossil_redirect_home();
393393
zTarget = pAttach->zAttachTarget;
394394
zSrc = pAttach->zAttachSrc;
395
- ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%s'", zSrc);
395
+ ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%q'", zSrc);
396396
zName = pAttach->zAttachName;
397397
zDesc = pAttach->zComment;
398398
zMime = mimetype_from_name(zName);
399399
fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
400400
if( validate16(zTarget, strlen(zTarget))
401
- && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zTarget)
401
+ && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget)
402402
){
403403
zTktUuid = zTarget;
404404
if( !g.perm.RdTkt ){ login_needed(); return; }
405405
if( g.perm.WrTkt ){
406406
style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
407407
--- src/attach.c
+++ src/attach.c
@@ -40,31 +40,31 @@
40 Stmt q;
41
42 if( zPage && zTkt ) zTkt = 0;
43 login_check_credentials();
44 blob_zero(&sql);
45 blob_appendf(&sql,
46 "SELECT datetime(mtime%s), src, target, filename,"
47 " comment, user,"
48 " (SELECT uuid FROM blob WHERE rid=attachid), attachid"
49 " FROM attachment",
50 timeline_utc()
51 );
52 if( zPage ){
53 if( g.perm.RdWiki==0 ) login_needed();
54 style_header("Attachments To %h", zPage);
55 blob_appendf(&sql, " WHERE target=%Q", zPage);
56 }else if( zTkt ){
57 if( g.perm.RdTkt==0 ) login_needed();
58 style_header("Attachments To Ticket %S", zTkt);
59 blob_appendf(&sql, " WHERE target GLOB '%q*'", zTkt);
60 }else{
61 if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
62 style_header("All Attachments");
63 }
64 blob_appendf(&sql, " ORDER BY mtime DESC");
65 db_prepare(&q, "%s", blob_str(&sql));
66 @ <ol>
67 while( db_step(&q)==SQLITE_ROW ){
68 const char *zDate = db_column_text(&q, 0);
69 const char *zSrc = db_column_text(&q, 1);
70 const char *zTarget = db_column_text(&q, 2);
@@ -377,11 +377,11 @@
377 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
378 #if 0
379 /* Shunning here needs to get both the attachment control artifact and
380 ** the object that is attached. */
381 if( g.perm.Admin ){
382 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
383 style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
384 g.zTop, zUuid);
385 }else{
386 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
387 g.zTop, zUuid);
@@ -390,17 +390,17 @@
390 #endif
391 pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
392 if( pAttach==0 ) fossil_redirect_home();
393 zTarget = pAttach->zAttachTarget;
394 zSrc = pAttach->zAttachSrc;
395 ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%s'", zSrc);
396 zName = pAttach->zAttachName;
397 zDesc = pAttach->zComment;
398 zMime = mimetype_from_name(zName);
399 fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
400 if( validate16(zTarget, strlen(zTarget))
401 && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zTarget)
402 ){
403 zTktUuid = zTarget;
404 if( !g.perm.RdTkt ){ login_needed(); return; }
405 if( g.perm.WrTkt ){
406 style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
407
--- src/attach.c
+++ src/attach.c
@@ -40,31 +40,31 @@
40 Stmt q;
41
42 if( zPage && zTkt ) zTkt = 0;
43 login_check_credentials();
44 blob_zero(&sql);
45 blob_append_sql(&sql,
46 "SELECT datetime(mtime%s), src, target, filename,"
47 " comment, user,"
48 " (SELECT uuid FROM blob WHERE rid=attachid), attachid"
49 " FROM attachment",
50 timeline_utc()
51 );
52 if( zPage ){
53 if( g.perm.RdWiki==0 ) login_needed();
54 style_header("Attachments To %h", zPage);
55 blob_append_sql(&sql, " WHERE target=%Q", zPage);
56 }else if( zTkt ){
57 if( g.perm.RdTkt==0 ) login_needed();
58 style_header("Attachments To Ticket %S", zTkt);
59 blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt);
60 }else{
61 if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed();
62 style_header("All Attachments");
63 }
64 blob_append_sql(&sql, " ORDER BY mtime DESC");
65 db_prepare(&q, "%s", blob_sql_text(&sql));
66 @ <ol>
67 while( db_step(&q)==SQLITE_ROW ){
68 const char *zDate = db_column_text(&q, 0);
69 const char *zSrc = db_column_text(&q, 1);
70 const char *zTarget = db_column_text(&q, 2);
@@ -377,11 +377,11 @@
377 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
378 #if 0
379 /* Shunning here needs to get both the attachment control artifact and
380 ** the object that is attached. */
381 if( g.perm.Admin ){
382 if( db_exists("SELECT 1 FROM shun WHERE uuid='%q'", zUuid) ){
383 style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
384 g.zTop, zUuid);
385 }else{
386 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
387 g.zTop, zUuid);
@@ -390,17 +390,17 @@
390 #endif
391 pAttach = manifest_get(rid, CFTYPE_ATTACHMENT, 0);
392 if( pAttach==0 ) fossil_redirect_home();
393 zTarget = pAttach->zAttachTarget;
394 zSrc = pAttach->zAttachSrc;
395 ridSrc = db_int(0,"SELECT rid FROM blob WHERE uuid='%q'", zSrc);
396 zName = pAttach->zAttachName;
397 zDesc = pAttach->zComment;
398 zMime = mimetype_from_name(zName);
399 fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
400 if( validate16(zTarget, strlen(zTarget))
401 && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget)
402 ){
403 zTktUuid = zTarget;
404 if( !g.perm.RdTkt ){ login_needed(); return; }
405 if( g.perm.WrTkt ){
406 style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
407
+36 -1
--- src/blob.c
+++ src/blob.c
@@ -34,14 +34,20 @@
3434
*/
3535
struct Blob {
3636
unsigned int nUsed; /* Number of bytes used in aData[] */
3737
unsigned int nAlloc; /* Number of bytes allocated for aData[] */
3838
unsigned int iCursor; /* Next character of input to parse */
39
+ unsigned int blobFlags; /* One or more BLOBFLAG_* bits */
3940
char *aData; /* Where the information is stored */
4041
void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
4142
};
4243
44
+/*
45
+** Allowed values for Blob.blobFlags
46
+*/
47
+#define BLOBFLAG_NotSQL 0x0001 /* Non-SQL text */
48
+
4349
/*
4450
** The current size of a Blob
4551
*/
4652
#define blob_size(X) ((X)->nUsed)
4753
@@ -148,10 +154,11 @@
148154
free(pBlob->aData);
149155
pBlob->aData = 0;
150156
pBlob->nAlloc = 0;
151157
pBlob->nUsed = 0;
152158
pBlob->iCursor = 0;
159
+ pBlob->blobFlags = 0;
153160
}else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
154161
char *pNew = fossil_realloc(pBlob->aData, newSize);
155162
pBlob->aData = pNew;
156163
pBlob->nAlloc = newSize;
157164
if( pBlob->nUsed>pBlob->nAlloc ){
@@ -162,11 +169,11 @@
162169
163170
/*
164171
** An initializer for Blobs
165172
*/
166173
#if INTERFACE
167
-#define BLOB_INITIALIZER {0,0,0,0,blobReallocMalloc}
174
+#define BLOB_INITIALIZER {0,0,0,0,0,blobReallocMalloc}
168175
#endif
169176
const Blob empty_blob = BLOB_INITIALIZER;
170177
171178
/*
172179
** A reallocation function for when the initial string is in unmanaged
@@ -217,10 +224,11 @@
217224
}else{
218225
if( size<=0 ) size = strlen(zData);
219226
pBlob->nUsed = pBlob->nAlloc = size;
220227
pBlob->aData = (char*)zData;
221228
pBlob->iCursor = 0;
229
+ pBlob->blobFlags = 0;
222230
pBlob->xRealloc = blobReallocStatic;
223231
}
224232
}
225233
226234
/*
@@ -248,10 +256,11 @@
248256
assert_blob_is_reset(pBlob);
249257
pBlob->nUsed = 0;
250258
pBlob->nAlloc = 1;
251259
pBlob->aData = (char*)zEmpty;
252260
pBlob->iCursor = 0;
261
+ pBlob->blobFlags = 0;
253262
pBlob->xRealloc = blobReallocStatic;
254263
}
255264
256265
/*
257266
** Append text or data to the end of a blob.
@@ -292,10 +301,24 @@
292301
if( p->aData[p->nUsed]!=0 ){
293302
blob_materialize(p);
294303
}
295304
return p->aData;
296305
}
306
+
307
+/*
308
+** Return a pointer to a null-terminated string for a blob that has
309
+** been created using blob_append_sql() and not blob_appendf(). If
310
+** text was ever added using blob_appendf() then throw an error.
311
+*/
312
+char *blob_sql_text(Blob *p){
313
+ blob_is_init(p);
314
+ if( (p->blobFlags & BLOBFLAG_NotSQL) ){
315
+ fossil_fatal("Internal error: Use of blob_appendf() to construct SQL text");
316
+ }
317
+ return blob_str(p);
318
+}
319
+
297320
298321
/*
299322
** Return a pointer to a null-terminated string for a blob.
300323
**
301324
** WARNING: If the blob is ephemeral, it might cause a '\000'
@@ -671,13 +694,25 @@
671694
return i;
672695
}
673696
674697
/*
675698
** Do printf-style string rendering and append the results to a blob.
699
+**
700
+** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
701
+** whereas blob_append_sql() does not.
676702
*/
677703
void blob_appendf(Blob *pBlob, const char *zFormat, ...){
678704
if( pBlob ){
705
+ va_list ap;
706
+ va_start(ap, zFormat);
707
+ vxprintf(pBlob, zFormat, ap);
708
+ va_end(ap);
709
+ pBlob->blobFlags |= BLOBFLAG_NotSQL;
710
+ }
711
+}
712
+void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
713
+ if( pBlob ){
679714
va_list ap;
680715
va_start(ap, zFormat);
681716
vxprintf(pBlob, zFormat, ap);
682717
va_end(ap);
683718
}
684719
--- src/blob.c
+++ src/blob.c
@@ -34,14 +34,20 @@
34 */
35 struct Blob {
36 unsigned int nUsed; /* Number of bytes used in aData[] */
37 unsigned int nAlloc; /* Number of bytes allocated for aData[] */
38 unsigned int iCursor; /* Next character of input to parse */
 
39 char *aData; /* Where the information is stored */
40 void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
41 };
42
 
 
 
 
 
43 /*
44 ** The current size of a Blob
45 */
46 #define blob_size(X) ((X)->nUsed)
47
@@ -148,10 +154,11 @@
148 free(pBlob->aData);
149 pBlob->aData = 0;
150 pBlob->nAlloc = 0;
151 pBlob->nUsed = 0;
152 pBlob->iCursor = 0;
 
153 }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
154 char *pNew = fossil_realloc(pBlob->aData, newSize);
155 pBlob->aData = pNew;
156 pBlob->nAlloc = newSize;
157 if( pBlob->nUsed>pBlob->nAlloc ){
@@ -162,11 +169,11 @@
162
163 /*
164 ** An initializer for Blobs
165 */
166 #if INTERFACE
167 #define BLOB_INITIALIZER {0,0,0,0,blobReallocMalloc}
168 #endif
169 const Blob empty_blob = BLOB_INITIALIZER;
170
171 /*
172 ** A reallocation function for when the initial string is in unmanaged
@@ -217,10 +224,11 @@
217 }else{
218 if( size<=0 ) size = strlen(zData);
219 pBlob->nUsed = pBlob->nAlloc = size;
220 pBlob->aData = (char*)zData;
221 pBlob->iCursor = 0;
 
222 pBlob->xRealloc = blobReallocStatic;
223 }
224 }
225
226 /*
@@ -248,10 +256,11 @@
248 assert_blob_is_reset(pBlob);
249 pBlob->nUsed = 0;
250 pBlob->nAlloc = 1;
251 pBlob->aData = (char*)zEmpty;
252 pBlob->iCursor = 0;
 
253 pBlob->xRealloc = blobReallocStatic;
254 }
255
256 /*
257 ** Append text or data to the end of a blob.
@@ -292,10 +301,24 @@
292 if( p->aData[p->nUsed]!=0 ){
293 blob_materialize(p);
294 }
295 return p->aData;
296 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
298 /*
299 ** Return a pointer to a null-terminated string for a blob.
300 **
301 ** WARNING: If the blob is ephemeral, it might cause a '\000'
@@ -671,13 +694,25 @@
671 return i;
672 }
673
674 /*
675 ** Do printf-style string rendering and append the results to a blob.
 
 
 
676 */
677 void blob_appendf(Blob *pBlob, const char *zFormat, ...){
678 if( pBlob ){
 
 
 
 
 
 
 
 
 
679 va_list ap;
680 va_start(ap, zFormat);
681 vxprintf(pBlob, zFormat, ap);
682 va_end(ap);
683 }
684
--- src/blob.c
+++ src/blob.c
@@ -34,14 +34,20 @@
34 */
35 struct Blob {
36 unsigned int nUsed; /* Number of bytes used in aData[] */
37 unsigned int nAlloc; /* Number of bytes allocated for aData[] */
38 unsigned int iCursor; /* Next character of input to parse */
39 unsigned int blobFlags; /* One or more BLOBFLAG_* bits */
40 char *aData; /* Where the information is stored */
41 void (*xRealloc)(Blob*, unsigned int); /* Function to reallocate the buffer */
42 };
43
44 /*
45 ** Allowed values for Blob.blobFlags
46 */
47 #define BLOBFLAG_NotSQL 0x0001 /* Non-SQL text */
48
49 /*
50 ** The current size of a Blob
51 */
52 #define blob_size(X) ((X)->nUsed)
53
@@ -148,10 +154,11 @@
154 free(pBlob->aData);
155 pBlob->aData = 0;
156 pBlob->nAlloc = 0;
157 pBlob->nUsed = 0;
158 pBlob->iCursor = 0;
159 pBlob->blobFlags = 0;
160 }else if( newSize>pBlob->nAlloc || newSize<pBlob->nAlloc-4000 ){
161 char *pNew = fossil_realloc(pBlob->aData, newSize);
162 pBlob->aData = pNew;
163 pBlob->nAlloc = newSize;
164 if( pBlob->nUsed>pBlob->nAlloc ){
@@ -162,11 +169,11 @@
169
170 /*
171 ** An initializer for Blobs
172 */
173 #if INTERFACE
174 #define BLOB_INITIALIZER {0,0,0,0,0,blobReallocMalloc}
175 #endif
176 const Blob empty_blob = BLOB_INITIALIZER;
177
178 /*
179 ** A reallocation function for when the initial string is in unmanaged
@@ -217,10 +224,11 @@
224 }else{
225 if( size<=0 ) size = strlen(zData);
226 pBlob->nUsed = pBlob->nAlloc = size;
227 pBlob->aData = (char*)zData;
228 pBlob->iCursor = 0;
229 pBlob->blobFlags = 0;
230 pBlob->xRealloc = blobReallocStatic;
231 }
232 }
233
234 /*
@@ -248,10 +256,11 @@
256 assert_blob_is_reset(pBlob);
257 pBlob->nUsed = 0;
258 pBlob->nAlloc = 1;
259 pBlob->aData = (char*)zEmpty;
260 pBlob->iCursor = 0;
261 pBlob->blobFlags = 0;
262 pBlob->xRealloc = blobReallocStatic;
263 }
264
265 /*
266 ** Append text or data to the end of a blob.
@@ -292,10 +301,24 @@
301 if( p->aData[p->nUsed]!=0 ){
302 blob_materialize(p);
303 }
304 return p->aData;
305 }
306
307 /*
308 ** Return a pointer to a null-terminated string for a blob that has
309 ** been created using blob_append_sql() and not blob_appendf(). If
310 ** text was ever added using blob_appendf() then throw an error.
311 */
312 char *blob_sql_text(Blob *p){
313 blob_is_init(p);
314 if( (p->blobFlags & BLOBFLAG_NotSQL) ){
315 fossil_fatal("Internal error: Use of blob_appendf() to construct SQL text");
316 }
317 return blob_str(p);
318 }
319
320
321 /*
322 ** Return a pointer to a null-terminated string for a blob.
323 **
324 ** WARNING: If the blob is ephemeral, it might cause a '\000'
@@ -671,13 +694,25 @@
694 return i;
695 }
696
697 /*
698 ** Do printf-style string rendering and append the results to a blob.
699 **
700 ** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
701 ** whereas blob_append_sql() does not.
702 */
703 void blob_appendf(Blob *pBlob, const char *zFormat, ...){
704 if( pBlob ){
705 va_list ap;
706 va_start(ap, zFormat);
707 vxprintf(pBlob, zFormat, ap);
708 va_end(ap);
709 pBlob->blobFlags |= BLOBFLAG_NotSQL;
710 }
711 }
712 void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
713 if( pBlob ){
714 va_list ap;
715 va_start(ap, zFormat);
716 vxprintf(pBlob, zFormat, ap);
717 va_end(ap);
718 }
719
+2 -2
--- src/branch.c
+++ src/branch.c
@@ -300,12 +300,12 @@
300300
if( colorTest ){
301301
showClosed = 0;
302302
showAll = 1;
303303
}
304304
305
- style_header(showClosed ? "Closed Branches" :
306
- showAll ? "All Branches" : "Open Branches");
305
+ style_header("%s", showClosed ? "Closed Branches" :
306
+ showAll ? "All Branches" : "Open Branches");
307307
style_submenu_element("Timeline", "Timeline", "brtimeline");
308308
if( showClosed ){
309309
style_submenu_element("All", "All", "brlist?all");
310310
style_submenu_element("Open","Open","brlist");
311311
}else if( showAll ){
312312
--- src/branch.c
+++ src/branch.c
@@ -300,12 +300,12 @@
300 if( colorTest ){
301 showClosed = 0;
302 showAll = 1;
303 }
304
305 style_header(showClosed ? "Closed Branches" :
306 showAll ? "All Branches" : "Open Branches");
307 style_submenu_element("Timeline", "Timeline", "brtimeline");
308 if( showClosed ){
309 style_submenu_element("All", "All", "brlist?all");
310 style_submenu_element("Open","Open","brlist");
311 }else if( showAll ){
312
--- src/branch.c
+++ src/branch.c
@@ -300,12 +300,12 @@
300 if( colorTest ){
301 showClosed = 0;
302 showAll = 1;
303 }
304
305 style_header("%s", showClosed ? "Closed Branches" :
306 showAll ? "All Branches" : "Open Branches");
307 style_submenu_element("Timeline", "Timeline", "brtimeline");
308 if( showClosed ){
309 style_submenu_element("All", "All", "brlist?all");
310 style_submenu_element("Open","Open","brlist");
311 }else if( showAll ){
312
+2 -2
--- src/browse.c
+++ src/browse.c
@@ -759,11 +759,11 @@
759759
db_prepare(&ins,
760760
"INSERT INTO temp.fileage(fid, pathname)"
761761
" SELECT rid, :path FROM blob WHERE uuid=:uuid"
762762
);
763763
while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764
- if(zGlob && !strglob(zGlob, pFile->zName)) continue;
764
+ if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
765765
db_bind_text(&ins, ":uuid", pFile->zUuid);
766766
db_bind_text(&ins, ":path", pFile->zName);
767767
db_step(&ins);
768768
db_reset(&ins);
769769
nFile++;
@@ -828,11 +828,11 @@
828828
rid = symbolic_name_to_rid(zName, "ci");
829829
if( rid==0 ){
830830
fossil_fatal("not a valid check-in: %s", zName);
831831
}
832832
style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
833
- style_header("File Ages", zName);
833
+ style_header("File Ages");
834834
zGlob = P("glob");
835835
compute_fileage(rid,zGlob);
836836
baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837837
zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838838
@ <h2>File Ages For Check-in
839839
--- src/browse.c
+++ src/browse.c
@@ -759,11 +759,11 @@
759 db_prepare(&ins,
760 "INSERT INTO temp.fileage(fid, pathname)"
761 " SELECT rid, :path FROM blob WHERE uuid=:uuid"
762 );
763 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764 if(zGlob && !strglob(zGlob, pFile->zName)) continue;
765 db_bind_text(&ins, ":uuid", pFile->zUuid);
766 db_bind_text(&ins, ":path", pFile->zName);
767 db_step(&ins);
768 db_reset(&ins);
769 nFile++;
@@ -828,11 +828,11 @@
828 rid = symbolic_name_to_rid(zName, "ci");
829 if( rid==0 ){
830 fossil_fatal("not a valid check-in: %s", zName);
831 }
832 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
833 style_header("File Ages", zName);
834 zGlob = P("glob");
835 compute_fileage(rid,zGlob);
836 baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837 zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838 @ <h2>File Ages For Check-in
839
--- src/browse.c
+++ src/browse.c
@@ -759,11 +759,11 @@
759 db_prepare(&ins,
760 "INSERT INTO temp.fileage(fid, pathname)"
761 " SELECT rid, :path FROM blob WHERE uuid=:uuid"
762 );
763 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764 if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
765 db_bind_text(&ins, ":uuid", pFile->zUuid);
766 db_bind_text(&ins, ":path", pFile->zName);
767 db_step(&ins);
768 db_reset(&ins);
769 nFile++;
@@ -828,11 +828,11 @@
828 rid = symbolic_name_to_rid(zName, "ci");
829 if( rid==0 ){
830 fossil_fatal("not a valid check-in: %s", zName);
831 }
832 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
833 style_header("File Ages");
834 zGlob = P("glob");
835 compute_fileage(rid,zGlob);
836 baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837 zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838 @ <h2>File Ages For Check-in
839
+9 -9
--- src/cache.c
+++ src/cache.c
@@ -61,11 +61,11 @@
6161
fossil_free(zDbName);
6262
if( rc ){
6363
sqlite3_close(db);
6464
return 0;
6565
}
66
- rc = sqlite3_exec(db,
66
+ rc = sqlite3_exec(db,
6767
"PRAGMA page_size=8192;"
6868
"CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
6969
"CREATE TABLE IF NOT EXISTS cache("
7070
"key TEXT PRIMARY KEY," /* Key used to access the cache */
7171
"id INT REFERENCES blob," /* The cache content */
@@ -94,11 +94,11 @@
9494
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
9595
if( rc ){
9696
sqlite3_finalize(pStmt);
9797
pStmt = 0;
9898
}
99
- return pStmt;
99
+ return pStmt;
100100
}
101101
102102
/*
103103
** This routine implements an SQL function that renders a large integer
104104
** compactly: ex: 12.3MB
@@ -153,11 +153,11 @@
153153
if( pStmt==0 ) goto cache_write_end;
154154
sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
155155
SQLITE_STATIC);
156156
if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
157157
sqlite3_finalize(pStmt);
158
- pStmt = cacheStmt(db,
158
+ pStmt = cacheStmt(db,
159159
"INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
160160
"VALUES(?1,?2,strftime('%s','now'),1,?3)"
161161
);
162162
if( pStmt==0 ) goto cache_write_end;
163163
sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
@@ -202,27 +202,27 @@
202202
203203
db = cacheOpen(0);
204204
if( db==0 ) return 0;
205205
sqlite3_busy_timeout(db, 10000);
206206
sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
207
- pStmt = cacheStmt(db,
207
+ pStmt = cacheStmt(db,
208208
"SELECT blob.data FROM cache, blob"
209209
" WHERE cache.key=?1 AND cache.id=blob.id");
210210
if( pStmt==0 ) goto cache_read_done;
211211
sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
212212
if( sqlite3_step(pStmt)==SQLITE_ROW ){
213213
blob_append(pContent, sqlite3_column_blob(pStmt, 0),
214214
sqlite3_column_bytes(pStmt, 0));
215215
rc = 1;
216216
sqlite3_reset(pStmt);
217
- pStmt = cacheStmt(db,
217
+ pStmt = cacheStmt(db,
218218
"UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
219219
" WHERE key=?1");
220220
if( pStmt ){
221221
sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
222222
sqlite3_step(pStmt);
223
- }
223
+ }
224224
}
225225
sqlite3_finalize(pStmt);
226226
cache_read_done:
227227
sqlite3_exec(db, "COMMIT", 0, 0, 0);
228228
sqlite3_close(db);
@@ -256,11 +256,11 @@
256256
sqlite3_stmt *pStmt;
257257
258258
db_find_and_open_repository(0,0);
259259
zCmd = g.argc>=3 ? g.argv[2] : "";
260260
nCmd = (int)strlen(zCmd);
261
- if( nCmd<=1 ){
261
+ if( nCmd<=1 ){
262262
fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
263263
}
264264
if( strncmp(zCmd, "init", nCmd)==0 ){
265265
db = cacheOpen(0);
266266
sqlite3_close(db);
@@ -290,11 +290,11 @@
290290
fossil_print("cache does not exist\n");
291291
}else{
292292
int nEntry = 0;
293293
char *zDbName = cacheName();
294294
cache_register_sizename(db);
295
- pStmt = cacheStmt(db,
295
+ pStmt = cacheStmt(db,
296296
"SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
297297
" FROM cache"
298298
" ORDER BY tm DESC"
299299
);
300300
if( pStmt ){
@@ -338,11 +338,11 @@
338338
if( db==0 ){
339339
@ The web-page cache is disabled for this repository
340340
}else{
341341
char *zDbName = cacheName();
342342
cache_register_sizename(db);
343
- pStmt = cacheStmt(db,
343
+ pStmt = cacheStmt(db,
344344
"SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
345345
" FROM cache"
346346
" ORDER BY tm DESC"
347347
);
348348
if( pStmt ){
349349
--- src/cache.c
+++ src/cache.c
@@ -61,11 +61,11 @@
61 fossil_free(zDbName);
62 if( rc ){
63 sqlite3_close(db);
64 return 0;
65 }
66 rc = sqlite3_exec(db,
67 "PRAGMA page_size=8192;"
68 "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
69 "CREATE TABLE IF NOT EXISTS cache("
70 "key TEXT PRIMARY KEY," /* Key used to access the cache */
71 "id INT REFERENCES blob," /* The cache content */
@@ -94,11 +94,11 @@
94 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
95 if( rc ){
96 sqlite3_finalize(pStmt);
97 pStmt = 0;
98 }
99 return pStmt;
100 }
101
102 /*
103 ** This routine implements an SQL function that renders a large integer
104 ** compactly: ex: 12.3MB
@@ -153,11 +153,11 @@
153 if( pStmt==0 ) goto cache_write_end;
154 sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
155 SQLITE_STATIC);
156 if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
157 sqlite3_finalize(pStmt);
158 pStmt = cacheStmt(db,
159 "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
160 "VALUES(?1,?2,strftime('%s','now'),1,?3)"
161 );
162 if( pStmt==0 ) goto cache_write_end;
163 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
@@ -202,27 +202,27 @@
202
203 db = cacheOpen(0);
204 if( db==0 ) return 0;
205 sqlite3_busy_timeout(db, 10000);
206 sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
207 pStmt = cacheStmt(db,
208 "SELECT blob.data FROM cache, blob"
209 " WHERE cache.key=?1 AND cache.id=blob.id");
210 if( pStmt==0 ) goto cache_read_done;
211 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
212 if( sqlite3_step(pStmt)==SQLITE_ROW ){
213 blob_append(pContent, sqlite3_column_blob(pStmt, 0),
214 sqlite3_column_bytes(pStmt, 0));
215 rc = 1;
216 sqlite3_reset(pStmt);
217 pStmt = cacheStmt(db,
218 "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
219 " WHERE key=?1");
220 if( pStmt ){
221 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
222 sqlite3_step(pStmt);
223 }
224 }
225 sqlite3_finalize(pStmt);
226 cache_read_done:
227 sqlite3_exec(db, "COMMIT", 0, 0, 0);
228 sqlite3_close(db);
@@ -256,11 +256,11 @@
256 sqlite3_stmt *pStmt;
257
258 db_find_and_open_repository(0,0);
259 zCmd = g.argc>=3 ? g.argv[2] : "";
260 nCmd = (int)strlen(zCmd);
261 if( nCmd<=1 ){
262 fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
263 }
264 if( strncmp(zCmd, "init", nCmd)==0 ){
265 db = cacheOpen(0);
266 sqlite3_close(db);
@@ -290,11 +290,11 @@
290 fossil_print("cache does not exist\n");
291 }else{
292 int nEntry = 0;
293 char *zDbName = cacheName();
294 cache_register_sizename(db);
295 pStmt = cacheStmt(db,
296 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
297 " FROM cache"
298 " ORDER BY tm DESC"
299 );
300 if( pStmt ){
@@ -338,11 +338,11 @@
338 if( db==0 ){
339 @ The web-page cache is disabled for this repository
340 }else{
341 char *zDbName = cacheName();
342 cache_register_sizename(db);
343 pStmt = cacheStmt(db,
344 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
345 " FROM cache"
346 " ORDER BY tm DESC"
347 );
348 if( pStmt ){
349
--- src/cache.c
+++ src/cache.c
@@ -61,11 +61,11 @@
61 fossil_free(zDbName);
62 if( rc ){
63 sqlite3_close(db);
64 return 0;
65 }
66 rc = sqlite3_exec(db,
67 "PRAGMA page_size=8192;"
68 "CREATE TABLE IF NOT EXISTS blob(id INTEGER PRIMARY KEY, data BLOB);"
69 "CREATE TABLE IF NOT EXISTS cache("
70 "key TEXT PRIMARY KEY," /* Key used to access the cache */
71 "id INT REFERENCES blob," /* The cache content */
@@ -94,11 +94,11 @@
94 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
95 if( rc ){
96 sqlite3_finalize(pStmt);
97 pStmt = 0;
98 }
99 return pStmt;
100 }
101
102 /*
103 ** This routine implements an SQL function that renders a large integer
104 ** compactly: ex: 12.3MB
@@ -153,11 +153,11 @@
153 if( pStmt==0 ) goto cache_write_end;
154 sqlite3_bind_blob(pStmt, 1, blob_buffer(pContent), blob_size(pContent),
155 SQLITE_STATIC);
156 if( sqlite3_step(pStmt)!=SQLITE_DONE ) goto cache_write_end;
157 sqlite3_finalize(pStmt);
158 pStmt = cacheStmt(db,
159 "INSERT OR IGNORE INTO cache(key,sz,tm,nref,id)"
160 "VALUES(?1,?2,strftime('%s','now'),1,?3)"
161 );
162 if( pStmt==0 ) goto cache_write_end;
163 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
@@ -202,27 +202,27 @@
202
203 db = cacheOpen(0);
204 if( db==0 ) return 0;
205 sqlite3_busy_timeout(db, 10000);
206 sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0);
207 pStmt = cacheStmt(db,
208 "SELECT blob.data FROM cache, blob"
209 " WHERE cache.key=?1 AND cache.id=blob.id");
210 if( pStmt==0 ) goto cache_read_done;
211 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
212 if( sqlite3_step(pStmt)==SQLITE_ROW ){
213 blob_append(pContent, sqlite3_column_blob(pStmt, 0),
214 sqlite3_column_bytes(pStmt, 0));
215 rc = 1;
216 sqlite3_reset(pStmt);
217 pStmt = cacheStmt(db,
218 "UPDATE cache SET nref=nref+1, tm=strftime('%s','now')"
219 " WHERE key=?1");
220 if( pStmt ){
221 sqlite3_bind_text(pStmt, 1, zKey, -1, SQLITE_STATIC);
222 sqlite3_step(pStmt);
223 }
224 }
225 sqlite3_finalize(pStmt);
226 cache_read_done:
227 sqlite3_exec(db, "COMMIT", 0, 0, 0);
228 sqlite3_close(db);
@@ -256,11 +256,11 @@
256 sqlite3_stmt *pStmt;
257
258 db_find_and_open_repository(0,0);
259 zCmd = g.argc>=3 ? g.argv[2] : "";
260 nCmd = (int)strlen(zCmd);
261 if( nCmd<=1 ){
262 fossil_fatal("Usage: %s cache SUBCOMMAND", g.argv[0]);
263 }
264 if( strncmp(zCmd, "init", nCmd)==0 ){
265 db = cacheOpen(0);
266 sqlite3_close(db);
@@ -290,11 +290,11 @@
290 fossil_print("cache does not exist\n");
291 }else{
292 int nEntry = 0;
293 char *zDbName = cacheName();
294 cache_register_sizename(db);
295 pStmt = cacheStmt(db,
296 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
297 " FROM cache"
298 " ORDER BY tm DESC"
299 );
300 if( pStmt ){
@@ -338,11 +338,11 @@
338 if( db==0 ){
339 @ The web-page cache is disabled for this repository
340 }else{
341 char *zDbName = cacheName();
342 cache_register_sizename(db);
343 pStmt = cacheStmt(db,
344 "SELECT key, sizename(sz), nRef, datetime(tm,'unixepoch')"
345 " FROM cache"
346 " ORDER BY tm DESC"
347 );
348 if( pStmt ){
349
+4 -3
--- src/cgi.c
+++ src/cgi.c
@@ -277,12 +277,12 @@
277277
** Return true if the response should be sent with Content-Encoding: gzip.
278278
*/
279279
static int is_gzippable(void){
280280
if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
281281
return strncmp(zContentType, "text/", 5)==0
282
- || strglob("application/*xml", zContentType)
283
- || strglob("application/*javascript", zContentType);
282
+ || sqlite3_strglob("application/*xml", zContentType)==0
283
+ || sqlite3_strglob("application/*javascript", zContentType)==0;
284284
}
285285
286286
/*
287287
** Do a normal HTTP reply
288288
*/
@@ -1712,11 +1712,12 @@
17121712
listen(listener,10);
17131713
fossil_print("Listening for %s requests on TCP port %d\n",
17141714
(flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
17151715
fflush(stdout);
17161716
if( zBrowser ){
1717
- zBrowser = mprintf(zBrowser, iPort);
1717
+ assert( strstr(zBrowser,"%d")!=0 );
1718
+ zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
17181719
#if defined(__CYGWIN__)
17191720
/* On Cygwin, we can do better than "echo" */
17201721
if( strncmp(zBrowser, "echo ", 5)==0 ){
17211722
wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
17221723
wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
17231724
--- src/cgi.c
+++ src/cgi.c
@@ -277,12 +277,12 @@
277 ** Return true if the response should be sent with Content-Encoding: gzip.
278 */
279 static int is_gzippable(void){
280 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
281 return strncmp(zContentType, "text/", 5)==0
282 || strglob("application/*xml", zContentType)
283 || strglob("application/*javascript", zContentType);
284 }
285
286 /*
287 ** Do a normal HTTP reply
288 */
@@ -1712,11 +1712,12 @@
1712 listen(listener,10);
1713 fossil_print("Listening for %s requests on TCP port %d\n",
1714 (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
1715 fflush(stdout);
1716 if( zBrowser ){
1717 zBrowser = mprintf(zBrowser, iPort);
 
1718 #if defined(__CYGWIN__)
1719 /* On Cygwin, we can do better than "echo" */
1720 if( strncmp(zBrowser, "echo ", 5)==0 ){
1721 wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
1722 wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
1723
--- src/cgi.c
+++ src/cgi.c
@@ -277,12 +277,12 @@
277 ** Return true if the response should be sent with Content-Encoding: gzip.
278 */
279 static int is_gzippable(void){
280 if( strstr(PD("HTTP_ACCEPT_ENCODING", ""), "gzip")==0 ) return 0;
281 return strncmp(zContentType, "text/", 5)==0
282 || sqlite3_strglob("application/*xml", zContentType)==0
283 || sqlite3_strglob("application/*javascript", zContentType)==0;
284 }
285
286 /*
287 ** Do a normal HTTP reply
288 */
@@ -1712,11 +1712,12 @@
1712 listen(listener,10);
1713 fossil_print("Listening for %s requests on TCP port %d\n",
1714 (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
1715 fflush(stdout);
1716 if( zBrowser ){
1717 assert( strstr(zBrowser,"%d")!=0 );
1718 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
1719 #if defined(__CYGWIN__)
1720 /* On Cygwin, we can do better than "echo" */
1721 if( strncmp(zBrowser, "echo ", 5)==0 ){
1722 wchar_t *wUrl = fossil_utf8_to_unicode(zBrowser+5);
1723 wUrl[wcslen(wUrl)-2] = 0; /* Strip terminating " &" */
1724
+20 -17
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
5252
zName = blob_str(&fname);
5353
if( fossil_strcmp(zName, ".")==0 ) {
5454
blob_reset(&where);
5555
break;
5656
}
57
- blob_appendf(&where, " %s (pathname=%Q %s) "
58
- "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
59
- (blob_size(&where)>0) ? "OR" : "AND", zName,
60
- filename_collation(), zName, filename_collation(),
61
- zName, filename_collation());
57
+ blob_append_sql(&where,
58
+ " %s (pathname=%Q %s) "
59
+ "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
60
+ (blob_size(&where)>0) ? "OR" : "AND", zName,
61
+ filename_collation(), zName, filename_collation(),
62
+ zName, filename_collation()
63
+ );
6264
}
6365
6466
db_prepare(&q,
6567
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
6668
" FROM vfile "
6769
" WHERE is_selected(id) %s"
6870
" AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
69
- blob_str(&where)
71
+ blob_sql_text(&where)
7072
);
7173
blob_zero(&rewrittenPathname);
7274
while( db_step(&q)==SQLITE_ROW ){
7375
const char *zPathname = db_column_text(&q,0);
7476
const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
313315
zName = blob_str(&fname);
314316
if( fossil_strcmp(zName, ".")==0 ) {
315317
blob_reset(&where);
316318
break;
317319
}
318
- blob_appendf(&where, " %s (pathname=%Q %s) "
319
- "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
320
- (blob_size(&where)>0) ? "OR" : "WHERE", zName,
321
- filename_collation(), zName, filename_collation(),
322
- zName, filename_collation());
320
+ blob_append_sql(&where,
321
+ " %s (pathname=%Q %s) "
322
+ "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
323
+ (blob_size(&where)>0) ? "OR" : "WHERE", zName,
324
+ filename_collation(), zName, filename_collation(),
325
+ zName, filename_collation()
326
+ );
323327
}
324328
vfile_check_signature(vid, 0);
325329
if( showAge ){
326330
db_prepare(&q,
327331
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
328332
" datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
329333
" FROM vfile %s"
330
- " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy
334
+ " ORDER BY %s",
335
+ vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/
331336
);
332337
}else{
333338
db_prepare(&q,
334339
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
335340
" FROM vfile %s"
336
- " ORDER BY %s", blob_str(&where), zOrderBy
341
+ " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
337342
);
338343
}
339344
blob_reset(&where);
340345
while( db_step(&q)==SQLITE_ROW ){
341346
const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
908913
assert( g.aCommitFile==0 );
909914
if( g.argc>2 ){
910915
int ii, jj=0;
911916
Blob fname;
912917
Stmt q;
913
- const char *zCollate;
914918
Bag toCommit;
915919
916
- zCollate = filename_collation();
917920
blob_zero(&fname);
918921
bag_init(&toCommit);
919922
for(ii=2; ii<g.argc; ii++){
920923
int cnt = 0;
921924
file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
924927
return result;
925928
}
926929
db_prepare(&q,
927930
"SELECT id FROM vfile WHERE pathname=%Q %s"
928931
" OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
929
- blob_str(&fname), zCollate, blob_str(&fname),
930
- zCollate, blob_str(&fname), zCollate);
932
+ blob_str(&fname), filename_collation(), blob_str(&fname),
933
+ filename_collation(), blob_str(&fname), filename_collation());
931934
while( db_step(&q)==SQLITE_ROW ){
932935
cnt++;
933936
bag_insert(&toCommit, db_column_int(&q, 0));
934937
}
935938
db_finalize(&q);
936939
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ) {
54 blob_reset(&where);
55 break;
56 }
57 blob_appendf(&where, " %s (pathname=%Q %s) "
58 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
59 (blob_size(&where)>0) ? "OR" : "AND", zName,
60 filename_collation(), zName, filename_collation(),
61 zName, filename_collation());
 
 
62 }
63
64 db_prepare(&q,
65 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
66 " FROM vfile "
67 " WHERE is_selected(id) %s"
68 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
69 blob_str(&where)
70 );
71 blob_zero(&rewrittenPathname);
72 while( db_step(&q)==SQLITE_ROW ){
73 const char *zPathname = db_column_text(&q,0);
74 const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
313 zName = blob_str(&fname);
314 if( fossil_strcmp(zName, ".")==0 ) {
315 blob_reset(&where);
316 break;
317 }
318 blob_appendf(&where, " %s (pathname=%Q %s) "
319 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
320 (blob_size(&where)>0) ? "OR" : "WHERE", zName,
321 filename_collation(), zName, filename_collation(),
322 zName, filename_collation());
 
 
323 }
324 vfile_check_signature(vid, 0);
325 if( showAge ){
326 db_prepare(&q,
327 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
328 " datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
329 " FROM vfile %s"
330 " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy
 
331 );
332 }else{
333 db_prepare(&q,
334 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
335 " FROM vfile %s"
336 " ORDER BY %s", blob_str(&where), zOrderBy
337 );
338 }
339 blob_reset(&where);
340 while( db_step(&q)==SQLITE_ROW ){
341 const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
908 assert( g.aCommitFile==0 );
909 if( g.argc>2 ){
910 int ii, jj=0;
911 Blob fname;
912 Stmt q;
913 const char *zCollate;
914 Bag toCommit;
915
916 zCollate = filename_collation();
917 blob_zero(&fname);
918 bag_init(&toCommit);
919 for(ii=2; ii<g.argc; ii++){
920 int cnt = 0;
921 file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
924 return result;
925 }
926 db_prepare(&q,
927 "SELECT id FROM vfile WHERE pathname=%Q %s"
928 " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
929 blob_str(&fname), zCollate, blob_str(&fname),
930 zCollate, blob_str(&fname), zCollate);
931 while( db_step(&q)==SQLITE_ROW ){
932 cnt++;
933 bag_insert(&toCommit, db_column_int(&q, 0));
934 }
935 db_finalize(&q);
936
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ) {
54 blob_reset(&where);
55 break;
56 }
57 blob_append_sql(&where,
58 " %s (pathname=%Q %s) "
59 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
60 (blob_size(&where)>0) ? "OR" : "AND", zName,
61 filename_collation(), zName, filename_collation(),
62 zName, filename_collation()
63 );
64 }
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
68 " FROM vfile "
69 " WHERE is_selected(id) %s"
70 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
71 blob_sql_text(&where)
72 );
73 blob_zero(&rewrittenPathname);
74 while( db_step(&q)==SQLITE_ROW ){
75 const char *zPathname = db_column_text(&q,0);
76 const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
315 zName = blob_str(&fname);
316 if( fossil_strcmp(zName, ".")==0 ) {
317 blob_reset(&where);
318 break;
319 }
320 blob_append_sql(&where,
321 " %s (pathname=%Q %s) "
322 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
323 (blob_size(&where)>0) ? "OR" : "WHERE", zName,
324 filename_collation(), zName, filename_collation(),
325 zName, filename_collation()
326 );
327 }
328 vfile_check_signature(vid, 0);
329 if( showAge ){
330 db_prepare(&q,
331 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
332 " datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
333 " FROM vfile %s"
334 " ORDER BY %s",
335 vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/
336 );
337 }else{
338 db_prepare(&q,
339 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
340 " FROM vfile %s"
341 " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
342 );
343 }
344 blob_reset(&where);
345 while( db_step(&q)==SQLITE_ROW ){
346 const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
913 assert( g.aCommitFile==0 );
914 if( g.argc>2 ){
915 int ii, jj=0;
916 Blob fname;
917 Stmt q;
 
918 Bag toCommit;
919
 
920 blob_zero(&fname);
921 bag_init(&toCommit);
922 for(ii=2; ii<g.argc; ii++){
923 int cnt = 0;
924 file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
927 return result;
928 }
929 db_prepare(&q,
930 "SELECT id FROM vfile WHERE pathname=%Q %s"
931 " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
932 blob_str(&fname), filename_collation(), blob_str(&fname),
933 filename_collation(), blob_str(&fname), filename_collation());
934 while( db_step(&q)==SQLITE_ROW ){
935 cnt++;
936 bag_insert(&toCommit, db_column_int(&q, 0));
937 }
938 db_finalize(&q);
939
+20 -17
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
5252
zName = blob_str(&fname);
5353
if( fossil_strcmp(zName, ".")==0 ) {
5454
blob_reset(&where);
5555
break;
5656
}
57
- blob_appendf(&where, " %s (pathname=%Q %s) "
58
- "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
59
- (blob_size(&where)>0) ? "OR" : "AND", zName,
60
- filename_collation(), zName, filename_collation(),
61
- zName, filename_collation());
57
+ blob_append_sql(&where,
58
+ " %s (pathname=%Q %s) "
59
+ "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
60
+ (blob_size(&where)>0) ? "OR" : "AND", zName,
61
+ filename_collation(), zName, filename_collation(),
62
+ zName, filename_collation()
63
+ );
6264
}
6365
6466
db_prepare(&q,
6567
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
6668
" FROM vfile "
6769
" WHERE is_selected(id) %s"
6870
" AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
69
- blob_str(&where)
71
+ blob_sql_text(&where)
7072
);
7173
blob_zero(&rewrittenPathname);
7274
while( db_step(&q)==SQLITE_ROW ){
7375
const char *zPathname = db_column_text(&q,0);
7476
const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
313315
zName = blob_str(&fname);
314316
if( fossil_strcmp(zName, ".")==0 ) {
315317
blob_reset(&where);
316318
break;
317319
}
318
- blob_appendf(&where, " %s (pathname=%Q %s) "
319
- "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
320
- (blob_size(&where)>0) ? "OR" : "WHERE", zName,
321
- filename_collation(), zName, filename_collation(),
322
- zName, filename_collation());
320
+ blob_append_sql(&where,
321
+ " %s (pathname=%Q %s) "
322
+ "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
323
+ (blob_size(&where)>0) ? "OR" : "WHERE", zName,
324
+ filename_collation(), zName, filename_collation(),
325
+ zName, filename_collation()
326
+ );
323327
}
324328
vfile_check_signature(vid, 0);
325329
if( showAge ){
326330
db_prepare(&q,
327331
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
328332
" datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
329333
" FROM vfile %s"
330
- " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy
334
+ " ORDER BY %s",
335
+ vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/
331336
);
332337
}else{
333338
db_prepare(&q,
334339
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
335340
" FROM vfile %s"
336
- " ORDER BY %s", blob_str(&where), zOrderBy
341
+ " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
337342
);
338343
}
339344
blob_reset(&where);
340345
while( db_step(&q)==SQLITE_ROW ){
341346
const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
908913
assert( g.aCommitFile==0 );
909914
if( g.argc>2 ){
910915
int ii, jj=0;
911916
Blob fname;
912917
Stmt q;
913
- const char *zCollate;
914918
Bag toCommit;
915919
916
- zCollate = filename_collation();
917920
blob_zero(&fname);
918921
bag_init(&toCommit);
919922
for(ii=2; ii<g.argc; ii++){
920923
int cnt = 0;
921924
file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
924927
return result;
925928
}
926929
db_prepare(&q,
927930
"SELECT id FROM vfile WHERE pathname=%Q %s"
928931
" OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
929
- blob_str(&fname), zCollate, blob_str(&fname),
930
- zCollate, blob_str(&fname), zCollate);
932
+ blob_str(&fname), filename_collation(), blob_str(&fname),
933
+ filename_collation(), blob_str(&fname), filename_collation());
931934
while( db_step(&q)==SQLITE_ROW ){
932935
cnt++;
933936
bag_insert(&toCommit, db_column_int(&q, 0));
934937
}
935938
db_finalize(&q);
936939
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ) {
54 blob_reset(&where);
55 break;
56 }
57 blob_appendf(&where, " %s (pathname=%Q %s) "
58 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
59 (blob_size(&where)>0) ? "OR" : "AND", zName,
60 filename_collation(), zName, filename_collation(),
61 zName, filename_collation());
 
 
62 }
63
64 db_prepare(&q,
65 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
66 " FROM vfile "
67 " WHERE is_selected(id) %s"
68 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
69 blob_str(&where)
70 );
71 blob_zero(&rewrittenPathname);
72 while( db_step(&q)==SQLITE_ROW ){
73 const char *zPathname = db_column_text(&q,0);
74 const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
313 zName = blob_str(&fname);
314 if( fossil_strcmp(zName, ".")==0 ) {
315 blob_reset(&where);
316 break;
317 }
318 blob_appendf(&where, " %s (pathname=%Q %s) "
319 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
320 (blob_size(&where)>0) ? "OR" : "WHERE", zName,
321 filename_collation(), zName, filename_collation(),
322 zName, filename_collation());
 
 
323 }
324 vfile_check_signature(vid, 0);
325 if( showAge ){
326 db_prepare(&q,
327 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
328 " datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
329 " FROM vfile %s"
330 " ORDER BY %s", vid, timeline_utc(), blob_str(&where), zOrderBy
 
331 );
332 }else{
333 db_prepare(&q,
334 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
335 " FROM vfile %s"
336 " ORDER BY %s", blob_str(&where), zOrderBy
337 );
338 }
339 blob_reset(&where);
340 while( db_step(&q)==SQLITE_ROW ){
341 const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
908 assert( g.aCommitFile==0 );
909 if( g.argc>2 ){
910 int ii, jj=0;
911 Blob fname;
912 Stmt q;
913 const char *zCollate;
914 Bag toCommit;
915
916 zCollate = filename_collation();
917 blob_zero(&fname);
918 bag_init(&toCommit);
919 for(ii=2; ii<g.argc; ii++){
920 int cnt = 0;
921 file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
924 return result;
925 }
926 db_prepare(&q,
927 "SELECT id FROM vfile WHERE pathname=%Q %s"
928 " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
929 blob_str(&fname), zCollate, blob_str(&fname),
930 zCollate, blob_str(&fname), zCollate);
931 while( db_step(&q)==SQLITE_ROW ){
932 cnt++;
933 bag_insert(&toCommit, db_column_int(&q, 0));
934 }
935 db_finalize(&q);
936
--- src/checkin.c
+++ src/checkin.c
@@ -52,23 +52,25 @@
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ) {
54 blob_reset(&where);
55 break;
56 }
57 blob_append_sql(&where,
58 " %s (pathname=%Q %s) "
59 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
60 (blob_size(&where)>0) ? "OR" : "AND", zName,
61 filename_collation(), zName, filename_collation(),
62 zName, filename_collation()
63 );
64 }
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
68 " FROM vfile "
69 " WHERE is_selected(id) %s"
70 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
71 blob_sql_text(&where)
72 );
73 blob_zero(&rewrittenPathname);
74 while( db_step(&q)==SQLITE_ROW ){
75 const char *zPathname = db_column_text(&q,0);
76 const char *zDisplayName = zPathname;
@@ -313,29 +315,32 @@
315 zName = blob_str(&fname);
316 if( fossil_strcmp(zName, ".")==0 ) {
317 blob_reset(&where);
318 break;
319 }
320 blob_append_sql(&where,
321 " %s (pathname=%Q %s) "
322 "OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
323 (blob_size(&where)>0) ? "OR" : "WHERE", zName,
324 filename_collation(), zName, filename_collation(),
325 zName, filename_collation()
326 );
327 }
328 vfile_check_signature(vid, 0);
329 if( showAge ){
330 db_prepare(&q,
331 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
332 " datetime(checkin_mtime(%d,rid),'unixepoch'%s)"
333 " FROM vfile %s"
334 " ORDER BY %s",
335 vid, timeline_utc(), blob_sql_text(&where), zOrderBy /*safe-for-%s*/
336 );
337 }else{
338 db_prepare(&q,
339 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
340 " FROM vfile %s"
341 " ORDER BY %s", blob_sql_text(&where), zOrderBy /*safe-for-%s*/
342 );
343 }
344 blob_reset(&where);
345 while( db_step(&q)==SQLITE_ROW ){
346 const char *zPathname = db_column_text(&q,0);
@@ -908,14 +913,12 @@
913 assert( g.aCommitFile==0 );
914 if( g.argc>2 ){
915 int ii, jj=0;
916 Blob fname;
917 Stmt q;
 
918 Bag toCommit;
919
 
920 blob_zero(&fname);
921 bag_init(&toCommit);
922 for(ii=2; ii<g.argc; ii++){
923 int cnt = 0;
924 file_tree_name(g.argv[ii], &fname, 1);
@@ -924,12 +927,12 @@
927 return result;
928 }
929 db_prepare(&q,
930 "SELECT id FROM vfile WHERE pathname=%Q %s"
931 " OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
932 blob_str(&fname), filename_collation(), blob_str(&fname),
933 filename_collation(), blob_str(&fname), filename_collation());
934 while( db_step(&q)==SQLITE_ROW ){
935 cnt++;
936 bag_insert(&toCommit, db_column_int(&q, 0));
937 }
938 db_finalize(&q);
939
+1 -1
--- src/checkout.c
+++ src/checkout.c
@@ -60,11 +60,11 @@
6060
Blob uuid;
6161
int vid;
6262
6363
blob_init(&uuid, zName, -1);
6464
if( name_to_uuid(&uuid, 1, "ci") ){
65
- fossil_fatal(g.zErrMsg);
65
+ fossil_fatal("%s", g.zErrMsg);
6666
}
6767
vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
6868
if( vid==0 ){
6969
fossil_fatal("no such check-in: %s", g.argv[2]);
7070
}
7171
7272
ADDED src/codecheck1.c
--- src/checkout.c
+++ src/checkout.c
@@ -60,11 +60,11 @@
60 Blob uuid;
61 int vid;
62
63 blob_init(&uuid, zName, -1);
64 if( name_to_uuid(&uuid, 1, "ci") ){
65 fossil_fatal(g.zErrMsg);
66 }
67 vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
68 if( vid==0 ){
69 fossil_fatal("no such check-in: %s", g.argv[2]);
70 }
71
72 DDED src/codecheck1.c
--- src/checkout.c
+++ src/checkout.c
@@ -60,11 +60,11 @@
60 Blob uuid;
61 int vid;
62
63 blob_init(&uuid, zName, -1);
64 if( name_to_uuid(&uuid, 1, "ci") ){
65 fossil_fatal("%s", g.zErrMsg);
66 }
67 vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
68 if( vid==0 ){
69 fossil_fatal("no such check-in: %s", g.argv[2]);
70 }
71
72 DDED src/codecheck1.c
--- a/src/codecheck1.c
+++ b/src/codecheck1.c
@@ -0,0 +1,14 @@
1
+/*
2
+** Copyright (c) 2014 D. Richard Hipp
3
+**
4
+** This program is free software; you can redistribute it and/or
5
+** modify it under the terms of the Simplified BSD License (also
6
+** known as the "2-Clause Licensetimeline_utc ** Copyright (c) 2014 D. Richard Hipp
7
+**
8
+** This program is free software; you can redistribute it and/or
9
+** modify it under the terms of the Simplified BSD License (also
10
+** known as the "2-Clause Licensetimeline_utc(c) 2014 D. Richard Hipp
11
+**
12
+** This program is free software; you can redistribute it and/or
13
+** modify it under the terms of the Simplified BSD License (also
14
+** known as the "2-Clause Licensetimeline_utchar const **az
--- a/src/codecheck1.c
+++ b/src/codecheck1.c
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/codecheck1.c
+++ b/src/codecheck1.c
@@ -0,0 +1,14 @@
1 /*
2 ** Copyright (c) 2014 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause Licensetimeline_utc ** Copyright (c) 2014 D. Richard Hipp
7 **
8 ** This program is free software; you can redistribute it and/or
9 ** modify it under the terms of the Simplified BSD License (also
10 ** known as the "2-Clause Licensetimeline_utc(c) 2014 D. Richard Hipp
11 **
12 ** This program is free software; you can redistribute it and/or
13 ** modify it under the terms of the Simplified BSD License (also
14 ** known as the "2-Clause Licensetimeline_utchar const **az
+2 -2
--- src/comformat.c
+++ src/comformat.c
@@ -497,14 +497,14 @@
497497
zOrigText = mprintf("%s", blob_str(&fileData));
498498
blob_reset(&fileData);
499499
}
500500
}
501501
if( decode ){
502
- zText = mprintf(fromFile ? "%z" : "%s", zText);
502
+ zText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zText);
503503
defossilize(zText);
504504
if( zOrigText ){
505
- zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText);
505
+ zOrigText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zOrigText);
506506
defossilize(zOrigText);
507507
}
508508
}
509509
if( indent<0 ){
510510
indent = strlen(zPrefix);
511511
--- src/comformat.c
+++ src/comformat.c
@@ -497,14 +497,14 @@
497 zOrigText = mprintf("%s", blob_str(&fileData));
498 blob_reset(&fileData);
499 }
500 }
501 if( decode ){
502 zText = mprintf(fromFile ? "%z" : "%s", zText);
503 defossilize(zText);
504 if( zOrigText ){
505 zOrigText = mprintf(fromFile ? "%z" : "%s", zOrigText);
506 defossilize(zOrigText);
507 }
508 }
509 if( indent<0 ){
510 indent = strlen(zPrefix);
511
--- src/comformat.c
+++ src/comformat.c
@@ -497,14 +497,14 @@
497 zOrigText = mprintf("%s", blob_str(&fileData));
498 blob_reset(&fileData);
499 }
500 }
501 if( decode ){
502 zText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zText);
503 defossilize(zText);
504 if( zOrigText ){
505 zOrigText = mprintf(fromFile?"%z":"%s" /*works-like:"%s"*/, zOrigText);
506 defossilize(zOrigText);
507 }
508 }
509 if( indent<0 ){
510 indent = strlen(zPrefix);
511
+36 -28
--- src/configure.c
+++ src/configure.c
@@ -194,19 +194,19 @@
194194
Blob x;
195195
int i;
196196
const char *zSep = "";
197197
198198
blob_zero(&x);
199
- blob_append(&x, "(", 1);
199
+ blob_append_sql(&x, "(");
200200
for(i=0; i<count(aConfig); i++){
201201
if( (aConfig[i].groupMask & iMask)==0 ) continue;
202202
if( aConfig[i].zName[0]=='@' ) continue;
203
- blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName);
203
+ blob_append_sql(&x, "%s'%q'", zSep/*safe-for-%s*/, aConfig[i].zName);
204204
zSep = ",";
205205
}
206
- blob_append(&x, ")", 1);
207
- return blob_str(&x);
206
+ blob_append_sql(&x, ")");
207
+ return blob_sql_text(&x);
208208
}
209209
210210
/*
211211
** Return the mask for the named configuration parameter if it can be
212212
** safely exported. Return 0 if the parameter is not safe to export.
@@ -361,11 +361,12 @@
361361
@ INSERT INTO _xfer_reportfmt
362362
@ SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
363363
@ INSERT INTO _xfer_user
364364
@ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
365365
;
366
- db_multi_exec(zSQL1);
366
+ assert( strchr(zSQL1,'%')==0 );
367
+ db_multi_exec(zSQL1 /*works-like:""*/);
367368
368369
/* When the replace flag is set, add triggers that run the first time
369370
** that new data is seen. The triggers run only once and delete all the
370371
** existing data.
371372
*/
@@ -390,11 +391,12 @@
390391
sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
391392
config_is_reset_function, 0, 0);
392393
sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
393394
config_reset_function, 0, 0);
394395
configHasBeenReset = 0;
395
- db_multi_exec(zSQL2);
396
+ assert( strchr(zSQL2,'%')==0 );
397
+ db_multi_exec(zSQL2 /*works-like:""*/);
396398
}
397399
}
398400
399401
/*
400402
** After receiving configuration data, call this routine to transfer
@@ -407,11 +409,12 @@
407409
@ DELETE FROM reportfmt;
408410
@ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
409411
@ DROP TABLE _xfer_user;
410412
@ DROP TABLE _xfer_reportfmt;
411413
;
412
- db_multi_exec(zSQL);
414
+ assert( strchr(zSQL,'%')==0 );
415
+ db_multi_exec(zSQL /*works-like:""*/);
413416
}
414417
415418
/*
416419
** Mask of modified configuration sets
417420
*/
@@ -563,35 +566,39 @@
563566
if( (thisMask & groupMask)==0 ) return;
564567
565568
blob_zero(&sql);
566569
if( groupMask & CONFIGSET_OVERWRITE ){
567570
if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
568
- db_multi_exec("DELETE FROM %s", &aType[ii].zName[1]);
571
+ db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
569572
configHasBeenReset |= thisMask;
570573
}
571
- blob_append(&sql, "REPLACE INTO ", -1);
572
- }else{
573
- blob_append(&sql, "INSERT OR IGNORE INTO ", -1);
574
- }
575
- blob_appendf(&sql, "%s(%s, mtime", &zName[1], aType[ii].zPrimKey);
576
- for(jj=2; jj<nToken; jj+=2){
577
- blob_appendf(&sql, ",%s", azToken[jj]);
578
- }
579
- blob_appendf(&sql,") VALUES(%s,%s", azToken[1], azToken[0]);
580
- for(jj=2; jj<nToken; jj+=2){
581
- blob_appendf(&sql, ",%s", azToken[jj+1]);
582
- }
583
- db_multi_exec("%s)", blob_str(&sql));
574
+ blob_append_sql(&sql, "REPLACE INTO ");
575
+ }else{
576
+ blob_append_sql(&sql, "INSERT OR IGNORE INTO ");
577
+ }
578
+ blob_append_sql(&sql, "\"%w\"(\"%w\", mtime", &zName[1], aType[ii].zPrimKey);
579
+ for(jj=2; jj<nToken; jj+=2){
580
+ blob_append_sql(&sql, ",\"%w\"", azToken[jj]);
581
+ }
582
+ blob_append_sql(&sql,") VALUES(%s,%s",
583
+ azToken[1] /*safe-for-%s*/, azToken[0] /*safe-for-%s*/);
584
+ for(jj=2; jj<nToken; jj+=2){
585
+ blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/);
586
+ }
587
+ db_multi_exec("%s)", blob_sql_text(&sql));
584588
if( db_changes()==0 ){
585589
blob_reset(&sql);
586
- blob_appendf(&sql, "UPDATE %s SET mtime=%s", &zName[1], azToken[0]);
590
+ blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s",
591
+ &zName[1], azToken[0]/*safe-for-%s*/);
587592
for(jj=2; jj<nToken; jj+=2){
588
- blob_appendf(&sql, ", %s=%s", azToken[jj], azToken[jj+1]);
593
+ blob_append_sql(&sql, ", \"%w\"=%s",
594
+ azToken[jj], azToken[jj+1]/*safe-for-%s*/);
589595
}
590
- blob_appendf(&sql, " WHERE %s=%s AND mtime<%s",
591
- aType[ii].zPrimKey, azToken[1], azToken[0]);
592
- db_multi_exec("%s", blob_str(&sql));
596
+ blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s",
597
+ aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/,
598
+ azToken[0]/*safe-for-%s*/);
599
+ db_multi_exec("%s", blob_sql_text(&sql));
593600
}
594601
blob_reset(&sql);
595602
rebuildMask |= thisMask;
596603
}else{
597604
/* Otherwise, the old format */
@@ -609,11 +616,11 @@
609616
/* Notice that we are evaluating arbitrary SQL received from the
610617
** client. But this can only happen if the client has authenticated
611618
** as an administrator, so presumably we trust the client at this
612619
** point.
613620
*/
614
- db_multi_exec("%s", blob_str(pContent));
621
+ db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/);
615622
}else{
616623
db_multi_exec(
617624
"REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
618625
zName, blob_str(pContent)
619626
);
@@ -966,11 +973,12 @@
966973
db_multi_exec("DELETE FROM concealed");
967974
}else if( fossil_strcmp(zName,"@shun")==0 ){
968975
db_multi_exec("DELETE FROM shun");
969976
}else if( fossil_strcmp(zName,"@reportfmt")==0 ){
970977
db_multi_exec("DELETE FROM reportfmt");
971
- db_multi_exec(zRepositorySchemaDefaultReports);
978
+ assert( strchr(zRepositorySchemaDefaultReports,'%')==0 );
979
+ db_multi_exec(zRepositorySchemaDefaultReports /*works-like:""*/);
972980
}
973981
}
974982
db_end_transaction(0);
975983
fossil_print("Configuration reset to factory defaults.\n");
976984
fossil_print("To recover, use: %s %s import %s\n",
977985
--- src/configure.c
+++ src/configure.c
@@ -194,19 +194,19 @@
194 Blob x;
195 int i;
196 const char *zSep = "";
197
198 blob_zero(&x);
199 blob_append(&x, "(", 1);
200 for(i=0; i<count(aConfig); i++){
201 if( (aConfig[i].groupMask & iMask)==0 ) continue;
202 if( aConfig[i].zName[0]=='@' ) continue;
203 blob_appendf(&x, "%s'%s'", zSep, aConfig[i].zName);
204 zSep = ",";
205 }
206 blob_append(&x, ")", 1);
207 return blob_str(&x);
208 }
209
210 /*
211 ** Return the mask for the named configuration parameter if it can be
212 ** safely exported. Return 0 if the parameter is not safe to export.
@@ -361,11 +361,12 @@
361 @ INSERT INTO _xfer_reportfmt
362 @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
363 @ INSERT INTO _xfer_user
364 @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
365 ;
366 db_multi_exec(zSQL1);
 
367
368 /* When the replace flag is set, add triggers that run the first time
369 ** that new data is seen. The triggers run only once and delete all the
370 ** existing data.
371 */
@@ -390,11 +391,12 @@
390 sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
391 config_is_reset_function, 0, 0);
392 sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
393 config_reset_function, 0, 0);
394 configHasBeenReset = 0;
395 db_multi_exec(zSQL2);
 
396 }
397 }
398
399 /*
400 ** After receiving configuration data, call this routine to transfer
@@ -407,11 +409,12 @@
407 @ DELETE FROM reportfmt;
408 @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
409 @ DROP TABLE _xfer_user;
410 @ DROP TABLE _xfer_reportfmt;
411 ;
412 db_multi_exec(zSQL);
 
413 }
414
415 /*
416 ** Mask of modified configuration sets
417 */
@@ -563,35 +566,39 @@
563 if( (thisMask & groupMask)==0 ) return;
564
565 blob_zero(&sql);
566 if( groupMask & CONFIGSET_OVERWRITE ){
567 if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
568 db_multi_exec("DELETE FROM %s", &aType[ii].zName[1]);
569 configHasBeenReset |= thisMask;
570 }
571 blob_append(&sql, "REPLACE INTO ", -1);
572 }else{
573 blob_append(&sql, "INSERT OR IGNORE INTO ", -1);
574 }
575 blob_appendf(&sql, "%s(%s, mtime", &zName[1], aType[ii].zPrimKey);
576 for(jj=2; jj<nToken; jj+=2){
577 blob_appendf(&sql, ",%s", azToken[jj]);
578 }
579 blob_appendf(&sql,") VALUES(%s,%s", azToken[1], azToken[0]);
580 for(jj=2; jj<nToken; jj+=2){
581 blob_appendf(&sql, ",%s", azToken[jj+1]);
582 }
583 db_multi_exec("%s)", blob_str(&sql));
 
584 if( db_changes()==0 ){
585 blob_reset(&sql);
586 blob_appendf(&sql, "UPDATE %s SET mtime=%s", &zName[1], azToken[0]);
 
587 for(jj=2; jj<nToken; jj+=2){
588 blob_appendf(&sql, ", %s=%s", azToken[jj], azToken[jj+1]);
 
589 }
590 blob_appendf(&sql, " WHERE %s=%s AND mtime<%s",
591 aType[ii].zPrimKey, azToken[1], azToken[0]);
592 db_multi_exec("%s", blob_str(&sql));
 
593 }
594 blob_reset(&sql);
595 rebuildMask |= thisMask;
596 }else{
597 /* Otherwise, the old format */
@@ -609,11 +616,11 @@
609 /* Notice that we are evaluating arbitrary SQL received from the
610 ** client. But this can only happen if the client has authenticated
611 ** as an administrator, so presumably we trust the client at this
612 ** point.
613 */
614 db_multi_exec("%s", blob_str(pContent));
615 }else{
616 db_multi_exec(
617 "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
618 zName, blob_str(pContent)
619 );
@@ -966,11 +973,12 @@
966 db_multi_exec("DELETE FROM concealed");
967 }else if( fossil_strcmp(zName,"@shun")==0 ){
968 db_multi_exec("DELETE FROM shun");
969 }else if( fossil_strcmp(zName,"@reportfmt")==0 ){
970 db_multi_exec("DELETE FROM reportfmt");
971 db_multi_exec(zRepositorySchemaDefaultReports);
 
972 }
973 }
974 db_end_transaction(0);
975 fossil_print("Configuration reset to factory defaults.\n");
976 fossil_print("To recover, use: %s %s import %s\n",
977
--- src/configure.c
+++ src/configure.c
@@ -194,19 +194,19 @@
194 Blob x;
195 int i;
196 const char *zSep = "";
197
198 blob_zero(&x);
199 blob_append_sql(&x, "(");
200 for(i=0; i<count(aConfig); i++){
201 if( (aConfig[i].groupMask & iMask)==0 ) continue;
202 if( aConfig[i].zName[0]=='@' ) continue;
203 blob_append_sql(&x, "%s'%q'", zSep/*safe-for-%s*/, aConfig[i].zName);
204 zSep = ",";
205 }
206 blob_append_sql(&x, ")");
207 return blob_sql_text(&x);
208 }
209
210 /*
211 ** Return the mask for the named configuration parameter if it can be
212 ** safely exported. Return 0 if the parameter is not safe to export.
@@ -361,11 +361,12 @@
361 @ INSERT INTO _xfer_reportfmt
362 @ SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
363 @ INSERT INTO _xfer_user
364 @ SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
365 ;
366 assert( strchr(zSQL1,'%')==0 );
367 db_multi_exec(zSQL1 /*works-like:""*/);
368
369 /* When the replace flag is set, add triggers that run the first time
370 ** that new data is seen. The triggers run only once and delete all the
371 ** existing data.
372 */
@@ -390,11 +391,12 @@
391 sqlite3_create_function(g.db, "config_is_reset", 1, SQLITE_UTF8, 0,
392 config_is_reset_function, 0, 0);
393 sqlite3_create_function(g.db, "config_reset", 1, SQLITE_UTF8, 0,
394 config_reset_function, 0, 0);
395 configHasBeenReset = 0;
396 assert( strchr(zSQL2,'%')==0 );
397 db_multi_exec(zSQL2 /*works-like:""*/);
398 }
399 }
400
401 /*
402 ** After receiving configuration data, call this routine to transfer
@@ -407,11 +409,12 @@
409 @ DELETE FROM reportfmt;
410 @ INSERT INTO reportfmt SELECT * FROM _xfer_reportfmt;
411 @ DROP TABLE _xfer_user;
412 @ DROP TABLE _xfer_reportfmt;
413 ;
414 assert( strchr(zSQL,'%')==0 );
415 db_multi_exec(zSQL /*works-like:""*/);
416 }
417
418 /*
419 ** Mask of modified configuration sets
420 */
@@ -563,35 +566,39 @@
566 if( (thisMask & groupMask)==0 ) return;
567
568 blob_zero(&sql);
569 if( groupMask & CONFIGSET_OVERWRITE ){
570 if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
571 db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
572 configHasBeenReset |= thisMask;
573 }
574 blob_append_sql(&sql, "REPLACE INTO ");
575 }else{
576 blob_append_sql(&sql, "INSERT OR IGNORE INTO ");
577 }
578 blob_append_sql(&sql, "\"%w\"(\"%w\", mtime", &zName[1], aType[ii].zPrimKey);
579 for(jj=2; jj<nToken; jj+=2){
580 blob_append_sql(&sql, ",\"%w\"", azToken[jj]);
581 }
582 blob_append_sql(&sql,") VALUES(%s,%s",
583 azToken[1] /*safe-for-%s*/, azToken[0] /*safe-for-%s*/);
584 for(jj=2; jj<nToken; jj+=2){
585 blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/);
586 }
587 db_multi_exec("%s)", blob_sql_text(&sql));
588 if( db_changes()==0 ){
589 blob_reset(&sql);
590 blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s",
591 &zName[1], azToken[0]/*safe-for-%s*/);
592 for(jj=2; jj<nToken; jj+=2){
593 blob_append_sql(&sql, ", \"%w\"=%s",
594 azToken[jj], azToken[jj+1]/*safe-for-%s*/);
595 }
596 blob_append_sql(&sql, " WHERE \"%w\"=%s AND mtime<%s",
597 aType[ii].zPrimKey, azToken[1]/*safe-for-%s*/,
598 azToken[0]/*safe-for-%s*/);
599 db_multi_exec("%s", blob_sql_text(&sql));
600 }
601 blob_reset(&sql);
602 rebuildMask |= thisMask;
603 }else{
604 /* Otherwise, the old format */
@@ -609,11 +616,11 @@
616 /* Notice that we are evaluating arbitrary SQL received from the
617 ** client. But this can only happen if the client has authenticated
618 ** as an administrator, so presumably we trust the client at this
619 ** point.
620 */
621 db_multi_exec("%s", blob_str(pContent) /*safe-for-%s*/);
622 }else{
623 db_multi_exec(
624 "REPLACE INTO config(name,value,mtime) VALUES(%Q,%Q,now())",
625 zName, blob_str(pContent)
626 );
@@ -966,11 +973,12 @@
973 db_multi_exec("DELETE FROM concealed");
974 }else if( fossil_strcmp(zName,"@shun")==0 ){
975 db_multi_exec("DELETE FROM shun");
976 }else if( fossil_strcmp(zName,"@reportfmt")==0 ){
977 db_multi_exec("DELETE FROM reportfmt");
978 assert( strchr(zRepositorySchemaDefaultReports,'%')==0 );
979 db_multi_exec(zRepositorySchemaDefaultReports /*works-like:""*/);
980 }
981 }
982 db_end_transaction(0);
983 fossil_print("Configuration reset to factory defaults.\n");
984 fossil_print("To recover, use: %s %s import %s\n",
985
+2 -2
--- src/content.c
+++ src/content.c
@@ -558,12 +558,12 @@
558558
}
559559
}else{
560560
/* We are creating a new entry */
561561
db_prepare(&s1,
562562
"INSERT INTO blob(rcvid,size,uuid,content)"
563
- "VALUES(%d,%d,'%b',:data)",
564
- g.rcvid, size, &hash
563
+ "VALUES(%d,%d,'%q',:data)",
564
+ g.rcvid, size, blob_str(&hash)
565565
);
566566
db_bind_blob(&s1, ":data", &cmpr);
567567
db_exec(&s1);
568568
rid = db_last_insert_rowid();
569569
if( !pBlob ){
570570
--- src/content.c
+++ src/content.c
@@ -558,12 +558,12 @@
558 }
559 }else{
560 /* We are creating a new entry */
561 db_prepare(&s1,
562 "INSERT INTO blob(rcvid,size,uuid,content)"
563 "VALUES(%d,%d,'%b',:data)",
564 g.rcvid, size, &hash
565 );
566 db_bind_blob(&s1, ":data", &cmpr);
567 db_exec(&s1);
568 rid = db_last_insert_rowid();
569 if( !pBlob ){
570
--- src/content.c
+++ src/content.c
@@ -558,12 +558,12 @@
558 }
559 }else{
560 /* We are creating a new entry */
561 db_prepare(&s1,
562 "INSERT INTO blob(rcvid,size,uuid,content)"
563 "VALUES(%d,%d,'%q',:data)",
564 g.rcvid, size, blob_str(&hash)
565 );
566 db_bind_blob(&s1, ":data", &cmpr);
567 db_exec(&s1);
568 rid = db_last_insert_rowid();
569 if( !pBlob ){
570
+34 -35
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177177
db.doRollback |= db.aHook[i].xHook();
178178
}
179179
while( db.pAllStmt ){
180180
db_finalize(db.pAllStmt);
181181
}
182
- db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
182
+ db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183183
db.doRollback = 0;
184184
}
185185
}
186186
187187
/*
@@ -664,17 +664,17 @@
664664
665665
db = db_open(zFileName);
666666
sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667667
rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668668
if( rc!=SQLITE_OK ){
669
- db_err(sqlite3_errmsg(db));
669
+ db_err("%s", sqlite3_errmsg(db));
670670
}
671671
va_start(ap, zSchema);
672672
while( (zSql = va_arg(ap, const char*))!=0 ){
673673
rc = sqlite3_exec(db, zSql, 0, 0, 0);
674674
if( rc!=SQLITE_OK ){
675
- db_err(sqlite3_errmsg(db));
675
+ db_err("%s", sqlite3_errmsg(db));
676676
}
677677
}
678678
va_end(ap);
679679
sqlite3_exec(db, "COMMIT", 0, 0, 0);
680680
sqlite3_close(db);
@@ -750,19 +750,19 @@
750750
751751
/*
752752
** Detaches the zLabel database.
753753
*/
754754
void db_detach(const char *zLabel){
755
- db_multi_exec("DETACH DATABASE %s", zLabel);
755
+ db_multi_exec("DETACH DATABASE %Q", zLabel);
756756
}
757757
758758
/*
759759
** zDbName is the name of a database file. Attach zDbName using
760760
** the name zLabel.
761761
*/
762762
void db_attach(const char *zDbName, const char *zLabel){
763
- db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
763
+ db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764764
}
765765
766766
/*
767767
** zDbName is the name of a database file. If no other database
768768
** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887887
static int db_local_table_exists_but_lacks_column(
888888
const char *zTable,
889889
const char *zColumn
890890
){
891891
char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892
- " WHERE name=='%s' /*scan*/",
892
+ " WHERE name==%Q /*scan*/",
893893
db_name("localdb"), zTable);
894894
int rc = 0;
895895
if( zDef ){
896896
char *zPattern = mprintf("* %s *", zColumn);
897
- rc = strglob(zPattern, zDef)==0;
897
+ rc = sqlite3_strglob(zPattern, zDef)!=0;
898898
fossil_free(zPattern);
899899
fossil_free(zDef);
900900
}
901901
return rc;
902902
}
@@ -919,19 +919,19 @@
919919
920920
/* If the "isexe" column is missing from the vfile table, then
921921
** add it now. This code added on 2010-03-06. After all users have
922922
** upgraded, this code can be safely deleted.
923923
*/
924
- if( !strglob("* isexe *", zVFileDef) ){
924
+ if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925925
db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926926
}
927927
928928
/* If "islink"/"isLink" columns are missing from tables, then
929929
** add them now. This code added on 2011-01-17 and 2011-08-27.
930930
** After all users have upgraded, this code can be safely deleted.
931931
*/
932
- if( !strglob("* islink *", zVFileDef) ){
932
+ if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933933
db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934934
if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935935
db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936936
}
937937
if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
11191119
** Return TRUE if the schema is out-of-date
11201120
*/
11211121
int db_schema_is_outofdate(void){
11221122
return db_exists("SELECT 1 FROM config"
11231123
" WHERE name='aux-schema'"
1124
- " AND value<>'%s'", AUX_SCHEMA);
1124
+ " AND value<>%Q", AUX_SCHEMA);
11251125
}
11261126
11271127
/*
11281128
** Return true if the database is writeable
11291129
*/
@@ -1330,17 +1330,17 @@
13301330
"INSERT INTO config(name,value,mtime)"
13311331
" VALUES('project-code', lower(hex(randomblob(20))),now());"
13321332
);
13331333
}else{
13341334
if( db_get("server-code", 0)==0 ) {
1335
- db_optional_sql("repository",
1335
+ db_multi_exec(
13361336
"INSERT INTO config(name,value,mtime)"
13371337
" VALUES('server-code', lower(hex(randomblob(20))),now());"
13381338
);
13391339
}
13401340
if( db_get("project-code", 0)==0 ) {
1341
- db_optional_sql("repository",
1341
+ db_multi_exec(
13421342
"INSERT INTO config(name,value,mtime)"
13431343
" VALUES('project-code', lower(hex(randomblob(20))),now());"
13441344
);
13451345
}
13461346
}
@@ -1355,17 +1355,17 @@
13551355
Blob x;
13561356
int i;
13571357
const char *zSep = "";
13581358
13591359
blob_zero(&x);
1360
- blob_append(&x, "(", 1);
1360
+ blob_append_sql(&x, "(");
13611361
for(i=0; ctrlSettings[i].name; i++){
1362
- blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1362
+ blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
13631363
zSep = ",";
13641364
}
1365
- blob_append(&x, ")", 1);
1366
- return blob_str(&x);
1365
+ blob_append_sql(&x, ")");
1366
+ return blob_sql_text(&x);
13671367
}
13681368
13691369
/*
13701370
** Fill an empty repository database with the basic information for a
13711371
** repository. This function is shared between 'create_repository_cmd'
@@ -2003,53 +2003,52 @@
20032003
** ckout:%s
20042004
**
20052005
** Where %s is the checkout root. The value is the repository file.
20062006
*/
20072007
void db_record_repository_filename(const char *zName){
2008
- const char *zCollation;
20092008
char *zRepoSetting;
20102009
char *zCkoutSetting;
20112010
Blob full;
20122011
if( zName==0 ){
20132012
if( !g.localOpen ) return;
20142013
zName = db_repository_filename();
20152014
}
20162015
file_canonical_name(zName, &full, 0);
2017
- zCollation = filename_collation();
2016
+ (void)filename_collation(); /* Initialize before connection swap */
20182017
db_swap_connections();
20192018
zRepoSetting = mprintf("repo:%q", blob_str(&full));
20202019
db_multi_exec(
2021
- "DELETE FROM global_config WHERE name %s = '%s';",
2022
- zCollation, zRepoSetting
2020
+ "DELETE FROM global_config WHERE name %s = %Q;",
2021
+ filename_collation(), zRepoSetting
20232022
);
20242023
db_multi_exec(
20252024
"INSERT OR IGNORE INTO global_config(name,value)"
2026
- "VALUES('%s',1);",
2025
+ "VALUES(%Q,1);",
20272026
zRepoSetting
20282027
);
20292028
fossil_free(zRepoSetting);
20302029
if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
20312030
Blob localRoot;
20322031
file_canonical_name(g.zLocalRoot, &localRoot, 1);
20332032
zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
20342033
db_multi_exec(
2035
- "DELETE FROM global_config WHERE name %s = '%s';",
2036
- zCollation, zCkoutSetting
2034
+ "DELETE FROM global_config WHERE name %s = %Q;",
2035
+ filename_collation(), zCkoutSetting
20372036
);
20382037
db_multi_exec(
20392038
"REPLACE INTO global_config(name, value)"
2040
- "VALUES('%s','%q');",
2039
+ "VALUES(%Q,%Q);",
20412040
zCkoutSetting, blob_str(&full)
20422041
);
20432042
db_swap_connections();
20442043
db_optional_sql("repository",
2045
- "DELETE FROM config WHERE name %s = '%s';",
2046
- zCollation, zCkoutSetting
2044
+ "DELETE FROM config WHERE name %s = %Q;",
2045
+ filename_collation(), zCkoutSetting
20472046
);
20482047
db_optional_sql("repository",
20492048
"REPLACE INTO config(name,value,mtime)"
2050
- "VALUES('%s',1,now());",
2049
+ "VALUES(%Q,1,now());",
20512050
zCkoutSetting
20522051
);
20532052
fossil_free(zCkoutSetting);
20542053
blob_reset(&localRoot);
20552054
}else{
@@ -2654,28 +2653,28 @@
26542653
zOrigSql += j+6;
26552654
j = -1;
26562655
}
26572656
}
26582657
blob_append(&newSql, zOrigSql, -1);
2659
- blob_appendf(&allSql,
2660
- "ALTER TABLE %s RENAME TO x_%s;\n"
2658
+ blob_append_sql(&allSql,
2659
+ "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
26612660
"%s WITHOUT ROWID;\n"
2662
- "INSERT INTO %s SELECT * FROM x_%s;\n"
2663
- "DROP TABLE x_%s;\n",
2664
- zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2661
+ "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2662
+ "DROP TABLE \"x_%w\";\n",
2663
+ zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
26652664
);
26662665
fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
26672666
blob_reset(&newSql);
26682667
}
2669
- blob_appendf(&allSql, "COMMIT;\n");
2668
+ blob_append_sql(&allSql, "COMMIT;\n");
26702669
db_finalize(&q);
26712670
if( dryRun ){
26722671
fossil_print("SQL that would have been evaluated:\n");
26732672
fossil_print("-------------------------------------------------------------\n");
2674
- fossil_print("%s", blob_str(&allSql));
2673
+ fossil_print("%s", blob_sql_text(&allSql));
26752674
}else{
2676
- db_multi_exec("%s", blob_str(&allSql));
2675
+ db_multi_exec("%s", blob_sql_text(&allSql));
26772676
}
26782677
blob_reset(&allSql);
26792678
db_close(1);
26802679
}
26812680
}
26822681
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err(sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err(sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %s", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name=='%s' /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = strglob(zPattern, zDef)==0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( !strglob("* isexe *", zVFileDef) ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( !strglob("* islink *", zVFileDef) ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>'%s'", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1330,17 +1330,17 @@
1330 "INSERT INTO config(name,value,mtime)"
1331 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1332 );
1333 }else{
1334 if( db_get("server-code", 0)==0 ) {
1335 db_optional_sql("repository",
1336 "INSERT INTO config(name,value,mtime)"
1337 " VALUES('server-code', lower(hex(randomblob(20))),now());"
1338 );
1339 }
1340 if( db_get("project-code", 0)==0 ) {
1341 db_optional_sql("repository",
1342 "INSERT INTO config(name,value,mtime)"
1343 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1344 );
1345 }
1346 }
@@ -1355,17 +1355,17 @@
1355 Blob x;
1356 int i;
1357 const char *zSep = "";
1358
1359 blob_zero(&x);
1360 blob_append(&x, "(", 1);
1361 for(i=0; ctrlSettings[i].name; i++){
1362 blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1363 zSep = ",";
1364 }
1365 blob_append(&x, ")", 1);
1366 return blob_str(&x);
1367 }
1368
1369 /*
1370 ** Fill an empty repository database with the basic information for a
1371 ** repository. This function is shared between 'create_repository_cmd'
@@ -2003,53 +2003,52 @@
2003 ** ckout:%s
2004 **
2005 ** Where %s is the checkout root. The value is the repository file.
2006 */
2007 void db_record_repository_filename(const char *zName){
2008 const char *zCollation;
2009 char *zRepoSetting;
2010 char *zCkoutSetting;
2011 Blob full;
2012 if( zName==0 ){
2013 if( !g.localOpen ) return;
2014 zName = db_repository_filename();
2015 }
2016 file_canonical_name(zName, &full, 0);
2017 zCollation = filename_collation();
2018 db_swap_connections();
2019 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2020 db_multi_exec(
2021 "DELETE FROM global_config WHERE name %s = '%s';",
2022 zCollation, zRepoSetting
2023 );
2024 db_multi_exec(
2025 "INSERT OR IGNORE INTO global_config(name,value)"
2026 "VALUES('%s',1);",
2027 zRepoSetting
2028 );
2029 fossil_free(zRepoSetting);
2030 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2031 Blob localRoot;
2032 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2033 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2034 db_multi_exec(
2035 "DELETE FROM global_config WHERE name %s = '%s';",
2036 zCollation, zCkoutSetting
2037 );
2038 db_multi_exec(
2039 "REPLACE INTO global_config(name, value)"
2040 "VALUES('%s','%q');",
2041 zCkoutSetting, blob_str(&full)
2042 );
2043 db_swap_connections();
2044 db_optional_sql("repository",
2045 "DELETE FROM config WHERE name %s = '%s';",
2046 zCollation, zCkoutSetting
2047 );
2048 db_optional_sql("repository",
2049 "REPLACE INTO config(name,value,mtime)"
2050 "VALUES('%s',1,now());",
2051 zCkoutSetting
2052 );
2053 fossil_free(zCkoutSetting);
2054 blob_reset(&localRoot);
2055 }else{
@@ -2654,28 +2653,28 @@
2654 zOrigSql += j+6;
2655 j = -1;
2656 }
2657 }
2658 blob_append(&newSql, zOrigSql, -1);
2659 blob_appendf(&allSql,
2660 "ALTER TABLE %s RENAME TO x_%s;\n"
2661 "%s WITHOUT ROWID;\n"
2662 "INSERT INTO %s SELECT * FROM x_%s;\n"
2663 "DROP TABLE x_%s;\n",
2664 zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2665 );
2666 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2667 blob_reset(&newSql);
2668 }
2669 blob_appendf(&allSql, "COMMIT;\n");
2670 db_finalize(&q);
2671 if( dryRun ){
2672 fossil_print("SQL that would have been evaluated:\n");
2673 fossil_print("-------------------------------------------------------------\n");
2674 fossil_print("%s", blob_str(&allSql));
2675 }else{
2676 db_multi_exec("%s", blob_str(&allSql));
2677 }
2678 blob_reset(&allSql);
2679 db_close(1);
2680 }
2681 }
2682
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err("%s", sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err("%s", sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %Q", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name==%Q /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = sqlite3_strglob(zPattern, zDef)!=0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>%Q", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1330,17 +1330,17 @@
1330 "INSERT INTO config(name,value,mtime)"
1331 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1332 );
1333 }else{
1334 if( db_get("server-code", 0)==0 ) {
1335 db_multi_exec(
1336 "INSERT INTO config(name,value,mtime)"
1337 " VALUES('server-code', lower(hex(randomblob(20))),now());"
1338 );
1339 }
1340 if( db_get("project-code", 0)==0 ) {
1341 db_multi_exec(
1342 "INSERT INTO config(name,value,mtime)"
1343 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1344 );
1345 }
1346 }
@@ -1355,17 +1355,17 @@
1355 Blob x;
1356 int i;
1357 const char *zSep = "";
1358
1359 blob_zero(&x);
1360 blob_append_sql(&x, "(");
1361 for(i=0; ctrlSettings[i].name; i++){
1362 blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
1363 zSep = ",";
1364 }
1365 blob_append_sql(&x, ")");
1366 return blob_sql_text(&x);
1367 }
1368
1369 /*
1370 ** Fill an empty repository database with the basic information for a
1371 ** repository. This function is shared between 'create_repository_cmd'
@@ -2003,53 +2003,52 @@
2003 ** ckout:%s
2004 **
2005 ** Where %s is the checkout root. The value is the repository file.
2006 */
2007 void db_record_repository_filename(const char *zName){
 
2008 char *zRepoSetting;
2009 char *zCkoutSetting;
2010 Blob full;
2011 if( zName==0 ){
2012 if( !g.localOpen ) return;
2013 zName = db_repository_filename();
2014 }
2015 file_canonical_name(zName, &full, 0);
2016 (void)filename_collation(); /* Initialize before connection swap */
2017 db_swap_connections();
2018 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2019 db_multi_exec(
2020 "DELETE FROM global_config WHERE name %s = %Q;",
2021 filename_collation(), zRepoSetting
2022 );
2023 db_multi_exec(
2024 "INSERT OR IGNORE INTO global_config(name,value)"
2025 "VALUES(%Q,1);",
2026 zRepoSetting
2027 );
2028 fossil_free(zRepoSetting);
2029 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2030 Blob localRoot;
2031 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2032 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2033 db_multi_exec(
2034 "DELETE FROM global_config WHERE name %s = %Q;",
2035 filename_collation(), zCkoutSetting
2036 );
2037 db_multi_exec(
2038 "REPLACE INTO global_config(name, value)"
2039 "VALUES(%Q,%Q);",
2040 zCkoutSetting, blob_str(&full)
2041 );
2042 db_swap_connections();
2043 db_optional_sql("repository",
2044 "DELETE FROM config WHERE name %s = %Q;",
2045 filename_collation(), zCkoutSetting
2046 );
2047 db_optional_sql("repository",
2048 "REPLACE INTO config(name,value,mtime)"
2049 "VALUES(%Q,1,now());",
2050 zCkoutSetting
2051 );
2052 fossil_free(zCkoutSetting);
2053 blob_reset(&localRoot);
2054 }else{
@@ -2654,28 +2653,28 @@
2653 zOrigSql += j+6;
2654 j = -1;
2655 }
2656 }
2657 blob_append(&newSql, zOrigSql, -1);
2658 blob_append_sql(&allSql,
2659 "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
2660 "%s WITHOUT ROWID;\n"
2661 "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2662 "DROP TABLE \"x_%w\";\n",
2663 zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
2664 );
2665 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2666 blob_reset(&newSql);
2667 }
2668 blob_append_sql(&allSql, "COMMIT;\n");
2669 db_finalize(&q);
2670 if( dryRun ){
2671 fossil_print("SQL that would have been evaluated:\n");
2672 fossil_print("-------------------------------------------------------------\n");
2673 fossil_print("%s", blob_sql_text(&allSql));
2674 }else{
2675 db_multi_exec("%s", blob_sql_text(&allSql));
2676 }
2677 blob_reset(&allSql);
2678 db_close(1);
2679 }
2680 }
2681
+34 -35
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177177
db.doRollback |= db.aHook[i].xHook();
178178
}
179179
while( db.pAllStmt ){
180180
db_finalize(db.pAllStmt);
181181
}
182
- db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
182
+ db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183183
db.doRollback = 0;
184184
}
185185
}
186186
187187
/*
@@ -664,17 +664,17 @@
664664
665665
db = db_open(zFileName);
666666
sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667667
rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668668
if( rc!=SQLITE_OK ){
669
- db_err(sqlite3_errmsg(db));
669
+ db_err("%s", sqlite3_errmsg(db));
670670
}
671671
va_start(ap, zSchema);
672672
while( (zSql = va_arg(ap, const char*))!=0 ){
673673
rc = sqlite3_exec(db, zSql, 0, 0, 0);
674674
if( rc!=SQLITE_OK ){
675
- db_err(sqlite3_errmsg(db));
675
+ db_err("%s", sqlite3_errmsg(db));
676676
}
677677
}
678678
va_end(ap);
679679
sqlite3_exec(db, "COMMIT", 0, 0, 0);
680680
sqlite3_close(db);
@@ -750,19 +750,19 @@
750750
751751
/*
752752
** Detaches the zLabel database.
753753
*/
754754
void db_detach(const char *zLabel){
755
- db_multi_exec("DETACH DATABASE %s", zLabel);
755
+ db_multi_exec("DETACH DATABASE %Q", zLabel);
756756
}
757757
758758
/*
759759
** zDbName is the name of a database file. Attach zDbName using
760760
** the name zLabel.
761761
*/
762762
void db_attach(const char *zDbName, const char *zLabel){
763
- db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
763
+ db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764764
}
765765
766766
/*
767767
** zDbName is the name of a database file. If no other database
768768
** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887887
static int db_local_table_exists_but_lacks_column(
888888
const char *zTable,
889889
const char *zColumn
890890
){
891891
char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892
- " WHERE name=='%s' /*scan*/",
892
+ " WHERE name==%Q /*scan*/",
893893
db_name("localdb"), zTable);
894894
int rc = 0;
895895
if( zDef ){
896896
char *zPattern = mprintf("* %s *", zColumn);
897
- rc = strglob(zPattern, zDef)==0;
897
+ rc = sqlite3_strglob(zPattern, zDef)!=0;
898898
fossil_free(zPattern);
899899
fossil_free(zDef);
900900
}
901901
return rc;
902902
}
@@ -919,19 +919,19 @@
919919
920920
/* If the "isexe" column is missing from the vfile table, then
921921
** add it now. This code added on 2010-03-06. After all users have
922922
** upgraded, this code can be safely deleted.
923923
*/
924
- if( !strglob("* isexe *", zVFileDef) ){
924
+ if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925925
db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926926
}
927927
928928
/* If "islink"/"isLink" columns are missing from tables, then
929929
** add them now. This code added on 2011-01-17 and 2011-08-27.
930930
** After all users have upgraded, this code can be safely deleted.
931931
*/
932
- if( !strglob("* islink *", zVFileDef) ){
932
+ if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933933
db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934934
if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935935
db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936936
}
937937
if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
11191119
** Return TRUE if the schema is out-of-date
11201120
*/
11211121
int db_schema_is_outofdate(void){
11221122
return db_exists("SELECT 1 FROM config"
11231123
" WHERE name='aux-schema'"
1124
- " AND value<>'%s'", AUX_SCHEMA);
1124
+ " AND value<>%Q", AUX_SCHEMA);
11251125
}
11261126
11271127
/*
11281128
** Return true if the database is writeable
11291129
*/
@@ -1330,17 +1330,17 @@
13301330
"INSERT INTO config(name,value,mtime)"
13311331
" VALUES('project-code', lower(hex(randomblob(20))),now());"
13321332
);
13331333
}else{
13341334
if( db_get("server-code", 0)==0 ) {
1335
- db_optional_sql("repository",
1335
+ db_multi_exec(
13361336
"INSERT INTO config(name,value,mtime)"
13371337
" VALUES('server-code', lower(hex(randomblob(20))),now());"
13381338
);
13391339
}
13401340
if( db_get("project-code", 0)==0 ) {
1341
- db_optional_sql("repository",
1341
+ db_multi_exec(
13421342
"INSERT INTO config(name,value,mtime)"
13431343
" VALUES('project-code', lower(hex(randomblob(20))),now());"
13441344
);
13451345
}
13461346
}
@@ -1355,17 +1355,17 @@
13551355
Blob x;
13561356
int i;
13571357
const char *zSep = "";
13581358
13591359
blob_zero(&x);
1360
- blob_append(&x, "(", 1);
1360
+ blob_append_sql(&x, "(");
13611361
for(i=0; ctrlSettings[i].name; i++){
1362
- blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1362
+ blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
13631363
zSep = ",";
13641364
}
1365
- blob_append(&x, ")", 1);
1366
- return blob_str(&x);
1365
+ blob_append_sql(&x, ")");
1366
+ return blob_sql_text(&x);
13671367
}
13681368
13691369
/*
13701370
** Fill an empty repository database with the basic information for a
13711371
** repository. This function is shared between 'create_repository_cmd'
@@ -2003,53 +2003,52 @@
20032003
** ckout:%s
20042004
**
20052005
** Where %s is the checkout root. The value is the repository file.
20062006
*/
20072007
void db_record_repository_filename(const char *zName){
2008
- const char *zCollation;
20092008
char *zRepoSetting;
20102009
char *zCkoutSetting;
20112010
Blob full;
20122011
if( zName==0 ){
20132012
if( !g.localOpen ) return;
20142013
zName = db_repository_filename();
20152014
}
20162015
file_canonical_name(zName, &full, 0);
2017
- zCollation = filename_collation();
2016
+ (void)filename_collation(); /* Initialize before connection swap */
20182017
db_swap_connections();
20192018
zRepoSetting = mprintf("repo:%q", blob_str(&full));
20202019
db_multi_exec(
2021
- "DELETE FROM global_config WHERE name %s = '%s';",
2022
- zCollation, zRepoSetting
2020
+ "DELETE FROM global_config WHERE name %s = %Q;",
2021
+ filename_collation(), zRepoSetting
20232022
);
20242023
db_multi_exec(
20252024
"INSERT OR IGNORE INTO global_config(name,value)"
2026
- "VALUES('%s',1);",
2025
+ "VALUES(%Q,1);",
20272026
zRepoSetting
20282027
);
20292028
fossil_free(zRepoSetting);
20302029
if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
20312030
Blob localRoot;
20322031
file_canonical_name(g.zLocalRoot, &localRoot, 1);
20332032
zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
20342033
db_multi_exec(
2035
- "DELETE FROM global_config WHERE name %s = '%s';",
2036
- zCollation, zCkoutSetting
2034
+ "DELETE FROM global_config WHERE name %s = %Q;",
2035
+ filename_collation(), zCkoutSetting
20372036
);
20382037
db_multi_exec(
20392038
"REPLACE INTO global_config(name, value)"
2040
- "VALUES('%s','%q');",
2039
+ "VALUES(%Q,%Q);",
20412040
zCkoutSetting, blob_str(&full)
20422041
);
20432042
db_swap_connections();
20442043
db_optional_sql("repository",
2045
- "DELETE FROM config WHERE name %s = '%s';",
2046
- zCollation, zCkoutSetting
2044
+ "DELETE FROM config WHERE name %s = %Q;",
2045
+ filename_collation(), zCkoutSetting
20472046
);
20482047
db_optional_sql("repository",
20492048
"REPLACE INTO config(name,value,mtime)"
2050
- "VALUES('%s',1,now());",
2049
+ "VALUES(%Q,1,now());",
20512050
zCkoutSetting
20522051
);
20532052
fossil_free(zCkoutSetting);
20542053
blob_reset(&localRoot);
20552054
}else{
@@ -2654,28 +2653,28 @@
26542653
zOrigSql += j+6;
26552654
j = -1;
26562655
}
26572656
}
26582657
blob_append(&newSql, zOrigSql, -1);
2659
- blob_appendf(&allSql,
2660
- "ALTER TABLE %s RENAME TO x_%s;\n"
2658
+ blob_append_sql(&allSql,
2659
+ "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
26612660
"%s WITHOUT ROWID;\n"
2662
- "INSERT INTO %s SELECT * FROM x_%s;\n"
2663
- "DROP TABLE x_%s;\n",
2664
- zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2661
+ "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2662
+ "DROP TABLE \"x_%w\";\n",
2663
+ zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
26652664
);
26662665
fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
26672666
blob_reset(&newSql);
26682667
}
2669
- blob_appendf(&allSql, "COMMIT;\n");
2668
+ blob_append_sql(&allSql, "COMMIT;\n");
26702669
db_finalize(&q);
26712670
if( dryRun ){
26722671
fossil_print("SQL that would have been evaluated:\n");
26732672
fossil_print("-------------------------------------------------------------\n");
2674
- fossil_print("%s", blob_str(&allSql));
2673
+ fossil_print("%s", blob_sql_text(&allSql));
26752674
}else{
2676
- db_multi_exec("%s", blob_str(&allSql));
2675
+ db_multi_exec("%s", blob_sql_text(&allSql));
26772676
}
26782677
blob_reset(&allSql);
26792678
db_close(1);
26802679
}
26812680
}
26822681
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err(sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err(sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %s", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name=='%s' /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = strglob(zPattern, zDef)==0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( !strglob("* isexe *", zVFileDef) ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( !strglob("* islink *", zVFileDef) ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>'%s'", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1330,17 +1330,17 @@
1330 "INSERT INTO config(name,value,mtime)"
1331 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1332 );
1333 }else{
1334 if( db_get("server-code", 0)==0 ) {
1335 db_optional_sql("repository",
1336 "INSERT INTO config(name,value,mtime)"
1337 " VALUES('server-code', lower(hex(randomblob(20))),now());"
1338 );
1339 }
1340 if( db_get("project-code", 0)==0 ) {
1341 db_optional_sql("repository",
1342 "INSERT INTO config(name,value,mtime)"
1343 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1344 );
1345 }
1346 }
@@ -1355,17 +1355,17 @@
1355 Blob x;
1356 int i;
1357 const char *zSep = "";
1358
1359 blob_zero(&x);
1360 blob_append(&x, "(", 1);
1361 for(i=0; ctrlSettings[i].name; i++){
1362 blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name);
1363 zSep = ",";
1364 }
1365 blob_append(&x, ")", 1);
1366 return blob_str(&x);
1367 }
1368
1369 /*
1370 ** Fill an empty repository database with the basic information for a
1371 ** repository. This function is shared between 'create_repository_cmd'
@@ -2003,53 +2003,52 @@
2003 ** ckout:%s
2004 **
2005 ** Where %s is the checkout root. The value is the repository file.
2006 */
2007 void db_record_repository_filename(const char *zName){
2008 const char *zCollation;
2009 char *zRepoSetting;
2010 char *zCkoutSetting;
2011 Blob full;
2012 if( zName==0 ){
2013 if( !g.localOpen ) return;
2014 zName = db_repository_filename();
2015 }
2016 file_canonical_name(zName, &full, 0);
2017 zCollation = filename_collation();
2018 db_swap_connections();
2019 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2020 db_multi_exec(
2021 "DELETE FROM global_config WHERE name %s = '%s';",
2022 zCollation, zRepoSetting
2023 );
2024 db_multi_exec(
2025 "INSERT OR IGNORE INTO global_config(name,value)"
2026 "VALUES('%s',1);",
2027 zRepoSetting
2028 );
2029 fossil_free(zRepoSetting);
2030 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2031 Blob localRoot;
2032 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2033 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2034 db_multi_exec(
2035 "DELETE FROM global_config WHERE name %s = '%s';",
2036 zCollation, zCkoutSetting
2037 );
2038 db_multi_exec(
2039 "REPLACE INTO global_config(name, value)"
2040 "VALUES('%s','%q');",
2041 zCkoutSetting, blob_str(&full)
2042 );
2043 db_swap_connections();
2044 db_optional_sql("repository",
2045 "DELETE FROM config WHERE name %s = '%s';",
2046 zCollation, zCkoutSetting
2047 );
2048 db_optional_sql("repository",
2049 "REPLACE INTO config(name,value,mtime)"
2050 "VALUES('%s',1,now());",
2051 zCkoutSetting
2052 );
2053 fossil_free(zCkoutSetting);
2054 blob_reset(&localRoot);
2055 }else{
@@ -2654,28 +2653,28 @@
2654 zOrigSql += j+6;
2655 j = -1;
2656 }
2657 }
2658 blob_append(&newSql, zOrigSql, -1);
2659 blob_appendf(&allSql,
2660 "ALTER TABLE %s RENAME TO x_%s;\n"
2661 "%s WITHOUT ROWID;\n"
2662 "INSERT INTO %s SELECT * FROM x_%s;\n"
2663 "DROP TABLE x_%s;\n",
2664 zTName, zTName, blob_str(&newSql), zTName, zTName, zTName
2665 );
2666 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2667 blob_reset(&newSql);
2668 }
2669 blob_appendf(&allSql, "COMMIT;\n");
2670 db_finalize(&q);
2671 if( dryRun ){
2672 fossil_print("SQL that would have been evaluated:\n");
2673 fossil_print("-------------------------------------------------------------\n");
2674 fossil_print("%s", blob_str(&allSql));
2675 }else{
2676 db_multi_exec("%s", blob_str(&allSql));
2677 }
2678 blob_reset(&allSql);
2679 db_close(1);
2680 }
2681 }
2682
--- src/db.c
+++ src/db.c
@@ -177,11 +177,11 @@
177 db.doRollback |= db.aHook[i].xHook();
178 }
179 while( db.pAllStmt ){
180 db_finalize(db.pAllStmt);
181 }
182 db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
183 db.doRollback = 0;
184 }
185 }
186
187 /*
@@ -664,17 +664,17 @@
664
665 db = db_open(zFileName);
666 sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
667 rc = sqlite3_exec(db, zSchema, 0, 0, 0);
668 if( rc!=SQLITE_OK ){
669 db_err("%s", sqlite3_errmsg(db));
670 }
671 va_start(ap, zSchema);
672 while( (zSql = va_arg(ap, const char*))!=0 ){
673 rc = sqlite3_exec(db, zSql, 0, 0, 0);
674 if( rc!=SQLITE_OK ){
675 db_err("%s", sqlite3_errmsg(db));
676 }
677 }
678 va_end(ap);
679 sqlite3_exec(db, "COMMIT", 0, 0, 0);
680 sqlite3_close(db);
@@ -750,19 +750,19 @@
750
751 /*
752 ** Detaches the zLabel database.
753 */
754 void db_detach(const char *zLabel){
755 db_multi_exec("DETACH DATABASE %Q", zLabel);
756 }
757
758 /*
759 ** zDbName is the name of a database file. Attach zDbName using
760 ** the name zLabel.
761 */
762 void db_attach(const char *zDbName, const char *zLabel){
763 db_multi_exec("ATTACH DATABASE %Q AS %Q", zDbName, zLabel);
764 }
765
766 /*
767 ** zDbName is the name of a database file. If no other database
768 ** file is open, then open this one. If another database file is
@@ -887,16 +887,16 @@
887 static int db_local_table_exists_but_lacks_column(
888 const char *zTable,
889 const char *zColumn
890 ){
891 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
892 " WHERE name==%Q /*scan*/",
893 db_name("localdb"), zTable);
894 int rc = 0;
895 if( zDef ){
896 char *zPattern = mprintf("* %s *", zColumn);
897 rc = sqlite3_strglob(zPattern, zDef)!=0;
898 fossil_free(zPattern);
899 fossil_free(zDef);
900 }
901 return rc;
902 }
@@ -919,19 +919,19 @@
919
920 /* If the "isexe" column is missing from the vfile table, then
921 ** add it now. This code added on 2010-03-06. After all users have
922 ** upgraded, this code can be safely deleted.
923 */
924 if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
925 db_multi_exec("ALTER TABLE vfile ADD COLUMN isexe BOOLEAN DEFAULT 0");
926 }
927
928 /* If "islink"/"isLink" columns are missing from tables, then
929 ** add them now. This code added on 2011-01-17 and 2011-08-27.
930 ** After all users have upgraded, this code can be safely deleted.
931 */
932 if( sqlite3_strglob("* islink *", zVFileDef)!=0 ){
933 db_multi_exec("ALTER TABLE vfile ADD COLUMN islink BOOLEAN DEFAULT 0");
934 if( db_local_table_exists_but_lacks_column("stashfile", "isLink") ){
935 db_multi_exec("ALTER TABLE stashfile ADD COLUMN isLink BOOL DEFAULT 0");
936 }
937 if( db_local_table_exists_but_lacks_column("undo", "isLink") ){
@@ -1119,11 +1119,11 @@
1119 ** Return TRUE if the schema is out-of-date
1120 */
1121 int db_schema_is_outofdate(void){
1122 return db_exists("SELECT 1 FROM config"
1123 " WHERE name='aux-schema'"
1124 " AND value<>%Q", AUX_SCHEMA);
1125 }
1126
1127 /*
1128 ** Return true if the database is writeable
1129 */
@@ -1330,17 +1330,17 @@
1330 "INSERT INTO config(name,value,mtime)"
1331 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1332 );
1333 }else{
1334 if( db_get("server-code", 0)==0 ) {
1335 db_multi_exec(
1336 "INSERT INTO config(name,value,mtime)"
1337 " VALUES('server-code', lower(hex(randomblob(20))),now());"
1338 );
1339 }
1340 if( db_get("project-code", 0)==0 ) {
1341 db_multi_exec(
1342 "INSERT INTO config(name,value,mtime)"
1343 " VALUES('project-code', lower(hex(randomblob(20))),now());"
1344 );
1345 }
1346 }
@@ -1355,17 +1355,17 @@
1355 Blob x;
1356 int i;
1357 const char *zSep = "";
1358
1359 blob_zero(&x);
1360 blob_append_sql(&x, "(");
1361 for(i=0; ctrlSettings[i].name; i++){
1362 blob_append_sql(&x, "%s%Q", zSep/*safe-for-%s*/, ctrlSettings[i].name);
1363 zSep = ",";
1364 }
1365 blob_append_sql(&x, ")");
1366 return blob_sql_text(&x);
1367 }
1368
1369 /*
1370 ** Fill an empty repository database with the basic information for a
1371 ** repository. This function is shared between 'create_repository_cmd'
@@ -2003,53 +2003,52 @@
2003 ** ckout:%s
2004 **
2005 ** Where %s is the checkout root. The value is the repository file.
2006 */
2007 void db_record_repository_filename(const char *zName){
 
2008 char *zRepoSetting;
2009 char *zCkoutSetting;
2010 Blob full;
2011 if( zName==0 ){
2012 if( !g.localOpen ) return;
2013 zName = db_repository_filename();
2014 }
2015 file_canonical_name(zName, &full, 0);
2016 (void)filename_collation(); /* Initialize before connection swap */
2017 db_swap_connections();
2018 zRepoSetting = mprintf("repo:%q", blob_str(&full));
2019 db_multi_exec(
2020 "DELETE FROM global_config WHERE name %s = %Q;",
2021 filename_collation(), zRepoSetting
2022 );
2023 db_multi_exec(
2024 "INSERT OR IGNORE INTO global_config(name,value)"
2025 "VALUES(%Q,1);",
2026 zRepoSetting
2027 );
2028 fossil_free(zRepoSetting);
2029 if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
2030 Blob localRoot;
2031 file_canonical_name(g.zLocalRoot, &localRoot, 1);
2032 zCkoutSetting = mprintf("ckout:%q", blob_str(&localRoot));
2033 db_multi_exec(
2034 "DELETE FROM global_config WHERE name %s = %Q;",
2035 filename_collation(), zCkoutSetting
2036 );
2037 db_multi_exec(
2038 "REPLACE INTO global_config(name, value)"
2039 "VALUES(%Q,%Q);",
2040 zCkoutSetting, blob_str(&full)
2041 );
2042 db_swap_connections();
2043 db_optional_sql("repository",
2044 "DELETE FROM config WHERE name %s = %Q;",
2045 filename_collation(), zCkoutSetting
2046 );
2047 db_optional_sql("repository",
2048 "REPLACE INTO config(name,value,mtime)"
2049 "VALUES(%Q,1,now());",
2050 zCkoutSetting
2051 );
2052 fossil_free(zCkoutSetting);
2053 blob_reset(&localRoot);
2054 }else{
@@ -2654,28 +2653,28 @@
2653 zOrigSql += j+6;
2654 j = -1;
2655 }
2656 }
2657 blob_append(&newSql, zOrigSql, -1);
2658 blob_append_sql(&allSql,
2659 "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
2660 "%s WITHOUT ROWID;\n"
2661 "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
2662 "DROP TABLE \"x_%w\";\n",
2663 zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
2664 );
2665 fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);
2666 blob_reset(&newSql);
2667 }
2668 blob_append_sql(&allSql, "COMMIT;\n");
2669 db_finalize(&q);
2670 if( dryRun ){
2671 fossil_print("SQL that would have been evaluated:\n");
2672 fossil_print("-------------------------------------------------------------\n");
2673 fossil_print("%s", blob_sql_text(&allSql));
2674 }else{
2675 db_multi_exec("%s", blob_sql_text(&allSql));
2676 }
2677 blob_reset(&allSql);
2678 db_close(1);
2679 }
2680 }
2681
+10 -10
--- src/delta.c
+++ src/delta.c
@@ -65,11 +65,11 @@
6565
** The "u32" type must be an unsigned 32-bit integer. Adjust this
6666
*/
6767
typedef unsigned int u32;
6868
6969
/*
70
-** Must be a 16-bit value
70
+** Must be a 16-bit value
7171
*/
7272
typedef short int s16;
7373
typedef unsigned short int u16;
7474
7575
#endif /* INTERFACE */
@@ -82,11 +82,11 @@
8282
8383
/*
8484
** The current state of the rolling hash.
8585
**
8686
** z[] holds the values that have been hashed. z[] is a circular buffer.
87
-** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
87
+** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
8888
** the window.
8989
**
9090
** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
9191
** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
9292
** (Each index for z[] should be module NHASH, of course. The %NHASH operator
@@ -135,11 +135,11 @@
135135
136136
/*
137137
** Write an base-64 integer into the given buffer.
138138
*/
139139
static void putInt(unsigned int v, char **pz){
140
- static const char zDigits[] =
140
+ static const char zDigits[] =
141141
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
142142
/* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
143143
int i, j;
144144
char zBuf[20];
145145
if( v==0 ){
@@ -229,11 +229,11 @@
229229
}
230230
231231
/*
232232
** Create a new delta.
233233
**
234
-** The delta is written into a preallocated buffer, zDelta, which
234
+** The delta is written into a preallocated buffer, zDelta, which
235235
** should be at least 60 bytes longer than the target file, zOut.
236236
** The delta string will be NUL-terminated, but it might also contain
237237
** embedded NUL characters if either the zSrc or zOut files are
238238
** binary. This function returns the length of the delta string
239239
** in bytes, excluding the final NUL terminator character.
@@ -245,11 +245,11 @@
245245
** delta file z, a program can compute the size of the output file
246246
** simply by reading the first line and decoding the base-64 number
247247
** found there. The delta_output_size() routine does exactly this.
248248
**
249249
** After the initial size number, the delta consists of a series of
250
-** literal text segments and commands to copy from the SOURCE file.
250
+** literal text segments and commands to copy from the SOURCE file.
251251
** A copy command looks like this:
252252
**
253253
** NNN@MMM,
254254
**
255255
** where NNN is the number of bytes to be copied and MMM is the offset
@@ -283,11 +283,11 @@
283283
** search for a matching section in the source file. When a match
284284
** is found, a copy command is added to the delta. An effort is
285285
** made to extend the matching section to regions that come before
286286
** and after the 16-byte hash window. A copy command is only issued
287287
** if the result would use less space that just quoting the text
288
-** literally. Literal text is added to the delta for sections that
288
+** literally. Literal text is added to the delta for sections that
289289
** do not match or which can not be encoded efficiently using copy
290290
** commands.
291291
*/
292292
int delta_create(
293293
const char *zSrc, /* The source or pattern file */
@@ -356,13 +356,13 @@
356356
hv = hash_32bit(&h) % nHash;
357357
DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
358358
iBlock = landmark[hv];
359359
while( iBlock>=0 && (limit--)>0 ){
360360
/*
361
- ** The hash window has identified a potential match against
361
+ ** The hash window has identified a potential match against
362362
** landmark block iBlock. But we need to investigate further.
363
- **
363
+ **
364364
** Look for a region in zOut that matches zSrc. Anchor the search
365365
** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
366366
** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
367367
**
368368
** Set cnt equal to the length of the match and set ofst so that
@@ -468,16 +468,16 @@
468468
}
469469
/* Output the final checksum record. */
470470
putInt(checksum(zOut, lenOut), &zDelta);
471471
*(zDelta++) = ';';
472472
fossil_free(collide);
473
- return zDelta - zOrigDelta;
473
+ return zDelta - zOrigDelta;
474474
}
475475
476476
/*
477477
** Return the size (in bytes) of the output from applying
478
-** a delta.
478
+** a delta.
479479
**
480480
** This routine is provided so that an procedure that is able
481481
** to call delta_apply() can learn how much space is required
482482
** for the output and hence allocate nor more space that is really
483483
** needed.
484484
--- src/delta.c
+++ src/delta.c
@@ -65,11 +65,11 @@
65 ** The "u32" type must be an unsigned 32-bit integer. Adjust this
66 */
67 typedef unsigned int u32;
68
69 /*
70 ** Must be a 16-bit value
71 */
72 typedef short int s16;
73 typedef unsigned short int u16;
74
75 #endif /* INTERFACE */
@@ -82,11 +82,11 @@
82
83 /*
84 ** The current state of the rolling hash.
85 **
86 ** z[] holds the values that have been hashed. z[] is a circular buffer.
87 ** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
88 ** the window.
89 **
90 ** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
91 ** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
92 ** (Each index for z[] should be module NHASH, of course. The %NHASH operator
@@ -135,11 +135,11 @@
135
136 /*
137 ** Write an base-64 integer into the given buffer.
138 */
139 static void putInt(unsigned int v, char **pz){
140 static const char zDigits[] =
141 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
142 /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
143 int i, j;
144 char zBuf[20];
145 if( v==0 ){
@@ -229,11 +229,11 @@
229 }
230
231 /*
232 ** Create a new delta.
233 **
234 ** The delta is written into a preallocated buffer, zDelta, which
235 ** should be at least 60 bytes longer than the target file, zOut.
236 ** The delta string will be NUL-terminated, but it might also contain
237 ** embedded NUL characters if either the zSrc or zOut files are
238 ** binary. This function returns the length of the delta string
239 ** in bytes, excluding the final NUL terminator character.
@@ -245,11 +245,11 @@
245 ** delta file z, a program can compute the size of the output file
246 ** simply by reading the first line and decoding the base-64 number
247 ** found there. The delta_output_size() routine does exactly this.
248 **
249 ** After the initial size number, the delta consists of a series of
250 ** literal text segments and commands to copy from the SOURCE file.
251 ** A copy command looks like this:
252 **
253 ** NNN@MMM,
254 **
255 ** where NNN is the number of bytes to be copied and MMM is the offset
@@ -283,11 +283,11 @@
283 ** search for a matching section in the source file. When a match
284 ** is found, a copy command is added to the delta. An effort is
285 ** made to extend the matching section to regions that come before
286 ** and after the 16-byte hash window. A copy command is only issued
287 ** if the result would use less space that just quoting the text
288 ** literally. Literal text is added to the delta for sections that
289 ** do not match or which can not be encoded efficiently using copy
290 ** commands.
291 */
292 int delta_create(
293 const char *zSrc, /* The source or pattern file */
@@ -356,13 +356,13 @@
356 hv = hash_32bit(&h) % nHash;
357 DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
358 iBlock = landmark[hv];
359 while( iBlock>=0 && (limit--)>0 ){
360 /*
361 ** The hash window has identified a potential match against
362 ** landmark block iBlock. But we need to investigate further.
363 **
364 ** Look for a region in zOut that matches zSrc. Anchor the search
365 ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
366 ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
367 **
368 ** Set cnt equal to the length of the match and set ofst so that
@@ -468,16 +468,16 @@
468 }
469 /* Output the final checksum record. */
470 putInt(checksum(zOut, lenOut), &zDelta);
471 *(zDelta++) = ';';
472 fossil_free(collide);
473 return zDelta - zOrigDelta;
474 }
475
476 /*
477 ** Return the size (in bytes) of the output from applying
478 ** a delta.
479 **
480 ** This routine is provided so that an procedure that is able
481 ** to call delta_apply() can learn how much space is required
482 ** for the output and hence allocate nor more space that is really
483 ** needed.
484
--- src/delta.c
+++ src/delta.c
@@ -65,11 +65,11 @@
65 ** The "u32" type must be an unsigned 32-bit integer. Adjust this
66 */
67 typedef unsigned int u32;
68
69 /*
70 ** Must be a 16-bit value
71 */
72 typedef short int s16;
73 typedef unsigned short int u16;
74
75 #endif /* INTERFACE */
@@ -82,11 +82,11 @@
82
83 /*
84 ** The current state of the rolling hash.
85 **
86 ** z[] holds the values that have been hashed. z[] is a circular buffer.
87 ** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
88 ** the window.
89 **
90 ** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
91 ** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
92 ** (Each index for z[] should be module NHASH, of course. The %NHASH operator
@@ -135,11 +135,11 @@
135
136 /*
137 ** Write an base-64 integer into the given buffer.
138 */
139 static void putInt(unsigned int v, char **pz){
140 static const char zDigits[] =
141 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
142 /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
143 int i, j;
144 char zBuf[20];
145 if( v==0 ){
@@ -229,11 +229,11 @@
229 }
230
231 /*
232 ** Create a new delta.
233 **
234 ** The delta is written into a preallocated buffer, zDelta, which
235 ** should be at least 60 bytes longer than the target file, zOut.
236 ** The delta string will be NUL-terminated, but it might also contain
237 ** embedded NUL characters if either the zSrc or zOut files are
238 ** binary. This function returns the length of the delta string
239 ** in bytes, excluding the final NUL terminator character.
@@ -245,11 +245,11 @@
245 ** delta file z, a program can compute the size of the output file
246 ** simply by reading the first line and decoding the base-64 number
247 ** found there. The delta_output_size() routine does exactly this.
248 **
249 ** After the initial size number, the delta consists of a series of
250 ** literal text segments and commands to copy from the SOURCE file.
251 ** A copy command looks like this:
252 **
253 ** NNN@MMM,
254 **
255 ** where NNN is the number of bytes to be copied and MMM is the offset
@@ -283,11 +283,11 @@
283 ** search for a matching section in the source file. When a match
284 ** is found, a copy command is added to the delta. An effort is
285 ** made to extend the matching section to regions that come before
286 ** and after the 16-byte hash window. A copy command is only issued
287 ** if the result would use less space that just quoting the text
288 ** literally. Literal text is added to the delta for sections that
289 ** do not match or which can not be encoded efficiently using copy
290 ** commands.
291 */
292 int delta_create(
293 const char *zSrc, /* The source or pattern file */
@@ -356,13 +356,13 @@
356 hv = hash_32bit(&h) % nHash;
357 DEBUG2( printf("LOOKING: %4d [%s]\n", base+i, print16(&zOut[base+i])); )
358 iBlock = landmark[hv];
359 while( iBlock>=0 && (limit--)>0 ){
360 /*
361 ** The hash window has identified a potential match against
362 ** landmark block iBlock. But we need to investigate further.
363 **
364 ** Look for a region in zOut that matches zSrc. Anchor the search
365 ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
366 ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
367 **
368 ** Set cnt equal to the length of the match and set ofst so that
@@ -468,16 +468,16 @@
468 }
469 /* Output the final checksum record. */
470 putInt(checksum(zOut, lenOut), &zDelta);
471 *(zDelta++) = ';';
472 fossil_free(collide);
473 return zDelta - zOrigDelta;
474 }
475
476 /*
477 ** Return the size (in bytes) of the output from applying
478 ** a delta.
479 **
480 ** This routine is provided so that an procedure that is able
481 ** to call delta_apply() can learn how much space is required
482 ** for the output and hence allocate nor more space that is really
483 ** needed.
484
+10 -10
--- src/descendants.c
+++ src/descendants.c
@@ -389,22 +389,22 @@
389389
verify_all_options();
390390
391391
if( recomputeFlag ) leaf_rebuild();
392392
blob_zero(&sql);
393393
blob_append(&sql, timeline_query_for_tty(), -1);
394
- blob_appendf(&sql, " AND blob.rid IN leaf");
394
+ blob_append_sql(&sql, " AND blob.rid IN leaf");
395395
if( showClosed ){
396
- blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
396
+ blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
397397
}else if( !showAll ){
398
- blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
398
+ blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
399399
}
400400
if( byBranch ){
401401
db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
402402
" event.mtime DESC",
403
- blob_str(&sql));
403
+ blob_sql_text(&sql));
404404
}else{
405
- db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
405
+ db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
406406
}
407407
blob_reset(&sql);
408408
n = 0;
409409
while( db_step(&q)==SQLITE_ROW ){
410410
const char *zId = db_column_text(&q, 1);
@@ -474,17 +474,17 @@
474474
}else{
475475
@ <h1>Open leaves:</h1>
476476
}
477477
blob_zero(&sql);
478478
blob_append(&sql, timeline_query_for_www(), -1);
479
- blob_appendf(&sql, " AND blob.rid IN leaf");
479
+ blob_append_sql(&sql, " AND blob.rid IN leaf");
480480
if( showClosed ){
481
- blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
481
+ blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
482482
}else if( !showAll ){
483
- blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
483
+ blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
484484
}
485
- db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
485
+ db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
486486
blob_reset(&sql);
487487
www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
488488
db_finalize(&q);
489489
@ <br />
490490
style_footer();
@@ -508,11 +508,11 @@
508508
Stmt q;
509509
int rid;
510510
511511
bag_init(&seen);
512512
bag_init(&pending);
513
- db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab);
513
+ db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab);
514514
db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
515515
while( db_step(&q)==SQLITE_ROW ){
516516
int mid = db_column_int(&q, 0);
517517
bag_insert(&pending, mid);
518518
bag_insert(&seen, mid);
519519
--- src/descendants.c
+++ src/descendants.c
@@ -389,22 +389,22 @@
389 verify_all_options();
390
391 if( recomputeFlag ) leaf_rebuild();
392 blob_zero(&sql);
393 blob_append(&sql, timeline_query_for_tty(), -1);
394 blob_appendf(&sql, " AND blob.rid IN leaf");
395 if( showClosed ){
396 blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
397 }else if( !showAll ){
398 blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
399 }
400 if( byBranch ){
401 db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
402 " event.mtime DESC",
403 blob_str(&sql));
404 }else{
405 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
406 }
407 blob_reset(&sql);
408 n = 0;
409 while( db_step(&q)==SQLITE_ROW ){
410 const char *zId = db_column_text(&q, 1);
@@ -474,17 +474,17 @@
474 }else{
475 @ <h1>Open leaves:</h1>
476 }
477 blob_zero(&sql);
478 blob_append(&sql, timeline_query_for_www(), -1);
479 blob_appendf(&sql, " AND blob.rid IN leaf");
480 if( showClosed ){
481 blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
482 }else if( !showAll ){
483 blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
484 }
485 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
486 blob_reset(&sql);
487 www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
488 db_finalize(&q);
489 @ <br />
490 style_footer();
@@ -508,11 +508,11 @@
508 Stmt q;
509 int rid;
510
511 bag_init(&seen);
512 bag_init(&pending);
513 db_prepare(&ins, "INSERT OR IGNORE INTO \"%s\" VALUES(:rid)", zTab);
514 db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
515 while( db_step(&q)==SQLITE_ROW ){
516 int mid = db_column_int(&q, 0);
517 bag_insert(&pending, mid);
518 bag_insert(&seen, mid);
519
--- src/descendants.c
+++ src/descendants.c
@@ -389,22 +389,22 @@
389 verify_all_options();
390
391 if( recomputeFlag ) leaf_rebuild();
392 blob_zero(&sql);
393 blob_append(&sql, timeline_query_for_tty(), -1);
394 blob_append_sql(&sql, " AND blob.rid IN leaf");
395 if( showClosed ){
396 blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
397 }else if( !showAll ){
398 blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
399 }
400 if( byBranch ){
401 db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
402 " event.mtime DESC",
403 blob_sql_text(&sql));
404 }else{
405 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
406 }
407 blob_reset(&sql);
408 n = 0;
409 while( db_step(&q)==SQLITE_ROW ){
410 const char *zId = db_column_text(&q, 1);
@@ -474,17 +474,17 @@
474 }else{
475 @ <h1>Open leaves:</h1>
476 }
477 blob_zero(&sql);
478 blob_append(&sql, timeline_query_for_www(), -1);
479 blob_append_sql(&sql, " AND blob.rid IN leaf");
480 if( showClosed ){
481 blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
482 }else if( !showAll ){
483 blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
484 }
485 db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
486 blob_reset(&sql);
487 www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
488 db_finalize(&q);
489 @ <br />
490 style_footer();
@@ -508,11 +508,11 @@
508 Stmt q;
509 int rid;
510
511 bag_init(&seen);
512 bag_init(&pending);
513 db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", zTab);
514 db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
515 while( db_step(&q)==SQLITE_ROW ){
516 int mid = db_column_int(&q, 0);
517 bag_insert(&pending, mid);
518 bag_insert(&seen, mid);
519
+11 -11
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -142,17 +142,17 @@
142142
Blob cmd; /* Text of command to run */
143143
144144
if( !fIncludeBinary ){
145145
Blob file2;
146146
if( isBin1 ){
147
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
147
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
148148
return;
149149
}
150150
if( zBinGlob ){
151151
Glob *pBinary = glob_create(zBinGlob);
152152
if( glob_match(pBinary, zName) ){
153
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
153
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
154154
glob_free(pBinary);
155155
return;
156156
}
157157
glob_free(pBinary);
158158
}
@@ -163,11 +163,11 @@
163163
}else{
164164
blob_read_from_file(&file2, zFile2);
165165
}
166166
}
167167
if( looks_like_binary(&file2) ){
168
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
168
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
169169
blob_reset(&file2);
170170
return;
171171
}
172172
blob_reset(&file2);
173173
}
@@ -238,17 +238,17 @@
238238
char zTemp1[300];
239239
char zTemp2[300];
240240
241241
if( !fIncludeBinary ){
242242
if( isBin1 || isBin2 ){
243
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
243
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
244244
return;
245245
}
246246
if( zBinGlob ){
247247
Glob *pBinary = glob_create(zBinGlob);
248248
if( glob_match(pBinary, zName) ){
249
- fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
249
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
250250
glob_free(pBinary);
251251
return;
252252
}
253253
glob_free(pBinary);
254254
}
@@ -302,11 +302,11 @@
302302
int isBin;
303303
file_tree_name(zFileTreeName, &fname, 1);
304304
historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305305
fIncludeBinary ? 0 : &isBin, 0);
306306
if( !isLink != !file_wd_islink(zFrom) ){
307
- fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
307
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
308308
}else{
309309
diff_file(&content, isBin, zFileTreeName, zFileTreeName,
310310
zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
311311
}
312312
blob_reset(&content);
@@ -346,11 +346,11 @@
346346
int rid = name_to_typed_rid(zFrom, "ci");
347347
if( !is_a_version(rid) ){
348348
fossil_fatal("no such check-in: %s", zFrom);
349349
}
350350
load_vfile_from_rid(rid);
351
- blob_appendf(&sql,
351
+ blob_append_sql(&sql,
352352
"SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
353353
" FROM vfile v1, vfile v2 "
354354
" WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
355355
" AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
356356
"UNION "
@@ -367,20 +367,20 @@
367367
" WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368368
" ORDER BY 1",
369369
rid, vid, rid, vid, vid, rid
370370
);
371371
}else{
372
- blob_appendf(&sql,
372
+ blob_append_sql(&sql,
373373
"SELECT pathname, deleted, chnged , rid==0, rid, islink"
374374
" FROM vfile"
375375
" WHERE vid=%d"
376376
" AND (deleted OR chnged OR rid==0)"
377377
" ORDER BY pathname",
378378
vid
379379
);
380380
}
381
- db_prepare(&q, blob_str(&sql));
381
+ db_prepare(&q, "%s", blob_sql_text(&sql));
382382
while( db_step(&q)==SQLITE_ROW ){
383383
const char *zPathname = db_column_text(&q,0);
384384
int isDeleted = db_column_int(&q, 1);
385385
int isChnged = db_column_int(&q,2);
386386
int isNew = db_column_int(&q,3);
@@ -408,11 +408,11 @@
408408
Blob content;
409409
int isBin;
410410
if( !isLink != !file_wd_islink(zFullName) ){
411411
diff_print_index(zPathname, diffFlags);
412412
diff_print_filenames(zPathname, zPathname, diffFlags);
413
- fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
413
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
414414
continue;
415415
}
416416
if( srcid>0 ){
417417
content_get(srcid, &content);
418418
}else{
@@ -462,11 +462,11 @@
462462
fIncludeBinary ? 0 : &isBin1, 0);
463463
historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464464
fIncludeBinary ? 0 : &isBin2, 0);
465465
if( isLink1 != isLink2 ){
466466
diff_print_filenames(zName, zName, diffFlags);
467
- fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
467
+ fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
468468
}else{
469469
diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
470470
zBinGlob, fIncludeBinary, diffFlags);
471471
}
472472
blob_reset(&v1);
473473
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -142,17 +142,17 @@
142 Blob cmd; /* Text of command to run */
143
144 if( !fIncludeBinary ){
145 Blob file2;
146 if( isBin1 ){
147 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
148 return;
149 }
150 if( zBinGlob ){
151 Glob *pBinary = glob_create(zBinGlob);
152 if( glob_match(pBinary, zName) ){
153 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
154 glob_free(pBinary);
155 return;
156 }
157 glob_free(pBinary);
158 }
@@ -163,11 +163,11 @@
163 }else{
164 blob_read_from_file(&file2, zFile2);
165 }
166 }
167 if( looks_like_binary(&file2) ){
168 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
169 blob_reset(&file2);
170 return;
171 }
172 blob_reset(&file2);
173 }
@@ -238,17 +238,17 @@
238 char zTemp1[300];
239 char zTemp2[300];
240
241 if( !fIncludeBinary ){
242 if( isBin1 || isBin2 ){
243 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
244 return;
245 }
246 if( zBinGlob ){
247 Glob *pBinary = glob_create(zBinGlob);
248 if( glob_match(pBinary, zName) ){
249 fossil_print(DIFF_CANNOT_COMPUTE_BINARY);
250 glob_free(pBinary);
251 return;
252 }
253 glob_free(pBinary);
254 }
@@ -302,11 +302,11 @@
302 int isBin;
303 file_tree_name(zFileTreeName, &fname, 1);
304 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305 fIncludeBinary ? 0 : &isBin, 0);
306 if( !isLink != !file_wd_islink(zFrom) ){
307 fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
308 }else{
309 diff_file(&content, isBin, zFileTreeName, zFileTreeName,
310 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
311 }
312 blob_reset(&content);
@@ -346,11 +346,11 @@
346 int rid = name_to_typed_rid(zFrom, "ci");
347 if( !is_a_version(rid) ){
348 fossil_fatal("no such check-in: %s", zFrom);
349 }
350 load_vfile_from_rid(rid);
351 blob_appendf(&sql,
352 "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
353 " FROM vfile v1, vfile v2 "
354 " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
355 " AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
356 "UNION "
@@ -367,20 +367,20 @@
367 " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368 " ORDER BY 1",
369 rid, vid, rid, vid, vid, rid
370 );
371 }else{
372 blob_appendf(&sql,
373 "SELECT pathname, deleted, chnged , rid==0, rid, islink"
374 " FROM vfile"
375 " WHERE vid=%d"
376 " AND (deleted OR chnged OR rid==0)"
377 " ORDER BY pathname",
378 vid
379 );
380 }
381 db_prepare(&q, blob_str(&sql));
382 while( db_step(&q)==SQLITE_ROW ){
383 const char *zPathname = db_column_text(&q,0);
384 int isDeleted = db_column_int(&q, 1);
385 int isChnged = db_column_int(&q,2);
386 int isNew = db_column_int(&q,3);
@@ -408,11 +408,11 @@
408 Blob content;
409 int isBin;
410 if( !isLink != !file_wd_islink(zFullName) ){
411 diff_print_index(zPathname, diffFlags);
412 diff_print_filenames(zPathname, zPathname, diffFlags);
413 fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
414 continue;
415 }
416 if( srcid>0 ){
417 content_get(srcid, &content);
418 }else{
@@ -462,11 +462,11 @@
462 fIncludeBinary ? 0 : &isBin1, 0);
463 historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464 fIncludeBinary ? 0 : &isBin2, 0);
465 if( isLink1 != isLink2 ){
466 diff_print_filenames(zName, zName, diffFlags);
467 fossil_print(DIFF_CANNOT_COMPUTE_SYMLINK);
468 }else{
469 diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
470 zBinGlob, fIncludeBinary, diffFlags);
471 }
472 blob_reset(&v1);
473
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -142,17 +142,17 @@
142 Blob cmd; /* Text of command to run */
143
144 if( !fIncludeBinary ){
145 Blob file2;
146 if( isBin1 ){
147 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
148 return;
149 }
150 if( zBinGlob ){
151 Glob *pBinary = glob_create(zBinGlob);
152 if( glob_match(pBinary, zName) ){
153 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
154 glob_free(pBinary);
155 return;
156 }
157 glob_free(pBinary);
158 }
@@ -163,11 +163,11 @@
163 }else{
164 blob_read_from_file(&file2, zFile2);
165 }
166 }
167 if( looks_like_binary(&file2) ){
168 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
169 blob_reset(&file2);
170 return;
171 }
172 blob_reset(&file2);
173 }
@@ -238,17 +238,17 @@
238 char zTemp1[300];
239 char zTemp2[300];
240
241 if( !fIncludeBinary ){
242 if( isBin1 || isBin2 ){
243 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
244 return;
245 }
246 if( zBinGlob ){
247 Glob *pBinary = glob_create(zBinGlob);
248 if( glob_match(pBinary, zName) ){
249 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
250 glob_free(pBinary);
251 return;
252 }
253 glob_free(pBinary);
254 }
@@ -302,11 +302,11 @@
302 int isBin;
303 file_tree_name(zFileTreeName, &fname, 1);
304 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305 fIncludeBinary ? 0 : &isBin, 0);
306 if( !isLink != !file_wd_islink(zFrom) ){
307 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
308 }else{
309 diff_file(&content, isBin, zFileTreeName, zFileTreeName,
310 zDiffCmd, zBinGlob, fIncludeBinary, diffFlags);
311 }
312 blob_reset(&content);
@@ -346,11 +346,11 @@
346 int rid = name_to_typed_rid(zFrom, "ci");
347 if( !is_a_version(rid) ){
348 fossil_fatal("no such check-in: %s", zFrom);
349 }
350 load_vfile_from_rid(rid);
351 blob_append_sql(&sql,
352 "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid, v1.islink"
353 " FROM vfile v1, vfile v2 "
354 " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d"
355 " AND (v2.deleted OR v2.chnged OR v1.mrid!=v2.rid)"
356 "UNION "
@@ -367,20 +367,20 @@
367 " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368 " ORDER BY 1",
369 rid, vid, rid, vid, vid, rid
370 );
371 }else{
372 blob_append_sql(&sql,
373 "SELECT pathname, deleted, chnged , rid==0, rid, islink"
374 " FROM vfile"
375 " WHERE vid=%d"
376 " AND (deleted OR chnged OR rid==0)"
377 " ORDER BY pathname",
378 vid
379 );
380 }
381 db_prepare(&q, "%s", blob_sql_text(&sql));
382 while( db_step(&q)==SQLITE_ROW ){
383 const char *zPathname = db_column_text(&q,0);
384 int isDeleted = db_column_int(&q, 1);
385 int isChnged = db_column_int(&q,2);
386 int isNew = db_column_int(&q,3);
@@ -408,11 +408,11 @@
408 Blob content;
409 int isBin;
410 if( !isLink != !file_wd_islink(zFullName) ){
411 diff_print_index(zPathname, diffFlags);
412 diff_print_filenames(zPathname, zPathname, diffFlags);
413 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
414 continue;
415 }
416 if( srcid>0 ){
417 content_get(srcid, &content);
418 }else{
@@ -462,11 +462,11 @@
462 fIncludeBinary ? 0 : &isBin1, 0);
463 historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464 fIncludeBinary ? 0 : &isBin2, 0);
465 if( isLink1 != isLink2 ){
466 diff_print_filenames(zName, zName, diffFlags);
467 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
468 }else{
469 diff_file_mem(&v1, &v2, isBin1, isBin2, zName, zDiffCmd,
470 zBinGlob, fIncludeBinary, diffFlags);
471 }
472 blob_reset(&v1);
473
+69 -71
--- src/doc.c
+++ src/doc.c
@@ -26,11 +26,11 @@
2626
** Try to guess the mimetype from content.
2727
**
2828
** If the content is pure text, return NULL.
2929
**
3030
** For image types, attempt to return an appropriate mimetype
31
-** name like "image/gif" or "image/jpeg".
31
+** name like "image/gif" or "image/jpeg".
3232
**
3333
** For any other binary type, return "unknown/unknown".
3434
*/
3535
const char *mimetype_from_content(Blob *pBlob){
3636
int i;
@@ -83,11 +83,11 @@
8383
int i;
8484
int first, last;
8585
int len;
8686
char zSuffix[20];
8787
88
- /* A table of mimetypes based on file suffixes.
88
+ /* A table of mimetypes based on file suffixes.
8989
** Suffixes must be in sorted order so that we can do a binary
9090
** search to find the mime-type
9191
*/
9292
static const struct {
9393
const char *zSuffix; /* The file suffix */
@@ -487,11 +487,11 @@
487487
db_end_transaction(0);
488488
}
489489
blob_to_utf8_no_bom(&filebody, 0);
490490
491491
/* The file is now contained in the filebody blob. Deliver the
492
- ** file to the user
492
+ ** file to the user
493493
*/
494494
zMime = P("mimetype");
495495
if( zMime==0 ){
496496
zMime = mimetype_from_name(zName);
497497
}
@@ -501,11 +501,11 @@
501501
Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
502502
" WHERE objid=%d AND type='ci'", vid));
503503
if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
504504
Blob title, tail;
505505
if( wiki_find_title(&filebody, &title, &tail) ){
506
- style_header(blob_str(&title));
506
+ style_header("%s", blob_str(&title));
507507
wiki_convert(&tail, 0, WIKI_BUTTONS);
508508
}else{
509509
style_header("Documentation");
510510
wiki_convert(&filebody, 0, WIKI_BUTTONS);
511511
}
@@ -513,11 +513,11 @@
513513
}else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
514514
Blob title = BLOB_INITIALIZER;
515515
Blob tail = BLOB_INITIALIZER;
516516
markdown_to_html(&filebody, &title, &tail);
517517
if( blob_size(&title)>0 ){
518
- style_header(blob_str(&title));
518
+ style_header("%s", blob_str(&title));
519519
}else{
520520
style_header("Documentation");
521521
}
522522
blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
523523
style_footer();
@@ -528,15 +528,13 @@
528528
@ </pre></blockquote>
529529
style_footer();
530530
#ifdef FOSSIL_ENABLE_TH1_DOCS
531531
}else if( db_get_boolean("th1-docs", 0) &&
532532
fossil_strcmp(zMime, "application/x-th1")==0 ){
533
- char *zHtml = htmlize(zName, -1);
534
- style_header(zHtml);
533
+ style_header("%h", zName);
535534
Th_Render(blob_str(&filebody));
536535
style_footer();
537
- fossil_free(zHtml);
538536
#endif
539537
}else{
540538
cgi_set_content_type(zMime);
541539
cgi_set_content(&filebody);
542540
}
@@ -546,79 +544,79 @@
546544
/* Jump here when unable to locate the document */
547545
db_end_transaction(0);
548546
style_header("Document Not Found");
549547
@ <p>No such document: %h(zName)</p>
550548
style_footer();
551
- return;
549
+ return;
552550
}
553551
554552
/*
555553
** The default logo.
556554
*/
557555
static const unsigned char aLogo[] = {
558
- 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
559
- 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
560
- 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
561
- 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
562
- 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
563
- 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
564
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
565
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
566
- 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
567
- 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
568
- 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
569
- 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
570
- 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
571
- 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
572
- 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
573
- 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
574
- 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
575
- 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
576
- 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
577
- 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
578
- 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
579
- 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
580
- 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
581
- 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
582
- 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
583
- 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
584
- 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
585
- 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
586
- 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
587
- 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
588
- 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
589
- 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
590
- 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
591
- 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
592
- 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
593
- 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
594
- 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
595
- 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
596
- 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
597
- 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
598
- 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
599
- 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
600
- 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
601
- 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
602
- 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
603
- 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
604
- 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
605
- 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
606
- 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
607
- 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
608
- 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
609
- 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
610
- 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
611
- 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
612
- 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
613
- 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
614
- 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
615
- 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
616
- 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
617
- 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
618
- 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
619
- 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
556
+ 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
557
+ 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
558
+ 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
559
+ 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
560
+ 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
561
+ 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
562
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
564
+ 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
565
+ 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
566
+ 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
567
+ 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
568
+ 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
569
+ 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
570
+ 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
571
+ 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
572
+ 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
573
+ 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
574
+ 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
575
+ 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
576
+ 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
577
+ 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
578
+ 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
579
+ 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
580
+ 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
581
+ 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
582
+ 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
583
+ 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
584
+ 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
585
+ 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
586
+ 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
587
+ 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
588
+ 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
589
+ 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
590
+ 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
591
+ 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
592
+ 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
593
+ 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
594
+ 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
595
+ 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
596
+ 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
597
+ 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
598
+ 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
599
+ 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
600
+ 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
601
+ 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
602
+ 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
603
+ 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
604
+ 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
605
+ 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
606
+ 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
607
+ 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
608
+ 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
609
+ 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
610
+ 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
611
+ 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
612
+ 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
613
+ 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
614
+ 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
615
+ 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
616
+ 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
617
+ 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
620618
};
621619
622620
/*
623621
** WEBPAGE: logo
624622
**
625623
--- src/doc.c
+++ src/doc.c
@@ -26,11 +26,11 @@
26 ** Try to guess the mimetype from content.
27 **
28 ** If the content is pure text, return NULL.
29 **
30 ** For image types, attempt to return an appropriate mimetype
31 ** name like "image/gif" or "image/jpeg".
32 **
33 ** For any other binary type, return "unknown/unknown".
34 */
35 const char *mimetype_from_content(Blob *pBlob){
36 int i;
@@ -83,11 +83,11 @@
83 int i;
84 int first, last;
85 int len;
86 char zSuffix[20];
87
88 /* A table of mimetypes based on file suffixes.
89 ** Suffixes must be in sorted order so that we can do a binary
90 ** search to find the mime-type
91 */
92 static const struct {
93 const char *zSuffix; /* The file suffix */
@@ -487,11 +487,11 @@
487 db_end_transaction(0);
488 }
489 blob_to_utf8_no_bom(&filebody, 0);
490
491 /* The file is now contained in the filebody blob. Deliver the
492 ** file to the user
493 */
494 zMime = P("mimetype");
495 if( zMime==0 ){
496 zMime = mimetype_from_name(zName);
497 }
@@ -501,11 +501,11 @@
501 Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
502 " WHERE objid=%d AND type='ci'", vid));
503 if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
504 Blob title, tail;
505 if( wiki_find_title(&filebody, &title, &tail) ){
506 style_header(blob_str(&title));
507 wiki_convert(&tail, 0, WIKI_BUTTONS);
508 }else{
509 style_header("Documentation");
510 wiki_convert(&filebody, 0, WIKI_BUTTONS);
511 }
@@ -513,11 +513,11 @@
513 }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
514 Blob title = BLOB_INITIALIZER;
515 Blob tail = BLOB_INITIALIZER;
516 markdown_to_html(&filebody, &title, &tail);
517 if( blob_size(&title)>0 ){
518 style_header(blob_str(&title));
519 }else{
520 style_header("Documentation");
521 }
522 blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
523 style_footer();
@@ -528,15 +528,13 @@
528 @ </pre></blockquote>
529 style_footer();
530 #ifdef FOSSIL_ENABLE_TH1_DOCS
531 }else if( db_get_boolean("th1-docs", 0) &&
532 fossil_strcmp(zMime, "application/x-th1")==0 ){
533 char *zHtml = htmlize(zName, -1);
534 style_header(zHtml);
535 Th_Render(blob_str(&filebody));
536 style_footer();
537 fossil_free(zHtml);
538 #endif
539 }else{
540 cgi_set_content_type(zMime);
541 cgi_set_content(&filebody);
542 }
@@ -546,79 +544,79 @@
546 /* Jump here when unable to locate the document */
547 db_end_transaction(0);
548 style_header("Document Not Found");
549 @ <p>No such document: %h(zName)</p>
550 style_footer();
551 return;
552 }
553
554 /*
555 ** The default logo.
556 */
557 static const unsigned char aLogo[] = {
558 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
559 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
560 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
561 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
562 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
563 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
564 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
565 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
566 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
567 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
568 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
569 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
570 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
571 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
572 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
573 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
574 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
575 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
576 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
577 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
578 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
579 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
580 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
581 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
582 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
583 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
584 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
585 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
586 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
587 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
588 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
589 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
590 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
591 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
592 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
593 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
594 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
595 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
596 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
597 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
598 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
599 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
600 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
601 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
602 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
603 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
604 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
605 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
606 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
607 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
608 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
609 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
610 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
611 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
612 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
613 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
614 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
615 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
616 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
617 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
618 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
619 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
620 };
621
622 /*
623 ** WEBPAGE: logo
624 **
625
--- src/doc.c
+++ src/doc.c
@@ -26,11 +26,11 @@
26 ** Try to guess the mimetype from content.
27 **
28 ** If the content is pure text, return NULL.
29 **
30 ** For image types, attempt to return an appropriate mimetype
31 ** name like "image/gif" or "image/jpeg".
32 **
33 ** For any other binary type, return "unknown/unknown".
34 */
35 const char *mimetype_from_content(Blob *pBlob){
36 int i;
@@ -83,11 +83,11 @@
83 int i;
84 int first, last;
85 int len;
86 char zSuffix[20];
87
88 /* A table of mimetypes based on file suffixes.
89 ** Suffixes must be in sorted order so that we can do a binary
90 ** search to find the mime-type
91 */
92 static const struct {
93 const char *zSuffix; /* The file suffix */
@@ -487,11 +487,11 @@
487 db_end_transaction(0);
488 }
489 blob_to_utf8_no_bom(&filebody, 0);
490
491 /* The file is now contained in the filebody blob. Deliver the
492 ** file to the user
493 */
494 zMime = P("mimetype");
495 if( zMime==0 ){
496 zMime = mimetype_from_name(zName);
497 }
@@ -501,11 +501,11 @@
501 Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
502 " WHERE objid=%d AND type='ci'", vid));
503 if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
504 Blob title, tail;
505 if( wiki_find_title(&filebody, &title, &tail) ){
506 style_header("%s", blob_str(&title));
507 wiki_convert(&tail, 0, WIKI_BUTTONS);
508 }else{
509 style_header("Documentation");
510 wiki_convert(&filebody, 0, WIKI_BUTTONS);
511 }
@@ -513,11 +513,11 @@
513 }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
514 Blob title = BLOB_INITIALIZER;
515 Blob tail = BLOB_INITIALIZER;
516 markdown_to_html(&filebody, &title, &tail);
517 if( blob_size(&title)>0 ){
518 style_header("%s", blob_str(&title));
519 }else{
520 style_header("Documentation");
521 }
522 blob_append(cgi_output_blob(), blob_buffer(&tail), blob_size(&tail));
523 style_footer();
@@ -528,15 +528,13 @@
528 @ </pre></blockquote>
529 style_footer();
530 #ifdef FOSSIL_ENABLE_TH1_DOCS
531 }else if( db_get_boolean("th1-docs", 0) &&
532 fossil_strcmp(zMime, "application/x-th1")==0 ){
533 style_header("%h", zName);
 
534 Th_Render(blob_str(&filebody));
535 style_footer();
 
536 #endif
537 }else{
538 cgi_set_content_type(zMime);
539 cgi_set_content(&filebody);
540 }
@@ -546,79 +544,79 @@
544 /* Jump here when unable to locate the document */
545 db_end_transaction(0);
546 style_header("Document Not Found");
547 @ <p>No such document: %h(zName)</p>
548 style_footer();
549 return;
550 }
551
552 /*
553 ** The default logo.
554 */
555 static const unsigned char aLogo[] = {
556 71, 73, 70, 56, 55, 97, 62, 0, 71, 0, 244, 0, 0, 85,
557 129, 149, 95, 136, 155, 99, 139, 157, 106, 144, 162, 113, 150, 166,
558 116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
559 195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
560 215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
561 233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255, 0, 0,
562 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
564 0, 0, 62, 0, 71, 0, 0, 5, 255, 96, 100, 141, 100, 105,
565 158, 168, 37, 41, 132, 192, 164, 112, 44, 207, 102, 99, 0, 56,
566 16, 84, 116, 239, 199, 141, 65, 110, 232, 248, 25, 141, 193, 161,
567 82, 113, 108, 202, 32, 55, 229, 210, 73, 61, 41, 164, 88, 102,
568 181, 10, 41, 96, 179, 91, 106, 35, 240, 5, 135, 143, 137, 242,
569 87, 123, 246, 33, 190, 81, 108, 163, 237, 198, 14, 30, 113, 233,
570 131, 78, 115, 72, 11, 115, 87, 101, 19, 124, 51, 66, 74, 8,
571 19, 16, 67, 100, 74, 133, 50, 15, 101, 135, 56, 11, 74, 6,
572 143, 49, 126, 106, 56, 8, 145, 67, 9, 152, 48, 139, 155, 5,
573 22, 13, 74, 115, 161, 41, 147, 101, 13, 130, 57, 132, 170, 40,
574 167, 155, 0, 94, 57, 3, 178, 48, 183, 181, 57, 160, 186, 40,
575 19, 141, 189, 0, 69, 192, 40, 16, 195, 155, 185, 199, 41, 201,
576 189, 191, 205, 193, 188, 131, 210, 49, 175, 88, 209, 214, 38, 19,
577 3, 11, 19, 111, 127, 60, 219, 39, 55, 204, 19, 11, 6, 100,
578 5, 10, 227, 228, 37, 163, 0, 239, 117, 56, 238, 243, 49, 195,
579 177, 247, 48, 158, 56, 251, 50, 216, 254, 197, 56, 128, 107, 158,
580 2, 125, 171, 114, 92, 218, 246, 96, 66, 3, 4, 50, 134, 176,
581 145, 6, 97, 64, 144, 24, 19, 136, 108, 91, 177, 160, 0, 194,
582 19, 253, 0, 216, 107, 214, 224, 192, 129, 5, 16, 83, 255, 244,
583 43, 213, 195, 24, 159, 27, 169, 64, 230, 88, 208, 227, 129, 182,
584 54, 4, 89, 158, 24, 181, 163, 199, 1, 155, 52, 233, 8, 130,
585 176, 83, 24, 128, 137, 50, 18, 32, 48, 48, 114, 11, 173, 137,
586 19, 110, 4, 64, 105, 1, 194, 30, 140, 68, 15, 24, 24, 224,
587 50, 76, 70, 0, 11, 171, 54, 26, 160, 181, 194, 149, 148, 40,
588 174, 148, 122, 64, 180, 208, 161, 17, 207, 112, 164, 1, 128, 96,
589 148, 78, 18, 21, 194, 33, 229, 51, 247, 65, 133, 97, 5, 250,
590 69, 229, 100, 34, 220, 128, 166, 116, 190, 62, 8, 167, 195, 170,
591 47, 163, 0, 130, 90, 152, 11, 160, 173, 170, 27, 154, 26, 91,
592 232, 151, 171, 18, 14, 162, 253, 98, 170, 18, 70, 171, 64, 219,
593 10, 67, 136, 134, 187, 116, 75, 180, 46, 179, 174, 135, 4, 189,
594 229, 231, 78, 40, 10, 62, 226, 164, 172, 64, 240, 167, 170, 10,
595 18, 124, 188, 10, 107, 65, 193, 94, 11, 93, 171, 28, 248, 17,
596 239, 46, 140, 78, 97, 34, 25, 153, 36, 99, 65, 130, 7, 203,
597 183, 168, 51, 34, 136, 25, 140, 10, 6, 16, 28, 255, 145, 241,
598 230, 140, 10, 66, 178, 167, 112, 48, 192, 128, 129, 9, 31, 141,
599 84, 138, 63, 163, 162, 2, 203, 206, 240, 56, 55, 98, 192, 188,
600 15, 185, 50, 160, 6, 0, 125, 62, 33, 214, 195, 33, 5, 24,
601 184, 25, 231, 14, 201, 245, 144, 23, 126, 104, 228, 0, 145, 2,
602 13, 140, 244, 212, 17, 21, 20, 176, 159, 17, 95, 225, 160, 128,
603 16, 1, 32, 224, 142, 32, 227, 125, 87, 64, 0, 16, 54, 129,
604 205, 2, 141, 76, 53, 130, 103, 37, 166, 64, 144, 107, 78, 196,
605 5, 192, 0, 54, 50, 229, 9, 141, 49, 84, 194, 35, 12, 196,
606 153, 48, 192, 137, 57, 84, 24, 7, 87, 159, 249, 240, 215, 143,
607 105, 241, 118, 149, 9, 139, 4, 64, 203, 141, 35, 140, 129, 131,
608 16, 222, 125, 231, 128, 2, 238, 17, 152, 66, 3, 5, 56, 224,
609 159, 103, 16, 76, 25, 75, 5, 11, 164, 215, 96, 9, 14, 16,
610 36, 225, 15, 11, 40, 144, 192, 156, 41, 10, 178, 199, 3, 66,
611 64, 80, 193, 3, 124, 90, 48, 129, 129, 102, 177, 18, 192, 154,
612 49, 84, 240, 208, 92, 22, 149, 96, 39, 9, 31, 74, 17, 94,
613 3, 8, 177, 199, 72, 59, 85, 76, 25, 216, 8, 139, 194, 197,
614 138, 163, 69, 96, 115, 0, 147, 72, 72, 84, 28, 14, 79, 86,
615 233, 230, 23, 113, 26, 160, 128, 3, 10, 58, 129, 103, 14, 159,
616 214, 163, 146, 117, 238, 213, 154, 128, 151, 109, 84, 64, 217, 13,
617 27, 10, 228, 39, 2, 235, 164, 168, 74, 8, 0, 59,
618 };
619
620 /*
621 ** WEBPAGE: logo
622 **
623
+27 -27
--- src/encode.c
+++ src/encode.c
@@ -47,30 +47,30 @@
4747
}
4848
i = 0;
4949
zOut = fossil_malloc( count+1 );
5050
while( n-->0 && (c = *zIn)!=0 ){
5151
switch( c ){
52
- case '<':
52
+ case '<':
5353
zOut[i++] = '&';
5454
zOut[i++] = 'l';
5555
zOut[i++] = 't';
5656
zOut[i++] = ';';
5757
break;
58
- case '>':
58
+ case '>':
5959
zOut[i++] = '&';
6060
zOut[i++] = 'g';
6161
zOut[i++] = 't';
6262
zOut[i++] = ';';
6363
break;
64
- case '&':
64
+ case '&':
6565
zOut[i++] = '&';
6666
zOut[i++] = 'a';
6767
zOut[i++] = 'm';
6868
zOut[i++] = 'p';
6969
zOut[i++] = ';';
7070
break;
71
- case '"':
71
+ case '"':
7272
zOut[i++] = '&';
7373
zOut[i++] = 'q';
7474
zOut[i++] = 'u';
7575
zOut[i++] = 'o';
7676
zOut[i++] = 't';
@@ -181,11 +181,11 @@
181181
/*
182182
** Convert the input string into a form that is suitable for use as
183183
** a token in the HTTP protocol. Spaces are encoded as '+' and special
184184
** characters are encoded as "%HH" where HH is a two-digit hexidecimal
185185
** representation of the character. The "/" character is not encoded
186
-** by this routine.
186
+** by this routine.
187187
*/
188188
char *urlize(const char *z, int n){
189189
return EncodeHttp(z, n, 0);
190190
}
191191
@@ -327,11 +327,11 @@
327327
328328
329329
/*
330330
** The characters used for HTTP base64 encoding.
331331
*/
332
-static unsigned char zBase[] =
332
+static unsigned char zBase[] =
333333
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
334334
335335
/*
336336
** Encode a string using a base-64 encoding.
337337
** The encoding can be reversed using the <b>decode64</b> function.
@@ -366,11 +366,11 @@
366366
z64[n] = 0;
367367
return z64;
368368
}
369369
370370
/*
371
-** COMMAND: test-encode64
371
+** COMMAND: test-encode64
372372
** Usage: %fossil test-encode64 STRING
373373
*/
374374
void test_encode64_cmd(void){
375375
char *z;
376376
int i;
@@ -431,11 +431,11 @@
431431
*pnByte = j;
432432
return zData;
433433
}
434434
435435
/*
436
-** COMMAND: test-decode64
436
+** COMMAND: test-decode64
437437
** Usage: %fossil test-decode64 STRING
438438
*/
439439
void test_decode64_cmd(void){
440440
char *z;
441441
int i, n;
@@ -454,11 +454,11 @@
454454
*/
455455
456456
/*
457457
** The array used for encoding
458458
*/ /* 123456789 12345 */
459
-static const char zEncode[] = "0123456789abcdef";
459
+static const char zEncode[] = "0123456789abcdef";
460460
461461
/*
462462
** Encode a N-digit base-256 in base-16. Return zero on success
463463
** and non-zero if there is an error.
464464
*/
@@ -473,33 +473,33 @@
473473
}
474474
475475
/*
476476
** An array for translating single base-16 characters into a value.
477477
** Disallowed input characters have a value of 64. Upper and lower
478
-** case is the same.
478
+** case is the same.
479479
*/
480480
static const char zDecode[] = {
481
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
481
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
485485
64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
486486
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
487487
64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
488488
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
497497
};
498498
499499
/*
500
-** Decode a N-character base-16 number into base-256. N must be a
500
+** Decode a N-character base-16 number into base-256. N must be a
501501
** multiple of 2. The output buffer must be at least N/2 characters
502502
** in length
503503
*/
504504
int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
505505
int i, j;
@@ -545,11 +545,11 @@
545545
/* Randomness used for XOR-ing by the obscure() and unobscure() routines */
546546
static const unsigned char aObscurer[16] = {
547547
0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
548548
0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
549549
};
550
-
550
+
551551
552552
/*
553553
** Obscure plain text so that it is not easily readable.
554554
**
555555
** This is used for storing sensitive information (such as passwords) in a
@@ -562,11 +562,11 @@
562562
*/
563563
char *obscure(const char *zIn){
564564
int n, i;
565565
unsigned char salt;
566566
char *zOut;
567
-
567
+
568568
if( zIn==0 ) return 0;
569569
n = strlen(zIn);
570570
zOut = fossil_malloc( n*2+3 );
571571
sqlite3_randomness(1, &salt);
572572
zOut[n+1] = (char)salt;
@@ -578,17 +578,17 @@
578578
/*
579579
** Undo the obscuring of text performed by obscure(). Or, if the input is
580580
** not hexadecimal (meaning the input is not the output of obscure()) then
581581
** do the equivalent of strdup().
582582
**
583
-** The result is memory obtained from malloc that should be freed by the caller.
583
+** The result is memory obtained from malloc that should be freed by the caller.
584584
*/
585585
char *unobscure(const char *zIn){
586586
int n, i;
587587
unsigned char salt;
588588
char *zOut;
589
-
589
+
590590
if( zIn==0 ) return 0;
591591
n = strlen(zIn);
592592
zOut = fossil_malloc( n + 1 );
593593
if( n<2
594594
|| decode16((unsigned char*)zIn, &salt, 2)
595595
--- src/encode.c
+++ src/encode.c
@@ -47,30 +47,30 @@
47 }
48 i = 0;
49 zOut = fossil_malloc( count+1 );
50 while( n-->0 && (c = *zIn)!=0 ){
51 switch( c ){
52 case '<':
53 zOut[i++] = '&';
54 zOut[i++] = 'l';
55 zOut[i++] = 't';
56 zOut[i++] = ';';
57 break;
58 case '>':
59 zOut[i++] = '&';
60 zOut[i++] = 'g';
61 zOut[i++] = 't';
62 zOut[i++] = ';';
63 break;
64 case '&':
65 zOut[i++] = '&';
66 zOut[i++] = 'a';
67 zOut[i++] = 'm';
68 zOut[i++] = 'p';
69 zOut[i++] = ';';
70 break;
71 case '"':
72 zOut[i++] = '&';
73 zOut[i++] = 'q';
74 zOut[i++] = 'u';
75 zOut[i++] = 'o';
76 zOut[i++] = 't';
@@ -181,11 +181,11 @@
181 /*
182 ** Convert the input string into a form that is suitable for use as
183 ** a token in the HTTP protocol. Spaces are encoded as '+' and special
184 ** characters are encoded as "%HH" where HH is a two-digit hexidecimal
185 ** representation of the character. The "/" character is not encoded
186 ** by this routine.
187 */
188 char *urlize(const char *z, int n){
189 return EncodeHttp(z, n, 0);
190 }
191
@@ -327,11 +327,11 @@
327
328
329 /*
330 ** The characters used for HTTP base64 encoding.
331 */
332 static unsigned char zBase[] =
333 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
334
335 /*
336 ** Encode a string using a base-64 encoding.
337 ** The encoding can be reversed using the <b>decode64</b> function.
@@ -366,11 +366,11 @@
366 z64[n] = 0;
367 return z64;
368 }
369
370 /*
371 ** COMMAND: test-encode64
372 ** Usage: %fossil test-encode64 STRING
373 */
374 void test_encode64_cmd(void){
375 char *z;
376 int i;
@@ -431,11 +431,11 @@
431 *pnByte = j;
432 return zData;
433 }
434
435 /*
436 ** COMMAND: test-decode64
437 ** Usage: %fossil test-decode64 STRING
438 */
439 void test_decode64_cmd(void){
440 char *z;
441 int i, n;
@@ -454,11 +454,11 @@
454 */
455
456 /*
457 ** The array used for encoding
458 */ /* 123456789 12345 */
459 static const char zEncode[] = "0123456789abcdef";
460
461 /*
462 ** Encode a N-digit base-256 in base-16. Return zero on success
463 ** and non-zero if there is an error.
464 */
@@ -473,33 +473,33 @@
473 }
474
475 /*
476 ** An array for translating single base-16 characters into a value.
477 ** Disallowed input characters have a value of 64. Upper and lower
478 ** case is the same.
479 */
480 static const char zDecode[] = {
481 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
485 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
486 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
487 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
488 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
497 };
498
499 /*
500 ** Decode a N-character base-16 number into base-256. N must be a
501 ** multiple of 2. The output buffer must be at least N/2 characters
502 ** in length
503 */
504 int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
505 int i, j;
@@ -545,11 +545,11 @@
545 /* Randomness used for XOR-ing by the obscure() and unobscure() routines */
546 static const unsigned char aObscurer[16] = {
547 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
548 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
549 };
550
551
552 /*
553 ** Obscure plain text so that it is not easily readable.
554 **
555 ** This is used for storing sensitive information (such as passwords) in a
@@ -562,11 +562,11 @@
562 */
563 char *obscure(const char *zIn){
564 int n, i;
565 unsigned char salt;
566 char *zOut;
567
568 if( zIn==0 ) return 0;
569 n = strlen(zIn);
570 zOut = fossil_malloc( n*2+3 );
571 sqlite3_randomness(1, &salt);
572 zOut[n+1] = (char)salt;
@@ -578,17 +578,17 @@
578 /*
579 ** Undo the obscuring of text performed by obscure(). Or, if the input is
580 ** not hexadecimal (meaning the input is not the output of obscure()) then
581 ** do the equivalent of strdup().
582 **
583 ** The result is memory obtained from malloc that should be freed by the caller.
584 */
585 char *unobscure(const char *zIn){
586 int n, i;
587 unsigned char salt;
588 char *zOut;
589
590 if( zIn==0 ) return 0;
591 n = strlen(zIn);
592 zOut = fossil_malloc( n + 1 );
593 if( n<2
594 || decode16((unsigned char*)zIn, &salt, 2)
595
--- src/encode.c
+++ src/encode.c
@@ -47,30 +47,30 @@
47 }
48 i = 0;
49 zOut = fossil_malloc( count+1 );
50 while( n-->0 && (c = *zIn)!=0 ){
51 switch( c ){
52 case '<':
53 zOut[i++] = '&';
54 zOut[i++] = 'l';
55 zOut[i++] = 't';
56 zOut[i++] = ';';
57 break;
58 case '>':
59 zOut[i++] = '&';
60 zOut[i++] = 'g';
61 zOut[i++] = 't';
62 zOut[i++] = ';';
63 break;
64 case '&':
65 zOut[i++] = '&';
66 zOut[i++] = 'a';
67 zOut[i++] = 'm';
68 zOut[i++] = 'p';
69 zOut[i++] = ';';
70 break;
71 case '"':
72 zOut[i++] = '&';
73 zOut[i++] = 'q';
74 zOut[i++] = 'u';
75 zOut[i++] = 'o';
76 zOut[i++] = 't';
@@ -181,11 +181,11 @@
181 /*
182 ** Convert the input string into a form that is suitable for use as
183 ** a token in the HTTP protocol. Spaces are encoded as '+' and special
184 ** characters are encoded as "%HH" where HH is a two-digit hexidecimal
185 ** representation of the character. The "/" character is not encoded
186 ** by this routine.
187 */
188 char *urlize(const char *z, int n){
189 return EncodeHttp(z, n, 0);
190 }
191
@@ -327,11 +327,11 @@
327
328
329 /*
330 ** The characters used for HTTP base64 encoding.
331 */
332 static unsigned char zBase[] =
333 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
334
335 /*
336 ** Encode a string using a base-64 encoding.
337 ** The encoding can be reversed using the <b>decode64</b> function.
@@ -366,11 +366,11 @@
366 z64[n] = 0;
367 return z64;
368 }
369
370 /*
371 ** COMMAND: test-encode64
372 ** Usage: %fossil test-encode64 STRING
373 */
374 void test_encode64_cmd(void){
375 char *z;
376 int i;
@@ -431,11 +431,11 @@
431 *pnByte = j;
432 return zData;
433 }
434
435 /*
436 ** COMMAND: test-decode64
437 ** Usage: %fossil test-decode64 STRING
438 */
439 void test_decode64_cmd(void){
440 char *z;
441 int i, n;
@@ -454,11 +454,11 @@
454 */
455
456 /*
457 ** The array used for encoding
458 */ /* 123456789 12345 */
459 static const char zEncode[] = "0123456789abcdef";
460
461 /*
462 ** Encode a N-digit base-256 in base-16. Return zero on success
463 ** and non-zero if there is an error.
464 */
@@ -473,33 +473,33 @@
473 }
474
475 /*
476 ** An array for translating single base-16 characters into a value.
477 ** Disallowed input characters have a value of 64. Upper and lower
478 ** case is the same.
479 */
480 static const char zDecode[] = {
481 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
482 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
483 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
484 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
485 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
486 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
487 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
488 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
489 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
490 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
491 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
492 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
493 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
494 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
495 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
496 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
497 };
498
499 /*
500 ** Decode a N-character base-16 number into base-256. N must be a
501 ** multiple of 2. The output buffer must be at least N/2 characters
502 ** in length
503 */
504 int decode16(const unsigned char *zIn, unsigned char *pOut, int N){
505 int i, j;
@@ -545,11 +545,11 @@
545 /* Randomness used for XOR-ing by the obscure() and unobscure() routines */
546 static const unsigned char aObscurer[16] = {
547 0xa7, 0x21, 0x31, 0xe3, 0x2a, 0x50, 0x2c, 0x86,
548 0x4c, 0xa4, 0x52, 0x25, 0xff, 0x49, 0x35, 0x85
549 };
550
551
552 /*
553 ** Obscure plain text so that it is not easily readable.
554 **
555 ** This is used for storing sensitive information (such as passwords) in a
@@ -562,11 +562,11 @@
562 */
563 char *obscure(const char *zIn){
564 int n, i;
565 unsigned char salt;
566 char *zOut;
567
568 if( zIn==0 ) return 0;
569 n = strlen(zIn);
570 zOut = fossil_malloc( n*2+3 );
571 sqlite3_randomness(1, &salt);
572 zOut[n+1] = (char)salt;
@@ -578,17 +578,17 @@
578 /*
579 ** Undo the obscuring of text performed by obscure(). Or, if the input is
580 ** not hexadecimal (meaning the input is not the output of obscure()) then
581 ** do the equivalent of strdup().
582 **
583 ** The result is memory obtained from malloc that should be freed by the caller.
584 */
585 char *unobscure(const char *zIn){
586 int n, i;
587 unsigned char salt;
588 char *zOut;
589
590 if( zIn==0 ) return 0;
591 n = strlen(zIn);
592 zOut = fossil_malloc( n + 1 );
593 if( n<2
594 || decode16((unsigned char*)zIn, &salt, 2)
595
+2 -4
--- src/event.c
+++ src/event.c
@@ -119,11 +119,11 @@
119119
if( pEvent==0 ){
120120
fossil_fatal("Object #%d is not an event", rid);
121121
}
122122
blob_init(&fullbody, pEvent->zWiki, -1);
123123
if( wiki_find_title(&fullbody, &title, &tail) ){
124
- style_header(blob_str(&title));
124
+ style_header("%s", blob_str(&title));
125125
}else{
126126
style_header("Event %S", zEventId);
127127
tail = fullbody;
128128
}
129129
if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
@@ -203,11 +203,10 @@
203203
void eventedit_page(void){
204204
char *zTag;
205205
int rid = 0;
206206
Blob event;
207207
const char *zEventId;
208
- char *zHtmlPageName;
209208
int n;
210209
const char *z;
211210
char *zBody = (char*)P("w");
212211
char *zETime = (char*)P("t");
213212
const char *zComment = P("c");
@@ -364,12 +363,11 @@
364363
return;
365364
}
366365
if( zBody==0 ){
367366
zBody = mprintf("<i>Event Text</i>");
368367
}
369
- zHtmlPageName = mprintf("Edit Event %S", zEventId);
370
- style_header(zHtmlPageName);
368
+ style_header("Edit Event %S", zEventId);
371369
if( P("preview")!=0 ){
372370
Blob title, tail, com;
373371
@ <p><b>Timeline comment preview:</b></p>
374372
@ <blockquote>
375373
@ <table border="0">
376374
--- src/event.c
+++ src/event.c
@@ -119,11 +119,11 @@
119 if( pEvent==0 ){
120 fossil_fatal("Object #%d is not an event", rid);
121 }
122 blob_init(&fullbody, pEvent->zWiki, -1);
123 if( wiki_find_title(&fullbody, &title, &tail) ){
124 style_header(blob_str(&title));
125 }else{
126 style_header("Event %S", zEventId);
127 tail = fullbody;
128 }
129 if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
@@ -203,11 +203,10 @@
203 void eventedit_page(void){
204 char *zTag;
205 int rid = 0;
206 Blob event;
207 const char *zEventId;
208 char *zHtmlPageName;
209 int n;
210 const char *z;
211 char *zBody = (char*)P("w");
212 char *zETime = (char*)P("t");
213 const char *zComment = P("c");
@@ -364,12 +363,11 @@
364 return;
365 }
366 if( zBody==0 ){
367 zBody = mprintf("<i>Event Text</i>");
368 }
369 zHtmlPageName = mprintf("Edit Event %S", zEventId);
370 style_header(zHtmlPageName);
371 if( P("preview")!=0 ){
372 Blob title, tail, com;
373 @ <p><b>Timeline comment preview:</b></p>
374 @ <blockquote>
375 @ <table border="0">
376
--- src/event.c
+++ src/event.c
@@ -119,11 +119,11 @@
119 if( pEvent==0 ){
120 fossil_fatal("Object #%d is not an event", rid);
121 }
122 blob_init(&fullbody, pEvent->zWiki, -1);
123 if( wiki_find_title(&fullbody, &title, &tail) ){
124 style_header("%s", blob_str(&title));
125 }else{
126 style_header("Event %S", zEventId);
127 tail = fullbody;
128 }
129 if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
@@ -203,11 +203,10 @@
203 void eventedit_page(void){
204 char *zTag;
205 int rid = 0;
206 Blob event;
207 const char *zEventId;
 
208 int n;
209 const char *z;
210 char *zBody = (char*)P("w");
211 char *zETime = (char*)P("t");
212 const char *zComment = P("c");
@@ -364,12 +363,11 @@
363 return;
364 }
365 if( zBody==0 ){
366 zBody = mprintf("<i>Event Text</i>");
367 }
368 style_header("Edit Event %S", zEventId);
 
369 if( P("preview")!=0 ){
370 Blob title, tail, com;
371 @ <p><b>Timeline comment preview:</b></p>
372 @ <blockquote>
373 @ <table border="0">
374
+2 -2
--- src/export.c
+++ src/export.c
@@ -232,12 +232,12 @@
232232
db_finalize(&q3);
233233
234234
/* Output the commit records.
235235
*/
236236
db_prepare(&q,
237
- "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment),"
238
- " coalesce(user,euser),"
237
+ "SELECT strftime('%%s',mtime), objid, coalesce(ecomment,comment),"
238
+ " coalesce(euser,user),"
239239
" (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)"
240240
" FROM event"
241241
" WHERE type='ci' AND NOT EXISTS (SELECT 1 FROM oldcommit WHERE objid=rid)"
242242
" ORDER BY mtime ASC",
243243
TAG_BRANCH
244244
--- src/export.c
+++ src/export.c
@@ -232,12 +232,12 @@
232 db_finalize(&q3);
233
234 /* Output the commit records.
235 */
236 db_prepare(&q,
237 "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment),"
238 " coalesce(user,euser),"
239 " (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)"
240 " FROM event"
241 " WHERE type='ci' AND NOT EXISTS (SELECT 1 FROM oldcommit WHERE objid=rid)"
242 " ORDER BY mtime ASC",
243 TAG_BRANCH
244
--- src/export.c
+++ src/export.c
@@ -232,12 +232,12 @@
232 db_finalize(&q3);
233
234 /* Output the commit records.
235 */
236 db_prepare(&q,
237 "SELECT strftime('%%s',mtime), objid, coalesce(ecomment,comment),"
238 " coalesce(euser,user),"
239 " (SELECT value FROM tagxref WHERE rid=objid AND tagid=%d)"
240 " FROM event"
241 " WHERE type='ci' AND NOT EXISTS (SELECT 1 FROM oldcommit WHERE objid=rid)"
242 " ORDER BY mtime ASC",
243 TAG_BRANCH
244
+12 -12
--- src/finfo.c
+++ src/finfo.c
@@ -319,11 +319,11 @@
319319
320320
zPrevDate[0] = 0;
321321
zFilename = PD("name","");
322322
url_add_parameter(&url, "name", zFilename);
323323
blob_zero(&sql);
324
- blob_appendf(&sql,
324
+ blob_append_sql(&sql,
325325
"SELECT"
326326
" datetime(event.mtime%s)," /* Date of change */
327327
" coalesce(event.ecomment, event.comment)," /* Check-in comment */
328328
" coalesce(event.euser, event.user)," /* User who made chng */
329329
" mlink.pid," /* Parent file rid */
@@ -338,44 +338,44 @@
338338
" mlink.pfnid", /* Previous filename */
339339
timeline_utc(), TAG_BRANCH
340340
);
341341
if( firstChngOnly ){
342342
#if 0
343
- blob_appendf(&sql, ", min(event.mtime)");
343
+ blob_append_sql(&sql, ", min(event.mtime)");
344344
#else
345
- blob_appendf(&sql,
345
+ blob_append_sql(&sql,
346346
", min(CASE (SELECT value FROM tagxref"
347347
" WHERE tagtype>0 AND tagid=%d"
348348
" AND tagxref.rid=mlink.mid)"
349349
" WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
350350
TAG_BRANCH);
351351
#endif
352352
}
353
- blob_appendf(&sql,
353
+ blob_append_sql(&sql,
354354
" FROM mlink, event"
355355
" WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
356356
" AND event.objid=mlink.mid",
357357
zFilename
358358
);
359359
if( baseCheckin ){
360360
compute_direct_ancestors(baseCheckin, 10000000);
361
- blob_appendf(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
361
+ blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
362362
}
363363
if( (zA = P("a"))!=0 ){
364
- blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
364
+ blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA);
365365
url_add_parameter(&url, "a", zA);
366366
}
367367
if( (zB = P("b"))!=0 ){
368
- blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB);
368
+ blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
369369
url_add_parameter(&url, "b", zB);
370370
}
371371
if( firstChngOnly ){
372
- blob_appendf(&sql, " GROUP BY mlink.fid");
372
+ blob_append_sql(&sql, " GROUP BY mlink.fid");
373373
}
374
- blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/");
374
+ blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/");
375375
if( (n = atoi(PD("n","0")))>0 ){
376
- blob_appendf(&sql, " LIMIT %d", n);
376
+ blob_append_sql(&sql, " LIMIT %d", n);
377377
url_add_parameter(&url, "n", P("n"));
378378
}
379379
if( baseCheckin==0 ){
380380
if( firstChngOnly ){
381381
style_submenu_element("Full", "Show all changes","%s",
@@ -384,11 +384,11 @@
384384
style_submenu_element("Simplified",
385385
"Show only first use of a change","%s",
386386
url_render(&url, "fco", 0, 0, 0));
387387
}
388388
}
389
- db_prepare(&q, blob_str(&sql));
389
+ db_prepare(&q, "%s", blob_sql_text(&sql));
390390
if( P("showsql")!=0 ){
391391
@ <p>SQL: %h(blob_str(&sql))</p>
392392
}
393393
blob_reset(&sql);
394394
blob_zero(&title);
@@ -473,11 +473,11 @@
473473
}else{
474474
@ <b>Deleted</b> by check-in
475475
}
476476
}
477477
hyperlink_to_uuid(zCkin);
478
- @ %w(zCom) (user:
478
+ @ %W(zCom) (user:
479479
hyperlink_to_user(zUser, zDate, "");
480480
@ branch: %h(zBr))
481481
if( g.perm.Hyperlink && zUuid ){
482482
const char *z = zFilename;
483483
@ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
484484
--- src/finfo.c
+++ src/finfo.c
@@ -319,11 +319,11 @@
319
320 zPrevDate[0] = 0;
321 zFilename = PD("name","");
322 url_add_parameter(&url, "name", zFilename);
323 blob_zero(&sql);
324 blob_appendf(&sql,
325 "SELECT"
326 " datetime(event.mtime%s)," /* Date of change */
327 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
328 " coalesce(event.euser, event.user)," /* User who made chng */
329 " mlink.pid," /* Parent file rid */
@@ -338,44 +338,44 @@
338 " mlink.pfnid", /* Previous filename */
339 timeline_utc(), TAG_BRANCH
340 );
341 if( firstChngOnly ){
342 #if 0
343 blob_appendf(&sql, ", min(event.mtime)");
344 #else
345 blob_appendf(&sql,
346 ", min(CASE (SELECT value FROM tagxref"
347 " WHERE tagtype>0 AND tagid=%d"
348 " AND tagxref.rid=mlink.mid)"
349 " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
350 TAG_BRANCH);
351 #endif
352 }
353 blob_appendf(&sql,
354 " FROM mlink, event"
355 " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
356 " AND event.objid=mlink.mid",
357 zFilename
358 );
359 if( baseCheckin ){
360 compute_direct_ancestors(baseCheckin, 10000000);
361 blob_appendf(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
362 }
363 if( (zA = P("a"))!=0 ){
364 blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
365 url_add_parameter(&url, "a", zA);
366 }
367 if( (zB = P("b"))!=0 ){
368 blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB);
369 url_add_parameter(&url, "b", zB);
370 }
371 if( firstChngOnly ){
372 blob_appendf(&sql, " GROUP BY mlink.fid");
373 }
374 blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/");
375 if( (n = atoi(PD("n","0")))>0 ){
376 blob_appendf(&sql, " LIMIT %d", n);
377 url_add_parameter(&url, "n", P("n"));
378 }
379 if( baseCheckin==0 ){
380 if( firstChngOnly ){
381 style_submenu_element("Full", "Show all changes","%s",
@@ -384,11 +384,11 @@
384 style_submenu_element("Simplified",
385 "Show only first use of a change","%s",
386 url_render(&url, "fco", 0, 0, 0));
387 }
388 }
389 db_prepare(&q, blob_str(&sql));
390 if( P("showsql")!=0 ){
391 @ <p>SQL: %h(blob_str(&sql))</p>
392 }
393 blob_reset(&sql);
394 blob_zero(&title);
@@ -473,11 +473,11 @@
473 }else{
474 @ <b>Deleted</b> by check-in
475 }
476 }
477 hyperlink_to_uuid(zCkin);
478 @ %w(zCom) (user:
479 hyperlink_to_user(zUser, zDate, "");
480 @ branch: %h(zBr))
481 if( g.perm.Hyperlink && zUuid ){
482 const char *z = zFilename;
483 @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
484
--- src/finfo.c
+++ src/finfo.c
@@ -319,11 +319,11 @@
319
320 zPrevDate[0] = 0;
321 zFilename = PD("name","");
322 url_add_parameter(&url, "name", zFilename);
323 blob_zero(&sql);
324 blob_append_sql(&sql,
325 "SELECT"
326 " datetime(event.mtime%s)," /* Date of change */
327 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
328 " coalesce(event.euser, event.user)," /* User who made chng */
329 " mlink.pid," /* Parent file rid */
@@ -338,44 +338,44 @@
338 " mlink.pfnid", /* Previous filename */
339 timeline_utc(), TAG_BRANCH
340 );
341 if( firstChngOnly ){
342 #if 0
343 blob_append_sql(&sql, ", min(event.mtime)");
344 #else
345 blob_append_sql(&sql,
346 ", min(CASE (SELECT value FROM tagxref"
347 " WHERE tagtype>0 AND tagid=%d"
348 " AND tagxref.rid=mlink.mid)"
349 " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)",
350 TAG_BRANCH);
351 #endif
352 }
353 blob_append_sql(&sql,
354 " FROM mlink, event"
355 " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)"
356 " AND event.objid=mlink.mid",
357 zFilename
358 );
359 if( baseCheckin ){
360 compute_direct_ancestors(baseCheckin, 10000000);
361 blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)");
362 }
363 if( (zA = P("a"))!=0 ){
364 blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA);
365 url_add_parameter(&url, "a", zA);
366 }
367 if( (zB = P("b"))!=0 ){
368 blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB);
369 url_add_parameter(&url, "b", zB);
370 }
371 if( firstChngOnly ){
372 blob_append_sql(&sql, " GROUP BY mlink.fid");
373 }
374 blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/");
375 if( (n = atoi(PD("n","0")))>0 ){
376 blob_append_sql(&sql, " LIMIT %d", n);
377 url_add_parameter(&url, "n", P("n"));
378 }
379 if( baseCheckin==0 ){
380 if( firstChngOnly ){
381 style_submenu_element("Full", "Show all changes","%s",
@@ -384,11 +384,11 @@
384 style_submenu_element("Simplified",
385 "Show only first use of a change","%s",
386 url_render(&url, "fco", 0, 0, 0));
387 }
388 }
389 db_prepare(&q, "%s", blob_sql_text(&sql));
390 if( P("showsql")!=0 ){
391 @ <p>SQL: %h(blob_str(&sql))</p>
392 }
393 blob_reset(&sql);
394 blob_zero(&title);
@@ -473,11 +473,11 @@
473 }else{
474 @ <b>Deleted</b> by check-in
475 }
476 }
477 hyperlink_to_uuid(zCkin);
478 @ %W(zCom) (user:
479 hyperlink_to_user(zUser, zDate, "");
480 @ branch: %h(zBr))
481 if( g.perm.Hyperlink && zUuid ){
482 const char *z = zFilename;
483 @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
484
+2 -2
--- src/http.c
+++ src/http.c
@@ -167,11 +167,11 @@
167167
char *zPrompt;
168168
char *zHttpAuth = 0;
169169
if( !isatty(fileno(stdin)) ) return 0;
170170
zPrompt = mprintf("\n%s authorization required by\n%s\n",
171171
g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
172
- fossil_print(zPrompt);
172
+ fossil_print("%s", zPrompt);
173173
free(zPrompt);
174174
if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
175175
zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
176176
}else{
177177
prompt_user("Basic Authorization user: ", &x);
@@ -214,11 +214,11 @@
214214
int i; /* Loop counter */
215215
int isError = 0; /* True if the reply is an error message */
216216
int isCompressed = 1; /* True if the reply is compressed */
217217
218218
if( transport_open(&g.url) ){
219
- fossil_warning(transport_errmsg(&g.url));
219
+ fossil_warning("%s", transport_errmsg(&g.url));
220220
return 1;
221221
}
222222
223223
/* Construct the login card and prepare the complete payload */
224224
blob_zero(&login);
225225
--- src/http.c
+++ src/http.c
@@ -167,11 +167,11 @@
167 char *zPrompt;
168 char *zHttpAuth = 0;
169 if( !isatty(fileno(stdin)) ) return 0;
170 zPrompt = mprintf("\n%s authorization required by\n%s\n",
171 g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
172 fossil_print(zPrompt);
173 free(zPrompt);
174 if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
175 zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
176 }else{
177 prompt_user("Basic Authorization user: ", &x);
@@ -214,11 +214,11 @@
214 int i; /* Loop counter */
215 int isError = 0; /* True if the reply is an error message */
216 int isCompressed = 1; /* True if the reply is compressed */
217
218 if( transport_open(&g.url) ){
219 fossil_warning(transport_errmsg(&g.url));
220 return 1;
221 }
222
223 /* Construct the login card and prepare the complete payload */
224 blob_zero(&login);
225
--- src/http.c
+++ src/http.c
@@ -167,11 +167,11 @@
167 char *zPrompt;
168 char *zHttpAuth = 0;
169 if( !isatty(fileno(stdin)) ) return 0;
170 zPrompt = mprintf("\n%s authorization required by\n%s\n",
171 g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical);
172 fossil_print("%s", zPrompt);
173 free(zPrompt);
174 if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){
175 zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd);
176 }else{
177 prompt_user("Basic Authorization user: ", &x);
@@ -214,11 +214,11 @@
214 int i; /* Loop counter */
215 int isError = 0; /* True if the reply is an error message */
216 int isCompressed = 1; /* True if the reply is compressed */
217
218 if( transport_open(&g.url) ){
219 fossil_warning("%s", transport_errmsg(&g.url));
220 return 1;
221 }
222
223 /* Construct the login card and prepare the complete payload */
224 blob_zero(&login);
225
+6 -8
--- src/info.c
+++ src/info.c
@@ -535,20 +535,18 @@
535535
timeline_utc(), timeline_utc(), rid, rid
536536
);
537537
sideBySide = !is_false(PD("sbs","1"));
538538
if( db_step(&q1)==SQLITE_ROW ){
539539
const char *zUuid = db_column_text(&q1, 0);
540
- char *zTitle = mprintf("Check-in [%S]", zUuid);
541540
char *zEUser, *zEComment;
542541
const char *zUser;
543542
const char *zComment;
544543
const char *zDate;
545544
const char *zOrigDate;
546545
547
- style_header(zTitle);
546
+ style_header("Check-in [%S]", zUuid);
548547
login_anonymous_available();
549
- free(zTitle);
550548
zEUser = db_text(0,
551549
"SELECT value FROM tagxref"
552550
" WHERE tagid=%d AND rid=%d AND tagtype>0",
553551
TAG_USER, rid);
554552
zEComment = db_text(0,
@@ -1582,11 +1580,11 @@
15821580
login_check_credentials();
15831581
if( !g.perm.Read ){ login_needed(); return; }
15841582
if( rid==0 ) fossil_redirect_home();
15851583
if( g.perm.Admin ){
15861584
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1587
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1585
+ if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
15881586
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
15891587
g.zTop, zUuid);
15901588
}else{
15911589
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
15921590
g.zTop, zUuid);
@@ -1768,20 +1766,20 @@
17681766
login_check_credentials();
17691767
if( !g.perm.Read ){ login_needed(); return; }
17701768
if( rid==0 ) fossil_redirect_home();
17711769
if( g.perm.Admin ){
17721770
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1773
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1771
+ if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
17741772
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
17751773
g.zTop, zUuid);
17761774
}else{
17771775
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
17781776
g.zTop, zUuid);
17791777
}
17801778
}
17811779
if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1782
- style_header(descOnly ? "Artifact Description" : "Artifact Content");
1780
+ style_header("%s", descOnly ? "Artifact Description" : "Artifact Content");
17831781
zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
17841782
if( g.perm.Setup ){
17851783
@ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
17861784
}else{
17871785
@ <h2>Artifact %s(zUuid):</h2>
@@ -1884,11 +1882,11 @@
18841882
if( !g.perm.RdTkt ){ login_needed(); return; }
18851883
rid = name_to_rid_www("name");
18861884
if( rid==0 ){ fossil_redirect_home(); }
18871885
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
18881886
if( g.perm.Admin ){
1889
- if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1887
+ if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
18901888
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
18911889
g.zTop, zUuid);
18921890
}else{
18931891
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
18941892
g.zTop, zUuid);
@@ -2029,11 +2027,11 @@
20292027
cgi_set_parameter("src","info");
20302028
ambiguous_page();
20312029
return;
20322030
}
20332031
zName = blob_str(&uuid);
2034
- rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
2032
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
20352033
if( rid==0 ){
20362034
style_header("Broken Link");
20372035
@ <p>No such object: %h(zName)</p>
20382036
style_footer();
20392037
return;
20402038
--- src/info.c
+++ src/info.c
@@ -535,20 +535,18 @@
535 timeline_utc(), timeline_utc(), rid, rid
536 );
537 sideBySide = !is_false(PD("sbs","1"));
538 if( db_step(&q1)==SQLITE_ROW ){
539 const char *zUuid = db_column_text(&q1, 0);
540 char *zTitle = mprintf("Check-in [%S]", zUuid);
541 char *zEUser, *zEComment;
542 const char *zUser;
543 const char *zComment;
544 const char *zDate;
545 const char *zOrigDate;
546
547 style_header(zTitle);
548 login_anonymous_available();
549 free(zTitle);
550 zEUser = db_text(0,
551 "SELECT value FROM tagxref"
552 " WHERE tagid=%d AND rid=%d AND tagtype>0",
553 TAG_USER, rid);
554 zEComment = db_text(0,
@@ -1582,11 +1580,11 @@
1582 login_check_credentials();
1583 if( !g.perm.Read ){ login_needed(); return; }
1584 if( rid==0 ) fossil_redirect_home();
1585 if( g.perm.Admin ){
1586 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1587 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1588 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
1589 g.zTop, zUuid);
1590 }else{
1591 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1592 g.zTop, zUuid);
@@ -1768,20 +1766,20 @@
1768 login_check_credentials();
1769 if( !g.perm.Read ){ login_needed(); return; }
1770 if( rid==0 ) fossil_redirect_home();
1771 if( g.perm.Admin ){
1772 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1773 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1774 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1775 g.zTop, zUuid);
1776 }else{
1777 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1778 g.zTop, zUuid);
1779 }
1780 }
1781 if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1782 style_header(descOnly ? "Artifact Description" : "Artifact Content");
1783 zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
1784 if( g.perm.Setup ){
1785 @ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
1786 }else{
1787 @ <h2>Artifact %s(zUuid):</h2>
@@ -1884,11 +1882,11 @@
1884 if( !g.perm.RdTkt ){ login_needed(); return; }
1885 rid = name_to_rid_www("name");
1886 if( rid==0 ){ fossil_redirect_home(); }
1887 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1888 if( g.perm.Admin ){
1889 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1890 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1891 g.zTop, zUuid);
1892 }else{
1893 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1894 g.zTop, zUuid);
@@ -2029,11 +2027,11 @@
2029 cgi_set_parameter("src","info");
2030 ambiguous_page();
2031 return;
2032 }
2033 zName = blob_str(&uuid);
2034 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
2035 if( rid==0 ){
2036 style_header("Broken Link");
2037 @ <p>No such object: %h(zName)</p>
2038 style_footer();
2039 return;
2040
--- src/info.c
+++ src/info.c
@@ -535,20 +535,18 @@
535 timeline_utc(), timeline_utc(), rid, rid
536 );
537 sideBySide = !is_false(PD("sbs","1"));
538 if( db_step(&q1)==SQLITE_ROW ){
539 const char *zUuid = db_column_text(&q1, 0);
 
540 char *zEUser, *zEComment;
541 const char *zUser;
542 const char *zComment;
543 const char *zDate;
544 const char *zOrigDate;
545
546 style_header("Check-in [%S]", zUuid);
547 login_anonymous_available();
 
548 zEUser = db_text(0,
549 "SELECT value FROM tagxref"
550 " WHERE tagid=%d AND rid=%d AND tagtype>0",
551 TAG_USER, rid);
552 zEComment = db_text(0,
@@ -1582,11 +1580,11 @@
1580 login_check_credentials();
1581 if( !g.perm.Read ){ login_needed(); return; }
1582 if( rid==0 ) fossil_redirect_home();
1583 if( g.perm.Admin ){
1584 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1585 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
1586 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
1587 g.zTop, zUuid);
1588 }else{
1589 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1590 g.zTop, zUuid);
@@ -1768,20 +1766,20 @@
1766 login_check_credentials();
1767 if( !g.perm.Read ){ login_needed(); return; }
1768 if( rid==0 ) fossil_redirect_home();
1769 if( g.perm.Admin ){
1770 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1771 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
1772 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1773 g.zTop, zUuid);
1774 }else{
1775 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1776 g.zTop, zUuid);
1777 }
1778 }
1779 if( descOnly || P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1780 style_header("%s", descOnly ? "Artifact Description" : "Artifact Content");
1781 zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
1782 if( g.perm.Setup ){
1783 @ <h2>Artifact %s(zUuid) (%d(rid)):</h2>
1784 }else{
1785 @ <h2>Artifact %s(zUuid):</h2>
@@ -1884,11 +1882,11 @@
1882 if( !g.perm.RdTkt ){ login_needed(); return; }
1883 rid = name_to_rid_www("name");
1884 if( rid==0 ){ fossil_redirect_home(); }
1885 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1886 if( g.perm.Admin ){
1887 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
1888 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1889 g.zTop, zUuid);
1890 }else{
1891 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1892 g.zTop, zUuid);
@@ -2029,11 +2027,11 @@
2027 cgi_set_parameter("src","info");
2028 ambiguous_page();
2029 return;
2030 }
2031 zName = blob_str(&uuid);
2032 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
2033 if( rid==0 ){
2034 style_header("Broken Link");
2035 @ <p>No such object: %h(zName)</p>
2036 style_footer();
2037 return;
2038
+7 -7
--- src/json.c
+++ src/json.c
@@ -1665,11 +1665,11 @@
16651665
cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
16661666
char resetBlob){
16671667
Stmt q = empty_Stmt;
16681668
cson_value * pay = NULL;
16691669
assert( blob_size(pSql) > 0 );
1670
- db_prepare(&q, "%s", blob_str(pSql));
1670
+ db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
16711671
if(resetBlob){
16721672
blob_reset(pSql);
16731673
}
16741674
pay = json_stmt_to_array_of_obj(&q, pTgt);
16751675
db_finalize(&q);
@@ -1983,16 +1983,16 @@
19831983
cson_object_set(jo, "sqlite", jv2);
19841984
sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
19851985
sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
19861986
SETBUF(jo2, "version");
19871987
zDb = db_name("repository");
1988
- cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb)));
1989
- cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb)));
1990
- cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.freelist_count", zDb)));
1991
- sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.encoding", zDb));
1988
+ cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_count", zDb)));
1989
+ cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_size", zDb)));
1990
+ cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".freelist_count", zDb)));
1991
+ sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".encoding", zDb));
19921992
SETBUF(jo2, "encoding");
1993
- sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.journal_mode", zDb));
1993
+ sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
19941994
cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
19951995
return jv;
19961996
#undef SETBUF
19971997
}
19981998
@@ -2016,11 +2016,11 @@
20162016
for( ; zPages->name; ++zPages, ++i ){
20172017
if(filterByMode){
20182018
if(g.isHTTP && zPages->runMode < 0) continue;
20192019
else if(zPages->runMode > 0) continue;
20202020
}
2021
- blob_appendf(pOut, zPages->name, -1);
2021
+ blob_append(pOut, zPages->name, -1);
20222022
if((zPages+1)->name){
20232023
blob_append(pOut, ", ",2);
20242024
}
20252025
}
20262026
return i;
20272027
--- src/json.c
+++ src/json.c
@@ -1665,11 +1665,11 @@
1665 cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
1666 char resetBlob){
1667 Stmt q = empty_Stmt;
1668 cson_value * pay = NULL;
1669 assert( blob_size(pSql) > 0 );
1670 db_prepare(&q, "%s", blob_str(pSql));
1671 if(resetBlob){
1672 blob_reset(pSql);
1673 }
1674 pay = json_stmt_to_array_of_obj(&q, pTgt);
1675 db_finalize(&q);
@@ -1983,16 +1983,16 @@
1983 cson_object_set(jo, "sqlite", jv2);
1984 sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
1985 sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
1986 SETBUF(jo2, "version");
1987 zDb = db_name("repository");
1988 cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb)));
1989 cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb)));
1990 cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.freelist_count", zDb)));
1991 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.encoding", zDb));
1992 SETBUF(jo2, "encoding");
1993 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA %s.journal_mode", zDb));
1994 cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
1995 return jv;
1996 #undef SETBUF
1997 }
1998
@@ -2016,11 +2016,11 @@
2016 for( ; zPages->name; ++zPages, ++i ){
2017 if(filterByMode){
2018 if(g.isHTTP && zPages->runMode < 0) continue;
2019 else if(zPages->runMode > 0) continue;
2020 }
2021 blob_appendf(pOut, zPages->name, -1);
2022 if((zPages+1)->name){
2023 blob_append(pOut, ", ",2);
2024 }
2025 }
2026 return i;
2027
--- src/json.c
+++ src/json.c
@@ -1665,11 +1665,11 @@
1665 cson_value * json_sql_to_array_of_obj(Blob * pSql, cson_array * pTgt,
1666 char resetBlob){
1667 Stmt q = empty_Stmt;
1668 cson_value * pay = NULL;
1669 assert( blob_size(pSql) > 0 );
1670 db_prepare(&q, "%s", blob_str(pSql) /*safe-for-%s*/);
1671 if(resetBlob){
1672 blob_reset(pSql);
1673 }
1674 pay = json_stmt_to_array_of_obj(&q, pTgt);
1675 db_finalize(&q);
@@ -1983,16 +1983,16 @@
1983 cson_object_set(jo, "sqlite", jv2);
1984 sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
1985 sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
1986 SETBUF(jo2, "version");
1987 zDb = db_name("repository");
1988 cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_count", zDb)));
1989 cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".page_size", zDb)));
1990 cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA \"%w\".freelist_count", zDb)));
1991 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".encoding", zDb));
1992 SETBUF(jo2, "encoding");
1993 sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
1994 cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
1995 return jv;
1996 #undef SETBUF
1997 }
1998
@@ -2016,11 +2016,11 @@
2016 for( ; zPages->name; ++zPages, ++i ){
2017 if(filterByMode){
2018 if(g.isHTTP && zPages->runMode < 0) continue;
2019 else if(zPages->runMode > 0) continue;
2020 }
2021 blob_append(pOut, zPages->name, -1);
2022 if((zPages+1)->name){
2023 blob_append(pOut, ", ",2);
2024 }
2025 }
2026 return i;
2027
--- src/json_config.c
+++ src/json_config.c
@@ -145,11 +145,11 @@
145145
for( i = 0; prop->name; ++prop ){
146146
if(prop->groupMask & confMask){
147147
if( i++ ){
148148
blob_append(&sql,",",1);
149149
}
150
- blob_appendf(&sql, "%Q", prop->name);
150
+ blob_append_sql(&sql, "%Q", prop->name);
151151
}
152152
}
153153
blob_append(&sql,") ", -1);
154154
}
155155
@@ -156,11 +156,11 @@
156156
157157
if( optSkinBackups ){
158158
blob_append(&sql, " OR name GLOB 'skin:*'", -1);
159159
}
160160
blob_append(&sql," ORDER BY name", -1);
161
- db_prepare(&q, blob_str(&sql));
161
+ db_prepare(&q, "%s", blob_sql_text(&sql));
162162
blob_reset(&sql);
163163
pay = cson_new_object();
164164
while( (SQLITE_ROW==db_step(&q)) ){
165165
cson_object_set(pay,
166166
db_column_text(&q,0),
167167
--- src/json_config.c
+++ src/json_config.c
@@ -145,11 +145,11 @@
145 for( i = 0; prop->name; ++prop ){
146 if(prop->groupMask & confMask){
147 if( i++ ){
148 blob_append(&sql,",",1);
149 }
150 blob_appendf(&sql, "%Q", prop->name);
151 }
152 }
153 blob_append(&sql,") ", -1);
154 }
155
@@ -156,11 +156,11 @@
156
157 if( optSkinBackups ){
158 blob_append(&sql, " OR name GLOB 'skin:*'", -1);
159 }
160 blob_append(&sql," ORDER BY name", -1);
161 db_prepare(&q, blob_str(&sql));
162 blob_reset(&sql);
163 pay = cson_new_object();
164 while( (SQLITE_ROW==db_step(&q)) ){
165 cson_object_set(pay,
166 db_column_text(&q,0),
167
--- src/json_config.c
+++ src/json_config.c
@@ -145,11 +145,11 @@
145 for( i = 0; prop->name; ++prop ){
146 if(prop->groupMask & confMask){
147 if( i++ ){
148 blob_append(&sql,",",1);
149 }
150 blob_append_sql(&sql, "%Q", prop->name);
151 }
152 }
153 blob_append(&sql,") ", -1);
154 }
155
@@ -156,11 +156,11 @@
156
157 if( optSkinBackups ){
158 blob_append(&sql, " OR name GLOB 'skin:*'", -1);
159 }
160 blob_append(&sql," ORDER BY name", -1);
161 db_prepare(&q, "%s", blob_sql_text(&sql));
162 blob_reset(&sql);
163 pay = cson_new_object();
164 while( (SQLITE_ROW==db_step(&q)) ){
165 cson_object_set(pay,
166 db_column_text(&q,0),
167
--- src/json_finfo.c
+++ src/json_finfo.c
@@ -62,11 +62,11 @@
6262
zBefore = json_find_option_cstr("before",NULL,"b");
6363
zAfter = json_find_option_cstr("after",NULL,"a");
6464
limit = json_find_option_int("limit",NULL,"n", -1);
6565
zCheckin = json_find_option_cstr("checkin",NULL,"ci");
6666
67
- blob_appendf(&sql,
67
+ blob_append_sql(&sql,
6868
/*0*/ "SELECT b.uuid,"
6969
/*1*/ " ci.uuid,"
7070
/*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
7171
/*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER),"
7272
/*4*/ " coalesce(event.euser, event.user),"
@@ -93,25 +93,24 @@
9393
json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
9494
"Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
9595
blob_reset(&sql);
9696
return NULL;
9797
}
98
- blob_appendf(&sql, " AND ci.uuid='%q'", zU);
98
+ blob_append_sql(&sql, " AND ci.uuid='%q'", zU);
9999
free(zU);
100100
}else{
101101
if( zAfter && *zAfter ){
102
- blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter);
102
+ blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zAfter);
103103
sort = 1;
104104
}else if( zBefore && *zBefore ){
105
- blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore);
105
+ blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zBefore);
106106
}
107107
}
108108
109
- blob_appendf(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
109
+ blob_append_sql(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
110110
/*printf("SQL=\n%s\n",blob_str(&sql));*/
111
- db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding
112
- SQL escapes*/);
111
+ db_prepare(&q, "%s", blob_sql_text(&sql));
113112
blob_reset(&sql);
114113
115114
pay = cson_new_object();
116115
cson_object_set(pay, "name", json_new_string(zFilename));
117116
if( limit > 0 ){
118117
--- src/json_finfo.c
+++ src/json_finfo.c
@@ -62,11 +62,11 @@
62 zBefore = json_find_option_cstr("before",NULL,"b");
63 zAfter = json_find_option_cstr("after",NULL,"a");
64 limit = json_find_option_int("limit",NULL,"n", -1);
65 zCheckin = json_find_option_cstr("checkin",NULL,"ci");
66
67 blob_appendf(&sql,
68 /*0*/ "SELECT b.uuid,"
69 /*1*/ " ci.uuid,"
70 /*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
71 /*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER),"
72 /*4*/ " coalesce(event.euser, event.user),"
@@ -93,25 +93,24 @@
93 json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
94 "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
95 blob_reset(&sql);
96 return NULL;
97 }
98 blob_appendf(&sql, " AND ci.uuid='%q'", zU);
99 free(zU);
100 }else{
101 if( zAfter && *zAfter ){
102 blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter);
103 sort = 1;
104 }else if( zBefore && *zBefore ){
105 blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore);
106 }
107 }
108
109 blob_appendf(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
110 /*printf("SQL=\n%s\n",blob_str(&sql));*/
111 db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding
112 SQL escapes*/);
113 blob_reset(&sql);
114
115 pay = cson_new_object();
116 cson_object_set(pay, "name", json_new_string(zFilename));
117 if( limit > 0 ){
118
--- src/json_finfo.c
+++ src/json_finfo.c
@@ -62,11 +62,11 @@
62 zBefore = json_find_option_cstr("before",NULL,"b");
63 zAfter = json_find_option_cstr("after",NULL,"a");
64 limit = json_find_option_int("limit",NULL,"n", -1);
65 zCheckin = json_find_option_cstr("checkin",NULL,"ci");
66
67 blob_append_sql(&sql,
68 /*0*/ "SELECT b.uuid,"
69 /*1*/ " ci.uuid,"
70 /*2*/ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */
71 /*3*/ " cast(strftime('%%s',event.mtime) AS INTEGER),"
72 /*4*/ " coalesce(event.euser, event.user),"
@@ -93,25 +93,24 @@
93 json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
94 "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found");
95 blob_reset(&sql);
96 return NULL;
97 }
98 blob_append_sql(&sql, " AND ci.uuid='%q'", zU);
99 free(zU);
100 }else{
101 if( zAfter && *zAfter ){
102 blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zAfter);
103 sort = 1;
104 }else if( zBefore && *zBefore ){
105 blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zBefore);
106 }
107 }
108
109 blob_append_sql(&sql," ORDER BY event.mtime %s /*sort*/", (sort>0?"ASC":"DESC"));
110 /*printf("SQL=\n%s\n",blob_str(&sql));*/
111 db_prepare(&q, "%s", blob_sql_text(&sql));
 
112 blob_reset(&sql);
113
114 pay = cson_new_object();
115 cson_object_set(pay, "name", json_new_string(zFilename));
116 if( limit > 0 ){
117
--- src/json_query.c
+++ src/json_query.c
@@ -64,11 +64,11 @@
6464
return NULL;
6565
}
6666
6767
zFmt = json_find_option_cstr2("format",NULL,"f",3);
6868
if(!zFmt) zFmt = "o";
69
- db_prepare(&q,"%s", zSql);
69
+ db_prepare(&q,"%s", zSql/*safe-for-%s*/);
7070
if( 0 == sqlite3_column_count( q.pStmt ) ){
7171
json_set_err(FSL_JSON_E_USAGE,
7272
"Input query has no result columns. "
7373
"Only SELECT-like queries are supported.");
7474
db_finalize(&q);
7575
--- src/json_query.c
+++ src/json_query.c
@@ -64,11 +64,11 @@
64 return NULL;
65 }
66
67 zFmt = json_find_option_cstr2("format",NULL,"f",3);
68 if(!zFmt) zFmt = "o";
69 db_prepare(&q,"%s", zSql);
70 if( 0 == sqlite3_column_count( q.pStmt ) ){
71 json_set_err(FSL_JSON_E_USAGE,
72 "Input query has no result columns. "
73 "Only SELECT-like queries are supported.");
74 db_finalize(&q);
75
--- src/json_query.c
+++ src/json_query.c
@@ -64,11 +64,11 @@
64 return NULL;
65 }
66
67 zFmt = json_find_option_cstr2("format",NULL,"f",3);
68 if(!zFmt) zFmt = "o";
69 db_prepare(&q,"%s", zSql/*safe-for-%s*/);
70 if( 0 == sqlite3_column_count( q.pStmt ) ){
71 json_set_err(FSL_JSON_E_USAGE,
72 "Input query has no result columns. "
73 "Only SELECT-like queries are supported.");
74 db_finalize(&q);
75
--- src/json_report.c
+++ src/json_report.c
@@ -204,11 +204,11 @@
204204
205205
/* Copy over report's SQL...*/
206206
blob_append(&sql, db_column_text(&q,0), -1);
207207
zTitle = mprintf("%s", db_column_text(&q,1));
208208
db_finalize(&q);
209
- db_prepare(&q, "%s", blob_str(&sql));
209
+ db_prepare(&q, "%s", blob_sql_text(&sql));
210210
211211
/** Build the response... */
212212
pay = cson_new_object();
213213
214214
cson_object_set(pay, "report", json_new_int(nReport));
215215
--- src/json_report.c
+++ src/json_report.c
@@ -204,11 +204,11 @@
204
205 /* Copy over report's SQL...*/
206 blob_append(&sql, db_column_text(&q,0), -1);
207 zTitle = mprintf("%s", db_column_text(&q,1));
208 db_finalize(&q);
209 db_prepare(&q, "%s", blob_str(&sql));
210
211 /** Build the response... */
212 pay = cson_new_object();
213
214 cson_object_set(pay, "report", json_new_int(nReport));
215
--- src/json_report.c
+++ src/json_report.c
@@ -204,11 +204,11 @@
204
205 /* Copy over report's SQL...*/
206 blob_append(&sql, db_column_text(&q,0), -1);
207 zTitle = mprintf("%s", db_column_text(&q,1));
208 db_finalize(&q);
209 db_prepare(&q, "%s", blob_sql_text(&sql));
210
211 /** Build the response... */
212 pay = cson_new_object();
213
214 cson_object_set(pay, "report", json_new_int(nReport));
215
+2 -2
--- src/json_tag.c
+++ src/json_tag.c
@@ -301,11 +301,11 @@
301301
" SELECT rid FROM tagxref"
302302
" WHERE tagtype>0 AND tagid=%d"
303303
" )"
304304
" ORDER BY event.mtime DESC"
305305
"%s LIMIT %d",
306
- zSqlBase, zType, tagid,
306
+ zSqlBase /*safe-for-%s*/, zType, tagid,
307307
(limit>0)?"":"--", limit
308308
);
309309
listV = json_stmt_to_array_of_obj(&q, NULL);
310310
db_finalize(&q);
311311
}
@@ -442,11 +442,11 @@
442442
if(!fTicket){
443443
blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
444444
}
445445
blob_append(&sql,
446446
" ORDER BY tagname", -1);
447
- db_prepare(&q, blob_buffer(&sql));
447
+ db_prepare(&q, "%s", blob_sql_text(&sql));
448448
blob_reset(&sql);
449449
cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
450450
while( SQLITE_ROW == db_step(&q) ){
451451
const char *zName = db_column_text(&q, 0);
452452
if(NULL==arV){
453453
--- src/json_tag.c
+++ src/json_tag.c
@@ -301,11 +301,11 @@
301 " SELECT rid FROM tagxref"
302 " WHERE tagtype>0 AND tagid=%d"
303 " )"
304 " ORDER BY event.mtime DESC"
305 "%s LIMIT %d",
306 zSqlBase, zType, tagid,
307 (limit>0)?"":"--", limit
308 );
309 listV = json_stmt_to_array_of_obj(&q, NULL);
310 db_finalize(&q);
311 }
@@ -442,11 +442,11 @@
442 if(!fTicket){
443 blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
444 }
445 blob_append(&sql,
446 " ORDER BY tagname", -1);
447 db_prepare(&q, blob_buffer(&sql));
448 blob_reset(&sql);
449 cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
450 while( SQLITE_ROW == db_step(&q) ){
451 const char *zName = db_column_text(&q, 0);
452 if(NULL==arV){
453
--- src/json_tag.c
+++ src/json_tag.c
@@ -301,11 +301,11 @@
301 " SELECT rid FROM tagxref"
302 " WHERE tagtype>0 AND tagid=%d"
303 " )"
304 " ORDER BY event.mtime DESC"
305 "%s LIMIT %d",
306 zSqlBase /*safe-for-%s*/, zType, tagid,
307 (limit>0)?"":"--", limit
308 );
309 listV = json_stmt_to_array_of_obj(&q, NULL);
310 db_finalize(&q);
311 }
@@ -442,11 +442,11 @@
442 if(!fTicket){
443 blob_append(&sql, " AND tagname NOT GLOB('tkt-*') ", -1);
444 }
445 blob_append(&sql,
446 " ORDER BY tagname", -1);
447 db_prepare(&q, "%s", blob_sql_text(&sql));
448 blob_reset(&sql);
449 cson_object_set(pay, "includeTickets", cson_value_new_bool(fTicket) );
450 while( SQLITE_ROW == db_step(&q) ){
451 const char *zName = db_column_text(&q, 0);
452 if(NULL==arV){
453
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -83,11 +83,11 @@
8383
@ tags TEXT,
8484
@ tagId INTEGER,
8585
@ brief TEXT
8686
@ )
8787
;
88
- db_multi_exec(zSql);
88
+ db_multi_exec("%s", zSql /*safe-for-%s*/);
8989
}
9090
9191
/*
9292
** Return a pointer to a constant string that forms the basis
9393
** for a timeline query for the JSON interface.
@@ -384,21 +384,21 @@
384384
" bgcolor as bgColor"
385385
" FROM event JOIN blob"
386386
" WHERE blob.rid=event.objid",
387387
-1);
388388
389
- blob_appendf(&sql,
389
+ blob_append_sql(&sql,
390390
" AND event.type='ci'"
391391
" AND blob.rid IN (SELECT rid FROM tagxref"
392392
" WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
393393
" ORDER BY event.mtime DESC",
394394
TAG_BRANCH);
395395
limit = json_timeline_limit(20);
396396
if(limit>0){
397
- blob_appendf(&sql," LIMIT %d ",limit);
397
+ blob_append_sql(&sql," LIMIT %d ",limit);
398398
}
399
- db_prepare(&q,"%s", blob_str(&sql));
399
+ db_prepare(&q,"%s", blob_sql_text(&sql));
400400
blob_reset(&sql);
401401
pay = json_stmt_to_array_of_obj(&q, NULL);
402402
db_finalize(&q);
403403
assert(NULL != pay);
404404
if(pay){
@@ -482,11 +482,11 @@
482482
#if 0
483483
/* only for testing! */
484484
tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
485485
SET("timelineSql");
486486
#endif
487
- db_multi_exec(blob_buffer(&sql));
487
+ db_multi_exec("%s", blob_buffer(&sql)/*safe-for-%s*/);
488488
blob_reset(&sql);
489489
db_prepare(&q, "SELECT "
490490
" rid AS rid"
491491
" FROM json_timeline"
492492
" ORDER BY rowid");
@@ -547,11 +547,11 @@
547547
#if 0
548548
/* only for testing! */
549549
tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550550
SET("timelineSql");
551551
#endif
552
- db_multi_exec(blob_buffer(&sql));
552
+ db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
553553
blob_reset(&sql);
554554
db_prepare(&q, "SELECT"
555555
" uuid AS uuid,"
556556
" mtime AS timestamp,"
557557
#if 0
@@ -565,12 +565,11 @@
565565
" tags AS tags," /*FIXME: split this into
566566
a JSON array*/
567567
" tagId AS tagId,"
568568
#endif
569569
" FROM json_timeline"
570
- " ORDER BY rowid",
571
- -1);
570
+ " ORDER BY rowid");
572571
list = cson_new_array();
573572
json_stmt_to_array_of_obj(&q, list);
574573
cson_object_set(pay, "timeline", cson_array_value(list));
575574
goto ok;
576575
error:
@@ -607,11 +606,11 @@
607606
if(check){
608607
json_set_err(check, "Query initialization failed.");
609608
goto error;
610609
}
611610
612
- db_multi_exec(blob_buffer(&sql));
611
+ db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
613612
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
614613
json_set_err((cson_rc.AllocError==check) \
615614
? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
616615
"Object property insertion failed."); \
617616
goto error;\
@@ -638,12 +637,11 @@
638637
" user AS user,"
639638
" eventType AS eventType,"
640639
" comment AS comment,"
641640
" brief AS briefComment"
642641
" FROM json_timeline"
643
- " ORDER BY rowid",
644
- -1);
642
+ " ORDER BY rowid");
645643
listV = cson_value_new_array();
646644
list = cson_value_get_array(listV);
647645
tmp = listV;
648646
SET("timeline");
649647
while( (SQLITE_ROW == db_step(&q) )){
650648
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -83,11 +83,11 @@
83 @ tags TEXT,
84 @ tagId INTEGER,
85 @ brief TEXT
86 @ )
87 ;
88 db_multi_exec(zSql);
89 }
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface.
@@ -384,21 +384,21 @@
384 " bgcolor as bgColor"
385 " FROM event JOIN blob"
386 " WHERE blob.rid=event.objid",
387 -1);
388
389 blob_appendf(&sql,
390 " AND event.type='ci'"
391 " AND blob.rid IN (SELECT rid FROM tagxref"
392 " WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
393 " ORDER BY event.mtime DESC",
394 TAG_BRANCH);
395 limit = json_timeline_limit(20);
396 if(limit>0){
397 blob_appendf(&sql," LIMIT %d ",limit);
398 }
399 db_prepare(&q,"%s", blob_str(&sql));
400 blob_reset(&sql);
401 pay = json_stmt_to_array_of_obj(&q, NULL);
402 db_finalize(&q);
403 assert(NULL != pay);
404 if(pay){
@@ -482,11 +482,11 @@
482 #if 0
483 /* only for testing! */
484 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
485 SET("timelineSql");
486 #endif
487 db_multi_exec(blob_buffer(&sql));
488 blob_reset(&sql);
489 db_prepare(&q, "SELECT "
490 " rid AS rid"
491 " FROM json_timeline"
492 " ORDER BY rowid");
@@ -547,11 +547,11 @@
547 #if 0
548 /* only for testing! */
549 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550 SET("timelineSql");
551 #endif
552 db_multi_exec(blob_buffer(&sql));
553 blob_reset(&sql);
554 db_prepare(&q, "SELECT"
555 " uuid AS uuid,"
556 " mtime AS timestamp,"
557 #if 0
@@ -565,12 +565,11 @@
565 " tags AS tags," /*FIXME: split this into
566 a JSON array*/
567 " tagId AS tagId,"
568 #endif
569 " FROM json_timeline"
570 " ORDER BY rowid",
571 -1);
572 list = cson_new_array();
573 json_stmt_to_array_of_obj(&q, list);
574 cson_object_set(pay, "timeline", cson_array_value(list));
575 goto ok;
576 error:
@@ -607,11 +606,11 @@
607 if(check){
608 json_set_err(check, "Query initialization failed.");
609 goto error;
610 }
611
612 db_multi_exec(blob_buffer(&sql));
613 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
614 json_set_err((cson_rc.AllocError==check) \
615 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
616 "Object property insertion failed."); \
617 goto error;\
@@ -638,12 +637,11 @@
638 " user AS user,"
639 " eventType AS eventType,"
640 " comment AS comment,"
641 " brief AS briefComment"
642 " FROM json_timeline"
643 " ORDER BY rowid",
644 -1);
645 listV = cson_value_new_array();
646 list = cson_value_get_array(listV);
647 tmp = listV;
648 SET("timeline");
649 while( (SQLITE_ROW == db_step(&q) )){
650
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -83,11 +83,11 @@
83 @ tags TEXT,
84 @ tagId INTEGER,
85 @ brief TEXT
86 @ )
87 ;
88 db_multi_exec("%s", zSql /*safe-for-%s*/);
89 }
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface.
@@ -384,21 +384,21 @@
384 " bgcolor as bgColor"
385 " FROM event JOIN blob"
386 " WHERE blob.rid=event.objid",
387 -1);
388
389 blob_append_sql(&sql,
390 " AND event.type='ci'"
391 " AND blob.rid IN (SELECT rid FROM tagxref"
392 " WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
393 " ORDER BY event.mtime DESC",
394 TAG_BRANCH);
395 limit = json_timeline_limit(20);
396 if(limit>0){
397 blob_append_sql(&sql," LIMIT %d ",limit);
398 }
399 db_prepare(&q,"%s", blob_sql_text(&sql));
400 blob_reset(&sql);
401 pay = json_stmt_to_array_of_obj(&q, NULL);
402 db_finalize(&q);
403 assert(NULL != pay);
404 if(pay){
@@ -482,11 +482,11 @@
482 #if 0
483 /* only for testing! */
484 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
485 SET("timelineSql");
486 #endif
487 db_multi_exec("%s", blob_buffer(&sql)/*safe-for-%s*/);
488 blob_reset(&sql);
489 db_prepare(&q, "SELECT "
490 " rid AS rid"
491 " FROM json_timeline"
492 " ORDER BY rowid");
@@ -547,11 +547,11 @@
547 #if 0
548 /* only for testing! */
549 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550 SET("timelineSql");
551 #endif
552 db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
553 blob_reset(&sql);
554 db_prepare(&q, "SELECT"
555 " uuid AS uuid,"
556 " mtime AS timestamp,"
557 #if 0
@@ -565,12 +565,11 @@
565 " tags AS tags," /*FIXME: split this into
566 a JSON array*/
567 " tagId AS tagId,"
568 #endif
569 " FROM json_timeline"
570 " ORDER BY rowid");
 
571 list = cson_new_array();
572 json_stmt_to_array_of_obj(&q, list);
573 cson_object_set(pay, "timeline", cson_array_value(list));
574 goto ok;
575 error:
@@ -607,11 +606,11 @@
606 if(check){
607 json_set_err(check, "Query initialization failed.");
608 goto error;
609 }
610
611 db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
612 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
613 json_set_err((cson_rc.AllocError==check) \
614 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
615 "Object property insertion failed."); \
616 goto error;\
@@ -638,12 +637,11 @@
637 " user AS user,"
638 " eventType AS eventType,"
639 " comment AS comment,"
640 " brief AS briefComment"
641 " FROM json_timeline"
642 " ORDER BY rowid");
 
643 listV = cson_value_new_array();
644 list = cson_value_get_array(listV);
645 tmp = listV;
646 SET("timeline");
647 while( (SQLITE_ROW == db_step(&q) )){
648
+9 -9
--- src/json_user.c
+++ src/json_user.c
@@ -286,11 +286,11 @@
286286
/* reminders: 1) does not allocate.
287287
2) we do this because changing a name
288288
invalidates any login token because the old name
289289
is part of the token hash.
290290
*/;
291
- blob_appendf(&sql, ", login=%Q", zNameNew);
291
+ blob_append_sql(&sql, ", login=%Q", zNameNew);
292292
++gotFields;
293293
}
294294
}
295295
296296
if( zCap && *zCap ){
@@ -298,11 +298,11 @@
298298
/* we "could" arguably silently ignore cap in this case. */
299299
json_set_err(FSL_JSON_E_DENIED,
300300
"Changing capabilities requires 'a' or 's' privileges.");
301301
goto error;
302302
}
303
- blob_appendf(&sql, ", cap=%Q", zCap);
303
+ blob_append_sql(&sql, ", cap=%Q", zCap);
304304
++gotFields;
305305
}
306306
307307
if( zPW && *zPW ){
308308
if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
@@ -314,24 +314,24 @@
314314
#define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
315315
#if !TRY_LOGIN_GROUP
316316
char * zPWHash = NULL;
317317
++gotFields;
318318
zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
319
- blob_appendf(&sql, ", pw=%Q", zPWHash);
319
+ blob_append_sql(&sql, ", pw=%Q", zPWHash);
320320
free(zPWHash);
321321
#else
322322
++gotFields;
323
- blob_appendf(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
323
+ blob_append_sql(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
324324
"(SELECT value FROM config WHERE name='project-code')))",
325325
zPW, zNameNew ? zNameNew : zName);
326326
/* shared_secret() func is undefined? */
327327
#endif
328328
}
329329
}
330330
331331
if( zInfo ){
332
- blob_appendf(&sql, ", info=%Q", zInfo);
332
+ blob_append_sql(&sql, ", info=%Q", zInfo);
333333
++gotFields;
334334
}
335335
336336
if((g.perm.Admin || g.perm.Setup)
337337
&& forceLogout && cson_value_get_bool(forceLogout)){
@@ -344,26 +344,26 @@
344344
"Required user data are missing.");
345345
goto error;
346346
}
347347
assert(uid>0);
348348
#if !TRY_LOGIN_GROUP
349
- blob_appendf(&sql, " WHERE uid=%d", uid);
349
+ blob_append_sql(&sql, " WHERE uid=%d", uid);
350350
#else /* need name for login group support :/ */
351
- blob_appendf(&sql, " WHERE login=%Q", zName);
351
+ blob_append_sql(&sql, " WHERE login=%Q", zName);
352352
#endif
353353
#if 0
354354
puts(blob_str(&sql));
355355
cson_output_FILE( cson_object_value(pUser), stdout, NULL );
356356
#endif
357
- db_prepare(&q, "%s", blob_str(&sql));
357
+ db_prepare(&q, "%s", blob_sql_text(&sql));
358358
db_exec(&q);
359359
db_finalize(&q);
360360
#if TRY_LOGIN_GROUP
361361
if( zPW || cson_value_get_bool(forceLogout) ){
362362
Blob groupSql = empty_blob;
363363
char * zErr = NULL;
364
- blob_appendf(&groupSql,
364
+ blob_append_sql(&groupSql,
365365
"INSERT INTO user(login)"
366366
" SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
367367
zName, zName
368368
);
369369
blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
370370
--- src/json_user.c
+++ src/json_user.c
@@ -286,11 +286,11 @@
286 /* reminders: 1) does not allocate.
287 2) we do this because changing a name
288 invalidates any login token because the old name
289 is part of the token hash.
290 */;
291 blob_appendf(&sql, ", login=%Q", zNameNew);
292 ++gotFields;
293 }
294 }
295
296 if( zCap && *zCap ){
@@ -298,11 +298,11 @@
298 /* we "could" arguably silently ignore cap in this case. */
299 json_set_err(FSL_JSON_E_DENIED,
300 "Changing capabilities requires 'a' or 's' privileges.");
301 goto error;
302 }
303 blob_appendf(&sql, ", cap=%Q", zCap);
304 ++gotFields;
305 }
306
307 if( zPW && *zPW ){
308 if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
@@ -314,24 +314,24 @@
314 #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
315 #if !TRY_LOGIN_GROUP
316 char * zPWHash = NULL;
317 ++gotFields;
318 zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
319 blob_appendf(&sql, ", pw=%Q", zPWHash);
320 free(zPWHash);
321 #else
322 ++gotFields;
323 blob_appendf(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
324 "(SELECT value FROM config WHERE name='project-code')))",
325 zPW, zNameNew ? zNameNew : zName);
326 /* shared_secret() func is undefined? */
327 #endif
328 }
329 }
330
331 if( zInfo ){
332 blob_appendf(&sql, ", info=%Q", zInfo);
333 ++gotFields;
334 }
335
336 if((g.perm.Admin || g.perm.Setup)
337 && forceLogout && cson_value_get_bool(forceLogout)){
@@ -344,26 +344,26 @@
344 "Required user data are missing.");
345 goto error;
346 }
347 assert(uid>0);
348 #if !TRY_LOGIN_GROUP
349 blob_appendf(&sql, " WHERE uid=%d", uid);
350 #else /* need name for login group support :/ */
351 blob_appendf(&sql, " WHERE login=%Q", zName);
352 #endif
353 #if 0
354 puts(blob_str(&sql));
355 cson_output_FILE( cson_object_value(pUser), stdout, NULL );
356 #endif
357 db_prepare(&q, "%s", blob_str(&sql));
358 db_exec(&q);
359 db_finalize(&q);
360 #if TRY_LOGIN_GROUP
361 if( zPW || cson_value_get_bool(forceLogout) ){
362 Blob groupSql = empty_blob;
363 char * zErr = NULL;
364 blob_appendf(&groupSql,
365 "INSERT INTO user(login)"
366 " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
367 zName, zName
368 );
369 blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
370
--- src/json_user.c
+++ src/json_user.c
@@ -286,11 +286,11 @@
286 /* reminders: 1) does not allocate.
287 2) we do this because changing a name
288 invalidates any login token because the old name
289 is part of the token hash.
290 */;
291 blob_append_sql(&sql, ", login=%Q", zNameNew);
292 ++gotFields;
293 }
294 }
295
296 if( zCap && *zCap ){
@@ -298,11 +298,11 @@
298 /* we "could" arguably silently ignore cap in this case. */
299 json_set_err(FSL_JSON_E_DENIED,
300 "Changing capabilities requires 'a' or 's' privileges.");
301 goto error;
302 }
303 blob_append_sql(&sql, ", cap=%Q", zCap);
304 ++gotFields;
305 }
306
307 if( zPW && *zPW ){
308 if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
@@ -314,24 +314,24 @@
314 #define TRY_LOGIN_GROUP 0 /* login group support is not yet implemented. */
315 #if !TRY_LOGIN_GROUP
316 char * zPWHash = NULL;
317 ++gotFields;
318 zPWHash = sha1_shared_secret(zPW, zNameNew ? zNameNew : zName, NULL);
319 blob_append_sql(&sql, ", pw=%Q", zPWHash);
320 free(zPWHash);
321 #else
322 ++gotFields;
323 blob_append_sql(&sql, ", pw=coalesce(shared_secret(%Q,%Q,"
324 "(SELECT value FROM config WHERE name='project-code')))",
325 zPW, zNameNew ? zNameNew : zName);
326 /* shared_secret() func is undefined? */
327 #endif
328 }
329 }
330
331 if( zInfo ){
332 blob_append_sql(&sql, ", info=%Q", zInfo);
333 ++gotFields;
334 }
335
336 if((g.perm.Admin || g.perm.Setup)
337 && forceLogout && cson_value_get_bool(forceLogout)){
@@ -344,26 +344,26 @@
344 "Required user data are missing.");
345 goto error;
346 }
347 assert(uid>0);
348 #if !TRY_LOGIN_GROUP
349 blob_append_sql(&sql, " WHERE uid=%d", uid);
350 #else /* need name for login group support :/ */
351 blob_append_sql(&sql, " WHERE login=%Q", zName);
352 #endif
353 #if 0
354 puts(blob_str(&sql));
355 cson_output_FILE( cson_object_value(pUser), stdout, NULL );
356 #endif
357 db_prepare(&q, "%s", blob_sql_text(&sql));
358 db_exec(&q);
359 db_finalize(&q);
360 #if TRY_LOGIN_GROUP
361 if( zPW || cson_value_get_bool(forceLogout) ){
362 Blob groupSql = empty_blob;
363 char * zErr = NULL;
364 blob_append_sql(&groupSql,
365 "INSERT INTO user(login)"
366 " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
367 zName, zName
368 );
369 blob_append(&groupSql, blob_str(&sql), blob_size(&sql));
370
+5 -6
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -444,22 +444,21 @@
444444
" substr(tagname,6) as name"
445445
" FROM tag WHERE tagname GLOB 'wiki-*'",
446446
-1);
447447
zGlob = json_find_option_cstr("glob",NULL,"g");
448448
if(zGlob && *zGlob){
449
- blob_appendf(&sql," AND name %s GLOB %Q",
450
- fInvert ? "NOT" : "", zGlob);
449
+ blob_append_sql(&sql," AND name %s GLOB %Q",
450
+ fInvert ? "NOT" : "", zGlob);
451451
}else{
452452
zGlob = json_find_option_cstr("like",NULL,"l");
453453
if(zGlob && *zGlob){
454
- blob_appendf(&sql," AND name %s LIKE %Q",
455
- fInvert ? "NOT" : "",
456
- zGlob);
454
+ blob_append_sql(&sql," AND name %s LIKE %Q",
455
+ fInvert ? "NOT" : "", zGlob);
457456
}
458457
}
459458
blob_append(&sql," ORDER BY lower(name)", -1);
460
- db_prepare(&q,"%s", blob_str(&sql));
459
+ db_prepare(&q,"%s", blob_sql_text(&sql));
461460
blob_reset(&sql);
462461
listV = cson_value_new_array();
463462
list = cson_value_get_array(listV);
464463
while( SQLITE_ROW == db_step(&q) ){
465464
cson_value * v;
466465
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -444,22 +444,21 @@
444 " substr(tagname,6) as name"
445 " FROM tag WHERE tagname GLOB 'wiki-*'",
446 -1);
447 zGlob = json_find_option_cstr("glob",NULL,"g");
448 if(zGlob && *zGlob){
449 blob_appendf(&sql," AND name %s GLOB %Q",
450 fInvert ? "NOT" : "", zGlob);
451 }else{
452 zGlob = json_find_option_cstr("like",NULL,"l");
453 if(zGlob && *zGlob){
454 blob_appendf(&sql," AND name %s LIKE %Q",
455 fInvert ? "NOT" : "",
456 zGlob);
457 }
458 }
459 blob_append(&sql," ORDER BY lower(name)", -1);
460 db_prepare(&q,"%s", blob_str(&sql));
461 blob_reset(&sql);
462 listV = cson_value_new_array();
463 list = cson_value_get_array(listV);
464 while( SQLITE_ROW == db_step(&q) ){
465 cson_value * v;
466
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -444,22 +444,21 @@
444 " substr(tagname,6) as name"
445 " FROM tag WHERE tagname GLOB 'wiki-*'",
446 -1);
447 zGlob = json_find_option_cstr("glob",NULL,"g");
448 if(zGlob && *zGlob){
449 blob_append_sql(&sql," AND name %s GLOB %Q",
450 fInvert ? "NOT" : "", zGlob);
451 }else{
452 zGlob = json_find_option_cstr("like",NULL,"l");
453 if(zGlob && *zGlob){
454 blob_append_sql(&sql," AND name %s LIKE %Q",
455 fInvert ? "NOT" : "", zGlob);
 
456 }
457 }
458 blob_append(&sql," ORDER BY lower(name)", -1);
459 db_prepare(&q,"%s", blob_sql_text(&sql));
460 blob_reset(&sql);
461 listV = cson_value_new_array();
462 list = cson_value_get_array(listV);
463 while( SQLITE_ROW == db_step(&q) ){
464 cson_value * v;
465
+3 -2
--- src/leaf.c
+++ src/leaf.c
@@ -39,11 +39,12 @@
3939
@ AND coalesce((SELECT value FROM tagxref
4040
@ WHERE tagid=%d AND rid=plink.pid), 'trunk')
4141
@ =coalesce((SELECT value FROM tagxref
4242
@ WHERE tagid=%d AND rid=plink.cid), 'trunk')
4343
;
44
- rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
44
+ rc = db_int(0, zSql /*works-like:"%d,%d,%d"*/,
45
+ rid, TAG_BRANCH, TAG_BRANCH);
4546
return rc==0;
4647
}
4748
4849
/*
4950
** Count the number of primary non-branch children for the given check-in.
@@ -63,11 +64,11 @@
6364
@ AND coalesce((SELECT value FROM tagxref
6465
@ WHERE tagid=%d AND rid=plink.pid), 'trunk')
6566
@ =coalesce((SELECT value FROM tagxref
6667
@ WHERE tagid=%d AND rid=plink.cid), 'trunk')
6768
;
68
- db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH);
69
+ db_static_prepare(&q, zSql /*works-like: "%d,%d"*/, TAG_BRANCH, TAG_BRANCH);
6970
db_bind_int(&q, ":pid", pid);
7071
if( db_step(&q)==SQLITE_ROW ){
7172
nNonBranch = db_column_int(&q, 0);
7273
}
7374
db_reset(&q);
7475
--- src/leaf.c
+++ src/leaf.c
@@ -39,11 +39,12 @@
39 @ AND coalesce((SELECT value FROM tagxref
40 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
41 @ =coalesce((SELECT value FROM tagxref
42 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
43 ;
44 rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
 
45 return rc==0;
46 }
47
48 /*
49 ** Count the number of primary non-branch children for the given check-in.
@@ -63,11 +64,11 @@
63 @ AND coalesce((SELECT value FROM tagxref
64 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
65 @ =coalesce((SELECT value FROM tagxref
66 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
67 ;
68 db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH);
69 db_bind_int(&q, ":pid", pid);
70 if( db_step(&q)==SQLITE_ROW ){
71 nNonBranch = db_column_int(&q, 0);
72 }
73 db_reset(&q);
74
--- src/leaf.c
+++ src/leaf.c
@@ -39,11 +39,12 @@
39 @ AND coalesce((SELECT value FROM tagxref
40 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
41 @ =coalesce((SELECT value FROM tagxref
42 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
43 ;
44 rc = db_int(0, zSql /*works-like:"%d,%d,%d"*/,
45 rid, TAG_BRANCH, TAG_BRANCH);
46 return rc==0;
47 }
48
49 /*
50 ** Count the number of primary non-branch children for the given check-in.
@@ -63,11 +64,11 @@
64 @ AND coalesce((SELECT value FROM tagxref
65 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
66 @ =coalesce((SELECT value FROM tagxref
67 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
68 ;
69 db_static_prepare(&q, zSql /*works-like: "%d,%d"*/, TAG_BRANCH, TAG_BRANCH);
70 db_bind_int(&q, ":pid", pid);
71 if( db_step(&q)==SQLITE_ROW ){
72 nNonBranch = db_column_int(&q, 0);
73 }
74 db_reset(&q);
75
+1 -1
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -27,11 +27,11 @@
2727
*/
2828
double load_average(void){
2929
#if !defined(_WIN32) && !defined(FOSSIL_OMIT_LOAD_AVERAGE)
3030
double a[3];
3131
if( getloadavg(a, 3)>0 ){
32
- return a[0];
32
+ return a[0]>=0.000001 ? a[0] : 0.000001;
3333
}
3434
#endif
3535
return 0.0;
3636
}
3737
3838
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -27,11 +27,11 @@
27 */
28 double load_average(void){
29 #if !defined(_WIN32) && !defined(FOSSIL_OMIT_LOAD_AVERAGE)
30 double a[3];
31 if( getloadavg(a, 3)>0 ){
32 return a[0];
33 }
34 #endif
35 return 0.0;
36 }
37
38
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -27,11 +27,11 @@
27 */
28 double load_average(void){
29 #if !defined(_WIN32) && !defined(FOSSIL_OMIT_LOAD_AVERAGE)
30 double a[3];
31 if( getloadavg(a, 3)>0 ){
32 return a[0]>=0.000001 ? a[0] : 0.000001;
33 }
34 #endif
35 return 0.0;
36 }
37
38
+13 -13
--- src/login.c
+++ src/login.c
@@ -395,15 +395,15 @@
395395
/* If a URI appears in the User-Agent, it is probably a bot */
396396
if( strncmp("http", zAgent+i,4)==0 ) return 0;
397397
}
398398
if( strncmp(zAgent, "Mozilla/", 8)==0 ){
399399
if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
400
- if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
401
- if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
402
- if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
403
- if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */
404
- if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
400
+ if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1;
401
+ if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1;
402
+ if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1;
403
+ if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */
404
+ if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1;
405405
return 0;
406406
}
407407
if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
408408
if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
409409
if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1294,11 +1294,11 @@
12941294
}else{
12951295
char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
12961296
int uid;
12971297
db_multi_exec(
12981298
"INSERT INTO user(login,pw,cap,info,mtime)"
1299
- "VALUES(%B,%Q,%B,%B,strftime('%s','now'))",
1299
+ "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
13001300
&login, zPw, &caps, &contact
13011301
);
13021302
free(zPw);
13031303
13041304
/* The user is registered, now just log him in. */
@@ -1469,17 +1469,17 @@
14691469
*pzErrMsg = 0; /* Default to no errors */
14701470
zSelf = db_name("repository");
14711471
14721472
/* Get the full pathname of the other repository */
14731473
file_canonical_name(zRepo, &fullName, 0);
1474
- zRepo = mprintf(blob_str(&fullName));
1474
+ zRepo = fossil_strdup(blob_str(&fullName));
14751475
blob_reset(&fullName);
14761476
14771477
/* Get the full pathname for our repository. Also the project code
14781478
** and project name for ourself. */
14791479
file_canonical_name(g.zRepositoryName, &fullName, 0);
1480
- zSelfRepo = mprintf(blob_str(&fullName));
1480
+ zSelfRepo = fossil_strdup(blob_str(&fullName));
14811481
blob_reset(&fullName);
14821482
zSelfProjCode = db_get("project-code", "unknown");
14831483
zSelfLabel = db_get("project-name", 0);
14841484
if( zSelfLabel==0 ){
14851485
zSelfLabel = zSelfProjCode;
@@ -1500,11 +1500,11 @@
15001500
zRepo, &pOther,
15011501
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
15021502
g.zVfsName
15031503
);
15041504
if( rc!=SQLITE_OK ){
1505
- *pzErrMsg = mprintf(sqlite3_errmsg(pOther));
1505
+ *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther));
15061506
}else{
15071507
rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
15081508
}
15091509
sqlite3_close(pOther);
15101510
if( rc ) return;
@@ -1533,13 +1533,13 @@
15331533
*/
15341534
zSelfProjCode = abbreviated_project_code(zSelfProjCode);
15351535
zOtherProjCode = abbreviated_project_code(zOtherProjCode);
15361536
db_begin_transaction();
15371537
db_multi_exec(
1538
- "DELETE FROM %s.config WHERE name GLOB 'peer-*';"
1539
- "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);"
1540
- "INSERT INTO %s.config(name,value) "
1538
+ "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';"
1539
+ "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);"
1540
+ "INSERT INTO \"%w\".config(name,value) "
15411541
" SELECT 'peer-name-%q', value FROM other.config"
15421542
" WHERE name='project-name';",
15431543
zSelf,
15441544
zSelf, zOtherProjCode, zRepo,
15451545
zSelf, zOtherProjCode
@@ -1550,11 +1550,11 @@
15501550
"INSERT OR IGNORE INTO other.config(name,value)"
15511551
" VALUES('login-group-code',lower(hex(randomblob(8))));",
15521552
zNewName
15531553
);
15541554
db_multi_exec(
1555
- "REPLACE INTO %s.config(name,value)"
1555
+ "REPLACE INTO \"%w\".config(name,value)"
15561556
" SELECT name, value FROM other.config"
15571557
" WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
15581558
zSelf
15591559
);
15601560
db_end_transaction(0);
15611561
--- src/login.c
+++ src/login.c
@@ -395,15 +395,15 @@
395 /* If a URI appears in the User-Agent, it is probably a bot */
396 if( strncmp("http", zAgent+i,4)==0 ) return 0;
397 }
398 if( strncmp(zAgent, "Mozilla/", 8)==0 ){
399 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
400 if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
401 if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
402 if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
403 if( strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent) ) return 1; /* IE11+ */
404 if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
405 return 0;
406 }
407 if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
408 if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
409 if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1294,11 +1294,11 @@
1294 }else{
1295 char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
1296 int uid;
1297 db_multi_exec(
1298 "INSERT INTO user(login,pw,cap,info,mtime)"
1299 "VALUES(%B,%Q,%B,%B,strftime('%s','now'))",
1300 &login, zPw, &caps, &contact
1301 );
1302 free(zPw);
1303
1304 /* The user is registered, now just log him in. */
@@ -1469,17 +1469,17 @@
1469 *pzErrMsg = 0; /* Default to no errors */
1470 zSelf = db_name("repository");
1471
1472 /* Get the full pathname of the other repository */
1473 file_canonical_name(zRepo, &fullName, 0);
1474 zRepo = mprintf(blob_str(&fullName));
1475 blob_reset(&fullName);
1476
1477 /* Get the full pathname for our repository. Also the project code
1478 ** and project name for ourself. */
1479 file_canonical_name(g.zRepositoryName, &fullName, 0);
1480 zSelfRepo = mprintf(blob_str(&fullName));
1481 blob_reset(&fullName);
1482 zSelfProjCode = db_get("project-code", "unknown");
1483 zSelfLabel = db_get("project-name", 0);
1484 if( zSelfLabel==0 ){
1485 zSelfLabel = zSelfProjCode;
@@ -1500,11 +1500,11 @@
1500 zRepo, &pOther,
1501 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1502 g.zVfsName
1503 );
1504 if( rc!=SQLITE_OK ){
1505 *pzErrMsg = mprintf(sqlite3_errmsg(pOther));
1506 }else{
1507 rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
1508 }
1509 sqlite3_close(pOther);
1510 if( rc ) return;
@@ -1533,13 +1533,13 @@
1533 */
1534 zSelfProjCode = abbreviated_project_code(zSelfProjCode);
1535 zOtherProjCode = abbreviated_project_code(zOtherProjCode);
1536 db_begin_transaction();
1537 db_multi_exec(
1538 "DELETE FROM %s.config WHERE name GLOB 'peer-*';"
1539 "INSERT INTO %s.config(name,value) VALUES('peer-repo-%s',%Q);"
1540 "INSERT INTO %s.config(name,value) "
1541 " SELECT 'peer-name-%q', value FROM other.config"
1542 " WHERE name='project-name';",
1543 zSelf,
1544 zSelf, zOtherProjCode, zRepo,
1545 zSelf, zOtherProjCode
@@ -1550,11 +1550,11 @@
1550 "INSERT OR IGNORE INTO other.config(name,value)"
1551 " VALUES('login-group-code',lower(hex(randomblob(8))));",
1552 zNewName
1553 );
1554 db_multi_exec(
1555 "REPLACE INTO %s.config(name,value)"
1556 " SELECT name, value FROM other.config"
1557 " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
1558 zSelf
1559 );
1560 db_end_transaction(0);
1561
--- src/login.c
+++ src/login.c
@@ -395,15 +395,15 @@
395 /* If a URI appears in the User-Agent, it is probably a bot */
396 if( strncmp("http", zAgent+i,4)==0 ) return 0;
397 }
398 if( strncmp(zAgent, "Mozilla/", 8)==0 ){
399 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
400 if( sqlite3_strglob("*Firefox/[1-9]*", zAgent)==0 ) return 1;
401 if( sqlite3_strglob("*Chrome/[1-9]*", zAgent)==0 ) return 1;
402 if( sqlite3_strglob("*(compatible;?MSIE?[1789]*", zAgent)==0 ) return 1;
403 if( sqlite3_strglob("*Trident/[1-9]*;?rv:[1-9]*", zAgent)==0 ) return 1; /* IE11+ */
404 if( sqlite3_strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent)==0 ) return 1;
405 return 0;
406 }
407 if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
408 if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
409 if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
@@ -1294,11 +1294,11 @@
1294 }else{
1295 char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
1296 int uid;
1297 db_multi_exec(
1298 "INSERT INTO user(login,pw,cap,info,mtime)"
1299 "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
1300 &login, zPw, &caps, &contact
1301 );
1302 free(zPw);
1303
1304 /* The user is registered, now just log him in. */
@@ -1469,17 +1469,17 @@
1469 *pzErrMsg = 0; /* Default to no errors */
1470 zSelf = db_name("repository");
1471
1472 /* Get the full pathname of the other repository */
1473 file_canonical_name(zRepo, &fullName, 0);
1474 zRepo = fossil_strdup(blob_str(&fullName));
1475 blob_reset(&fullName);
1476
1477 /* Get the full pathname for our repository. Also the project code
1478 ** and project name for ourself. */
1479 file_canonical_name(g.zRepositoryName, &fullName, 0);
1480 zSelfRepo = fossil_strdup(blob_str(&fullName));
1481 blob_reset(&fullName);
1482 zSelfProjCode = db_get("project-code", "unknown");
1483 zSelfLabel = db_get("project-name", 0);
1484 if( zSelfLabel==0 ){
1485 zSelfLabel = zSelfProjCode;
@@ -1500,11 +1500,11 @@
1500 zRepo, &pOther,
1501 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1502 g.zVfsName
1503 );
1504 if( rc!=SQLITE_OK ){
1505 *pzErrMsg = fossil_strdup(sqlite3_errmsg(pOther));
1506 }else{
1507 rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
1508 }
1509 sqlite3_close(pOther);
1510 if( rc ) return;
@@ -1533,13 +1533,13 @@
1533 */
1534 zSelfProjCode = abbreviated_project_code(zSelfProjCode);
1535 zOtherProjCode = abbreviated_project_code(zOtherProjCode);
1536 db_begin_transaction();
1537 db_multi_exec(
1538 "DELETE FROM \"%w\".config WHERE name GLOB 'peer-*';"
1539 "INSERT INTO \"%w\".config(name,value) VALUES('peer-repo-%q',%Q);"
1540 "INSERT INTO \"%w\".config(name,value) "
1541 " SELECT 'peer-name-%q', value FROM other.config"
1542 " WHERE name='project-name';",
1543 zSelf,
1544 zSelf, zOtherProjCode, zRepo,
1545 zSelf, zOtherProjCode
@@ -1550,11 +1550,11 @@
1550 "INSERT OR IGNORE INTO other.config(name,value)"
1551 " VALUES('login-group-code',lower(hex(randomblob(8))));",
1552 zNewName
1553 );
1554 db_multi_exec(
1555 "REPLACE INTO \"%w\".config(name,value)"
1556 " SELECT name, value FROM other.config"
1557 " WHERE name GLOB 'peer-*' OR name GLOB 'login-group-*'",
1558 zSelf
1559 );
1560 db_end_transaction(0);
1561
+9 -7
--- src/main.c
+++ src/main.c
@@ -169,11 +169,11 @@
169169
int xlinkClusterOnly; /* Set when cloning. Only process clusters */
170170
int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
171171
int *aCommitFile; /* Array of files to be committed */
172172
int markPrivate; /* All new artifacts are private if true */
173173
int clockSkewSeen; /* True if clocks on client and server out of sync */
174
- int wikiFlags; /* Wiki conversion flags applied to %w and %W */
174
+ int wikiFlags; /* Wiki conversion flags applied to %W */
175175
char isHTTP; /* True if server/CGI modes, else assume CLI. */
176176
char javascriptHyperlink; /* If true, set href= using script, not HTML */
177177
Blob httpHeader; /* Complete text of the HTTP request header */
178178
UrlData url; /* Information about current URL */
179179
const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -1721,19 +1721,19 @@
17211721
if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
17221722
zNotFound = azRedirect[i*2+1];
17231723
continue;
17241724
}
17251725
db_open_repository(azRedirect[i*2]);
1726
- if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){
1727
- cgi_redirectf(azRedirect[i*2+1], zName);
1726
+ if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'", zName) ){
1727
+ cgi_redirectf(azRedirect[i*2+1] /*works-like:"%s"*/, zName);
17281728
return;
17291729
}
17301730
db_close(1);
17311731
}
17321732
}
17331733
if( zNotFound ){
1734
- cgi_redirectf(zNotFound, zName);
1734
+ cgi_redirectf(zNotFound /*works-like:"%s"*/, zName);
17351735
}else{
17361736
@ <html>
17371737
@ <head><title>No Such Object</title></head>
17381738
@ <body>
17391739
@ <p>No such object: <b>%h(zName)</b></p>
@@ -1927,11 +1927,11 @@
19271927
** --scgi Interpret input as SCGI rather than HTTP
19281928
**
19291929
** See also: cgi, server, winsrv
19301930
*/
19311931
void cmd_http(void){
1932
- const char *zIpAddr;
1932
+ const char *zIpAddr = 0;
19331933
const char *zNotFound;
19341934
const char *zHost;
19351935
const char *zAltBase;
19361936
const char *zFileGlob;
19371937
int useSCGI;
@@ -1952,11 +1952,14 @@
19521952
g.useLocalauth = find_option("localauth", 0, 0)!=0;
19531953
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
19541954
useSCGI = find_option("scgi", 0, 0)!=0;
19551955
zAltBase = find_option("baseurl", 0, 1);
19561956
if( zAltBase ) set_base_url(zAltBase);
1957
- if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");
1957
+ if( find_option("https",0,0)!=0 ){
1958
+ zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
1959
+ cgi_replace_parameter("HTTPS","on");
1960
+ }
19581961
zHost = find_option("host", 0, 1);
19591962
if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
19601963
g.cgiOutput = 1;
19611964
19621965
/* We should be done with options.. */
@@ -1972,11 +1975,10 @@
19721975
zIpAddr = g.argv[4];
19731976
find_server_repository(0, 5);
19741977
}else{
19751978
g.httpIn = stdin;
19761979
g.httpOut = stdout;
1977
- zIpAddr = 0;
19781980
find_server_repository(0, 2);
19791981
}
19801982
if( zIpAddr==0 ){
19811983
zIpAddr = cgi_ssh_remote_addr(0);
19821984
if( zIpAddr && zIpAddr[0] ){
19831985
--- src/main.c
+++ src/main.c
@@ -169,11 +169,11 @@
169 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
170 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
171 int *aCommitFile; /* Array of files to be committed */
172 int markPrivate; /* All new artifacts are private if true */
173 int clockSkewSeen; /* True if clocks on client and server out of sync */
174 int wikiFlags; /* Wiki conversion flags applied to %w and %W */
175 char isHTTP; /* True if server/CGI modes, else assume CLI. */
176 char javascriptHyperlink; /* If true, set href= using script, not HTML */
177 Blob httpHeader; /* Complete text of the HTTP request header */
178 UrlData url; /* Information about current URL */
179 const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -1721,19 +1721,19 @@
1721 if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
1722 zNotFound = azRedirect[i*2+1];
1723 continue;
1724 }
1725 db_open_repository(azRedirect[i*2]);
1726 if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){
1727 cgi_redirectf(azRedirect[i*2+1], zName);
1728 return;
1729 }
1730 db_close(1);
1731 }
1732 }
1733 if( zNotFound ){
1734 cgi_redirectf(zNotFound, zName);
1735 }else{
1736 @ <html>
1737 @ <head><title>No Such Object</title></head>
1738 @ <body>
1739 @ <p>No such object: <b>%h(zName)</b></p>
@@ -1927,11 +1927,11 @@
1927 ** --scgi Interpret input as SCGI rather than HTTP
1928 **
1929 ** See also: cgi, server, winsrv
1930 */
1931 void cmd_http(void){
1932 const char *zIpAddr;
1933 const char *zNotFound;
1934 const char *zHost;
1935 const char *zAltBase;
1936 const char *zFileGlob;
1937 int useSCGI;
@@ -1952,11 +1952,14 @@
1952 g.useLocalauth = find_option("localauth", 0, 0)!=0;
1953 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
1954 useSCGI = find_option("scgi", 0, 0)!=0;
1955 zAltBase = find_option("baseurl", 0, 1);
1956 if( zAltBase ) set_base_url(zAltBase);
1957 if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");
 
 
 
1958 zHost = find_option("host", 0, 1);
1959 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
1960 g.cgiOutput = 1;
1961
1962 /* We should be done with options.. */
@@ -1972,11 +1975,10 @@
1972 zIpAddr = g.argv[4];
1973 find_server_repository(0, 5);
1974 }else{
1975 g.httpIn = stdin;
1976 g.httpOut = stdout;
1977 zIpAddr = 0;
1978 find_server_repository(0, 2);
1979 }
1980 if( zIpAddr==0 ){
1981 zIpAddr = cgi_ssh_remote_addr(0);
1982 if( zIpAddr && zIpAddr[0] ){
1983
--- src/main.c
+++ src/main.c
@@ -169,11 +169,11 @@
169 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
170 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
171 int *aCommitFile; /* Array of files to be committed */
172 int markPrivate; /* All new artifacts are private if true */
173 int clockSkewSeen; /* True if clocks on client and server out of sync */
174 int wikiFlags; /* Wiki conversion flags applied to %W */
175 char isHTTP; /* True if server/CGI modes, else assume CLI. */
176 char javascriptHyperlink; /* If true, set href= using script, not HTML */
177 Blob httpHeader; /* Complete text of the HTTP request header */
178 UrlData url; /* Information about current URL */
179 const char *zLogin; /* Login name. NULL or "" if not logged in. */
@@ -1721,19 +1721,19 @@
1721 if( fossil_strcmp(azRedirect[i*2],"*")==0 ){
1722 zNotFound = azRedirect[i*2+1];
1723 continue;
1724 }
1725 db_open_repository(azRedirect[i*2]);
1726 if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'", zName) ){
1727 cgi_redirectf(azRedirect[i*2+1] /*works-like:"%s"*/, zName);
1728 return;
1729 }
1730 db_close(1);
1731 }
1732 }
1733 if( zNotFound ){
1734 cgi_redirectf(zNotFound /*works-like:"%s"*/, zName);
1735 }else{
1736 @ <html>
1737 @ <head><title>No Such Object</title></head>
1738 @ <body>
1739 @ <p>No such object: <b>%h(zName)</b></p>
@@ -1927,11 +1927,11 @@
1927 ** --scgi Interpret input as SCGI rather than HTTP
1928 **
1929 ** See also: cgi, server, winsrv
1930 */
1931 void cmd_http(void){
1932 const char *zIpAddr = 0;
1933 const char *zNotFound;
1934 const char *zHost;
1935 const char *zAltBase;
1936 const char *zFileGlob;
1937 int useSCGI;
@@ -1952,11 +1952,14 @@
1952 g.useLocalauth = find_option("localauth", 0, 0)!=0;
1953 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
1954 useSCGI = find_option("scgi", 0, 0)!=0;
1955 zAltBase = find_option("baseurl", 0, 1);
1956 if( zAltBase ) set_base_url(zAltBase);
1957 if( find_option("https",0,0)!=0 ){
1958 zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
1959 cgi_replace_parameter("HTTPS","on");
1960 }
1961 zHost = find_option("host", 0, 1);
1962 if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
1963 g.cgiOutput = 1;
1964
1965 /* We should be done with options.. */
@@ -1972,11 +1975,10 @@
1975 zIpAddr = g.argv[4];
1976 find_server_repository(0, 5);
1977 }else{
1978 g.httpIn = stdin;
1979 g.httpOut = stdout;
 
1980 find_server_repository(0, 2);
1981 }
1982 if( zIpAddr==0 ){
1983 zIpAddr = cgi_ssh_remote_addr(0);
1984 if( zIpAddr && zIpAddr[0] ){
1985
+8 -1
--- src/main.mk
+++ src/main.mk
@@ -360,10 +360,13 @@
360360
361361
install: $(APPNAME)
362362
mkdir -p $(INSTALLDIR)
363363
mv $(APPNAME) $(INSTALLDIR)
364364
365
+codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
366
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
367
+
365368
$(OBJDIR):
366369
-mkdir $(OBJDIR)
367370
368371
$(OBJDIR)/translate: $(SRCDIR)/translate.c
369372
$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -375,10 +378,13 @@
375378
$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
376379
377380
$(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
378381
$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
379382
383
+$(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
384
+ $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
385
+
380386
# WARNING. DANGER. Running the test suite modifies the repository the
381387
# build is done from, i.e. the checkout belongs to. Do not sync/push
382388
# the repository after running the tests.
383389
test: $(OBJDIR) $(APPNAME)
384390
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -430,11 +436,12 @@
430436
$(OBJDIR)/th_lang.o \
431437
$(OBJDIR)/th_tcl.o \
432438
$(OBJDIR)/cson_amalgamation.o
433439
434440
435
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
441
+$(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
442
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
436443
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
437444
438445
# This rule prevents make from using its default rules to try build
439446
# an executable named "manifest" out of the file named "manifest.c"
440447
#
441448
--- src/main.mk
+++ src/main.mk
@@ -360,10 +360,13 @@
360
361 install: $(APPNAME)
362 mkdir -p $(INSTALLDIR)
363 mv $(APPNAME) $(INSTALLDIR)
364
 
 
 
365 $(OBJDIR):
366 -mkdir $(OBJDIR)
367
368 $(OBJDIR)/translate: $(SRCDIR)/translate.c
369 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -375,10 +378,13 @@
375 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
376
377 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
378 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
379
 
 
 
380 # WARNING. DANGER. Running the test suite modifies the repository the
381 # build is done from, i.e. the checkout belongs to. Do not sync/push
382 # the repository after running the tests.
383 test: $(OBJDIR) $(APPNAME)
384 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -430,11 +436,12 @@
430 $(OBJDIR)/th_lang.o \
431 $(OBJDIR)/th_tcl.o \
432 $(OBJDIR)/cson_amalgamation.o
433
434
435 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
 
436 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
437
438 # This rule prevents make from using its default rules to try build
439 # an executable named "manifest" out of the file named "manifest.c"
440 #
441
--- src/main.mk
+++ src/main.mk
@@ -360,10 +360,13 @@
360
361 install: $(APPNAME)
362 mkdir -p $(INSTALLDIR)
363 mv $(APPNAME) $(INSTALLDIR)
364
365 codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
366 $(OBJDIR)/codecheck1 $(TRANS_SRC)
367
368 $(OBJDIR):
369 -mkdir $(OBJDIR)
370
371 $(OBJDIR)/translate: $(SRCDIR)/translate.c
372 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -375,10 +378,13 @@
378 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
379
380 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
381 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
382
383 $(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
384 $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
385
386 # WARNING. DANGER. Running the test suite modifies the repository the
387 # build is done from, i.e. the checkout belongs to. Do not sync/push
388 # the repository after running the tests.
389 test: $(OBJDIR) $(APPNAME)
390 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -430,11 +436,12 @@
436 $(OBJDIR)/th_lang.o \
437 $(OBJDIR)/th_tcl.o \
438 $(OBJDIR)/cson_amalgamation.o
439
440
441 $(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
442 $(OBJDIR)/codecheck1 $(TRANS_SRC)
443 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
444
445 # This rule prevents make from using its default rules to try build
446 # an executable named "manifest" out of the file named "manifest.c"
447 #
448
+65 -11
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -241,10 +241,13 @@
241241
242242
install: $(APPNAME)
243243
mkdir -p $(INSTALLDIR)
244244
mv $(APPNAME) $(INSTALLDIR)
245245
246
+codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
247
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
248
+
246249
$(OBJDIR):
247250
-mkdir $(OBJDIR)
248251
249252
$(OBJDIR)/translate: $(SRCDIR)/translate.c
250253
$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -256,10 +259,13 @@
256259
$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
257260
258261
$(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
259262
$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
260263
264
+$(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
265
+ $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
266
+
261267
# WARNING. DANGER. Running the test suite modifies the repository the
262268
# build is done from, i.e. the checkout belongs to. Do not sync/push
263269
# the repository after running the tests.
264270
test: $(OBJDIR) $(APPNAME)
265271
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -304,11 +310,12 @@
304310
$(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
305311
$(OBJDIR)/cson_amalgamation.o
306312
}]
307313
308314
writeln {
309
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
315
+$(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
316
+ $(OBJDIR)/codecheck1 $(TRANS_SRC)
310317
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
311318
312319
# This rule prevents make from using its default rules to try build
313320
# an executable named "manifest" out of the file named "manifest.c"
314321
#
@@ -505,12 +512,12 @@
505512
#### The directories where the OpenSSL include and library files are located.
506513
# The recommended usage here is to use the Sysinternals junction tool
507514
# to create a hard link between an "openssl-1.x" sub-directory of the
508515
# Fossil source code directory and the target OpenSSL source directory.
509516
#
510
-OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
511
-OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
517
+OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
518
+OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
512519
513520
#### Either the directory where the Tcl library is installed or the Tcl
514521
# source code directory resides (depending on the value of the macro
515522
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
516523
# this directory must have "include" and "lib" sub-directories. If
@@ -753,10 +760,11 @@
753760
ifdef USE_WINDOWS
754761
TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
755762
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
756763
MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
757764
VERSION = $(subst /,\,$(OBJDIR)/version.exe)
765
+CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
758766
CAT = type
759767
CP = copy
760768
GREP = find
761769
MV = copy
762770
RM = del /Q
@@ -765,10 +773,11 @@
765773
else
766774
TRANSLATE = $(OBJDIR)/translate.exe
767775
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
768776
MKINDEX = $(OBJDIR)/mkindex.exe
769777
VERSION = $(OBJDIR)/version.exe
778
+CODECHECK1 = $(OBJDIR)/codecheck1.exe
770779
CAT = cat
771780
CP = cp
772781
GREP = grep
773782
MV = mv
774783
RM = rm -f
@@ -819,10 +828,13 @@
819828
$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
820829
821830
$(VERSION): $(SRCDIR)/mkversion.c
822831
$(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
823832
833
+$(CODECHECK1): $(SRCDIR)/codecheck1.c
834
+ $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
835
+
824836
# WARNING. DANGER. Running the test suite modifies the repository the
825837
# build is done from, i.e. the checkout belongs to. Do not sync/push
826838
# the repository after running the tests.
827839
test: $(OBJDIR) $(APPNAME)
828840
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -886,11 +898,12 @@
886898
887899
ifdef FOSSIL_BUILD_SSL
888900
APPTARGETS += openssl
889901
endif
890902
891
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
903
+$(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
904
+ $(CODECHECK1) $(TRANS_SRC)
892905
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
893906
894907
# This rule prevents make from using its default rules to try build
895908
# an executable named "manifest" out of the file named "manifest.c"
896909
#
@@ -1037,12 +1050,13 @@
10371050
10381051
APPNAME = $(OBJDIR)\fossil$(E)
10391052
10401053
all: $(APPNAME)
10411054
1042
-$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
1055
+$(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
10431056
cd $(OBJDIR)
1057
+ codecheck1$E $(SRC)
10441058
$(DMDIR)\bin\link @link
10451059
10461060
$(OBJDIR)\fossil.res: $B\win\fossil.rc
10471061
$(RC) $(RCFLAGS) -o$@ $**
10481062
@@ -1066,11 +1080,14 @@
10661080
$(BCC) -o$@ $**
10671081
10681082
mkindex$E: $(SRCDIR)\mkindex.c
10691083
$(BCC) -o$@ $**
10701084
1071
-version$E: $B\src\mkversion.c
1085
+mkversion$E: $(SRCDIR)\mkversion.c
1086
+ $(BCC) -o$@ $**
1087
+
1088
+codecheck1$E: $(SRCDIR)\codecheck1.c
10721089
$(BCC) -o$@ $**
10731090
10741091
$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
10751092
$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
10761093
@@ -1084,11 +1101,11 @@
10841101
$(TCC) -o$@ -c $**
10851102
10861103
$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
10871104
cp $@ $@
10881105
1089
-VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
1106
+VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
10901107
+$** > $@
10911108
10921109
page_index.h: mkindex$E $(SRC)
10931110
+$** > $@
10941111
@@ -1095,11 +1112,11 @@
10951112
clean:
10961113
-del $(OBJDIR)\*.obj
10971114
-del *.obj *_.c *.h *.map
10981115
10991116
realclean:
1100
- -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
1117
+ -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E
11011118
11021119
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
11031120
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
11041121
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
11051122
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1145,10 +1162,18 @@
11451162
11461163
writeln {#
11471164
##############################################################################
11481165
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
11491166
##############################################################################
1167
+#
1168
+# This Makefile will only function correctly if used from a sub-directory
1169
+# that is a direct child of the top-level directory for this project.
1170
+#
1171
+!if !exist("..\.fossil-settings")
1172
+!error "Please change the current directory to the one containing this file."
1173
+!endif
1174
+
11501175
#
11511176
# This file is automatically generated. Instead of editing this
11521177
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
11531178
# to regenerate this file.
11541179
#
@@ -1166,10 +1191,13 @@
11661191
PERLDIR = C:\Perl\bin
11671192
PERL = perl.exe
11681193
11691194
# Uncomment to enable debug symbols
11701195
# DEBUG = 1
1196
+
1197
+# Uncomment to support Windows XP with Visual Studio 201x
1198
+# FOSSIL_ENABLE_WINXP = 1
11711199
11721200
# Uncomment to enable JSON API
11731201
# FOSSIL_ENABLE_JSON = 1
11741202
11751203
# Uncomment to enable miniz usage
@@ -1189,13 +1217,14 @@
11891217
11901218
# Uncomment to enable Tcl support
11911219
# FOSSIL_ENABLE_TCL = 1
11921220
11931221
!ifdef FOSSIL_ENABLE_SSL
1194
-SSLDIR = $(B)\compat\openssl-1.0.1i
1222
+SSLDIR = $(B)\compat\openssl-1.0.1j
11951223
SSLINCDIR = $(SSLDIR)\inc32
11961224
SSLLIBDIR = $(SSLDIR)\out32
1225
+SSLLFLAGS = /nologo /opt:ref /debug
11971226
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
11981227
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
11991228
!message Using 'x64' platform for OpenSSL...
12001229
SSLCONFIG = VC-WIN64A no-asm
12011230
SSLSETUP = ms\do_win64a.bat
@@ -1238,10 +1267,21 @@
12381267
INCL = $(INCL) /I$(TCLINCDIR)
12391268
!endif
12401269
12411270
CFLAGS = /nologo
12421271
LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
1272
+
1273
+!ifdef FOSSIL_ENABLE_WINXP
1274
+XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
1275
+CFLAGS = $(CFLAGS) $(XPCFLAGS)
1276
+!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1277
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1278
+!else
1279
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1280
+!endif
1281
+LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1282
+!endif
12431283
12441284
!ifdef DEBUG
12451285
CFLAGS = $(CFLAGS) /Zi /MTd /Od
12461286
LDFLAGS = $(LDFLAGS) /DEBUG
12471287
!else
@@ -1344,21 +1384,29 @@
13441384
13451385
all: $(OX) $(APPNAME)
13461386
13471387
zlib:
13481388
@echo Building zlib from "$(ZLIBDIR)"...
1389
+!ifdef FOSSIL_ENABLE_WINXP
1390
+ @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
1391
+!else
13491392
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
1393
+!endif
13501394
13511395
!ifdef FOSSIL_ENABLE_SSL
13521396
openssl:
13531397
@echo Building OpenSSL from "$(SSLDIR)"...
13541398
!if "$(PERLDIR)" != ""
13551399
@set PATH=$(PERLDIR);$(PATH)
13561400
!endif
13571401
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
13581402
@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
1403
+!ifdef FOSSIL_ENABLE_WINXP
1404
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1405
+!else
13591406
@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
1407
+!endif
13601408
!endif
13611409
13621410
!ifndef FOSSIL_ENABLE_MINIZ
13631411
APPTARGETS = $(APPTARGETS) zlib
13641412
!endif
@@ -1367,12 +1415,13 @@
13671415
!ifdef FOSSIL_BUILD_SSL
13681416
APPTARGETS = $(APPTARGETS) openssl
13691417
!endif
13701418
!endif
13711419
1372
-$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
1420
+$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
13731421
cd $(OX)
1422
+ codecheck1$E $(SRC)
13741423
link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
13751424
13761425
$(OX)\linkopts: $B\win\Makefile.msc}
13771426
set redir {>}
13781427
foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1395,11 +1444,14 @@
13951444
$(BCC) $**
13961445
13971446
mkindex$E: $(SRCDIR)\mkindex.c
13981447
$(BCC) $**
13991448
1400
-mkversion$E: $B\src\mkversion.c
1449
+mkversion$E: $(SRCDIR)\mkversion.c
1450
+ $(BCC) $**
1451
+
1452
+codecheck1$E: $(SRCDIR)\codecheck1.c
14011453
$(BCC) $**
14021454
14031455
$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
14041456
$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
14051457
@@ -1447,10 +1499,12 @@
14471499
-del mkindex$P
14481500
-del makeheaders$E
14491501
-del makeheaders$P
14501502
-del mkversion$E
14511503
-del mkversion$P
1504
+ -del codecheck1$E
1505
+ -del codecheck1$P
14521506
14531507
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
14541508
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
14551509
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
14561510
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
14571511
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -241,10 +241,13 @@
241
242 install: $(APPNAME)
243 mkdir -p $(INSTALLDIR)
244 mv $(APPNAME) $(INSTALLDIR)
245
 
 
 
246 $(OBJDIR):
247 -mkdir $(OBJDIR)
248
249 $(OBJDIR)/translate: $(SRCDIR)/translate.c
250 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -256,10 +259,13 @@
256 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
257
258 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
259 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
260
 
 
 
261 # WARNING. DANGER. Running the test suite modifies the repository the
262 # build is done from, i.e. the checkout belongs to. Do not sync/push
263 # the repository after running the tests.
264 test: $(OBJDIR) $(APPNAME)
265 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -304,11 +310,12 @@
304 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
305 $(OBJDIR)/cson_amalgamation.o
306 }]
307
308 writeln {
309 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
 
310 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
311
312 # This rule prevents make from using its default rules to try build
313 # an executable named "manifest" out of the file named "manifest.c"
314 #
@@ -505,12 +512,12 @@
505 #### The directories where the OpenSSL include and library files are located.
506 # The recommended usage here is to use the Sysinternals junction tool
507 # to create a hard link between an "openssl-1.x" sub-directory of the
508 # Fossil source code directory and the target OpenSSL source directory.
509 #
510 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
511 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
512
513 #### Either the directory where the Tcl library is installed or the Tcl
514 # source code directory resides (depending on the value of the macro
515 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
516 # this directory must have "include" and "lib" sub-directories. If
@@ -753,10 +760,11 @@
753 ifdef USE_WINDOWS
754 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
755 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
756 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
757 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
 
758 CAT = type
759 CP = copy
760 GREP = find
761 MV = copy
762 RM = del /Q
@@ -765,10 +773,11 @@
765 else
766 TRANSLATE = $(OBJDIR)/translate.exe
767 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
768 MKINDEX = $(OBJDIR)/mkindex.exe
769 VERSION = $(OBJDIR)/version.exe
 
770 CAT = cat
771 CP = cp
772 GREP = grep
773 MV = mv
774 RM = rm -f
@@ -819,10 +828,13 @@
819 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
820
821 $(VERSION): $(SRCDIR)/mkversion.c
822 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
823
 
 
 
824 # WARNING. DANGER. Running the test suite modifies the repository the
825 # build is done from, i.e. the checkout belongs to. Do not sync/push
826 # the repository after running the tests.
827 test: $(OBJDIR) $(APPNAME)
828 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -886,11 +898,12 @@
886
887 ifdef FOSSIL_BUILD_SSL
888 APPTARGETS += openssl
889 endif
890
891 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
 
892 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
893
894 # This rule prevents make from using its default rules to try build
895 # an executable named "manifest" out of the file named "manifest.c"
896 #
@@ -1037,12 +1050,13 @@
1037
1038 APPNAME = $(OBJDIR)\fossil$(E)
1039
1040 all: $(APPNAME)
1041
1042 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
1043 cd $(OBJDIR)
 
1044 $(DMDIR)\bin\link @link
1045
1046 $(OBJDIR)\fossil.res: $B\win\fossil.rc
1047 $(RC) $(RCFLAGS) -o$@ $**
1048
@@ -1066,11 +1080,14 @@
1066 $(BCC) -o$@ $**
1067
1068 mkindex$E: $(SRCDIR)\mkindex.c
1069 $(BCC) -o$@ $**
1070
1071 version$E: $B\src\mkversion.c
 
 
 
1072 $(BCC) -o$@ $**
1073
1074 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
1075 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
1076
@@ -1084,11 +1101,11 @@
1084 $(TCC) -o$@ -c $**
1085
1086 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
1087 cp $@ $@
1088
1089 VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
1090 +$** > $@
1091
1092 page_index.h: mkindex$E $(SRC)
1093 +$** > $@
1094
@@ -1095,11 +1112,11 @@
1095 clean:
1096 -del $(OBJDIR)\*.obj
1097 -del *.obj *_.c *.h *.map
1098
1099 realclean:
1100 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
1101
1102 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1103 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1104 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1105 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1145,10 +1162,18 @@
1145
1146 writeln {#
1147 ##############################################################################
1148 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
1149 ##############################################################################
 
 
 
 
 
 
 
 
1150 #
1151 # This file is automatically generated. Instead of editing this
1152 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
1153 # to regenerate this file.
1154 #
@@ -1166,10 +1191,13 @@
1166 PERLDIR = C:\Perl\bin
1167 PERL = perl.exe
1168
1169 # Uncomment to enable debug symbols
1170 # DEBUG = 1
 
 
 
1171
1172 # Uncomment to enable JSON API
1173 # FOSSIL_ENABLE_JSON = 1
1174
1175 # Uncomment to enable miniz usage
@@ -1189,13 +1217,14 @@
1189
1190 # Uncomment to enable Tcl support
1191 # FOSSIL_ENABLE_TCL = 1
1192
1193 !ifdef FOSSIL_ENABLE_SSL
1194 SSLDIR = $(B)\compat\openssl-1.0.1i
1195 SSLINCDIR = $(SSLDIR)\inc32
1196 SSLLIBDIR = $(SSLDIR)\out32
 
1197 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1198 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1199 !message Using 'x64' platform for OpenSSL...
1200 SSLCONFIG = VC-WIN64A no-asm
1201 SSLSETUP = ms\do_win64a.bat
@@ -1238,10 +1267,21 @@
1238 INCL = $(INCL) /I$(TCLINCDIR)
1239 !endif
1240
1241 CFLAGS = /nologo
1242 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
 
 
 
 
 
 
 
 
 
 
 
1243
1244 !ifdef DEBUG
1245 CFLAGS = $(CFLAGS) /Zi /MTd /Od
1246 LDFLAGS = $(LDFLAGS) /DEBUG
1247 !else
@@ -1344,21 +1384,29 @@
1344
1345 all: $(OX) $(APPNAME)
1346
1347 zlib:
1348 @echo Building zlib from "$(ZLIBDIR)"...
 
 
 
1349 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
 
1350
1351 !ifdef FOSSIL_ENABLE_SSL
1352 openssl:
1353 @echo Building OpenSSL from "$(SSLDIR)"...
1354 !if "$(PERLDIR)" != ""
1355 @set PATH=$(PERLDIR);$(PATH)
1356 !endif
1357 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1358 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
 
 
 
1359 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
 
1360 !endif
1361
1362 !ifndef FOSSIL_ENABLE_MINIZ
1363 APPTARGETS = $(APPTARGETS) zlib
1364 !endif
@@ -1367,12 +1415,13 @@
1367 !ifdef FOSSIL_BUILD_SSL
1368 APPTARGETS = $(APPTARGETS) openssl
1369 !endif
1370 !endif
1371
1372 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
1373 cd $(OX)
 
1374 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
1375
1376 $(OX)\linkopts: $B\win\Makefile.msc}
1377 set redir {>}
1378 foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1395,11 +1444,14 @@
1395 $(BCC) $**
1396
1397 mkindex$E: $(SRCDIR)\mkindex.c
1398 $(BCC) $**
1399
1400 mkversion$E: $B\src\mkversion.c
 
 
 
1401 $(BCC) $**
1402
1403 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
1404 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
1405
@@ -1447,10 +1499,12 @@
1447 -del mkindex$P
1448 -del makeheaders$E
1449 -del makeheaders$P
1450 -del mkversion$E
1451 -del mkversion$P
 
 
1452
1453 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1454 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1455 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1456 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
1457
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -241,10 +241,13 @@
241
242 install: $(APPNAME)
243 mkdir -p $(INSTALLDIR)
244 mv $(APPNAME) $(INSTALLDIR)
245
246 codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1
247 $(OBJDIR)/codecheck1 $(TRANS_SRC)
248
249 $(OBJDIR):
250 -mkdir $(OBJDIR)
251
252 $(OBJDIR)/translate: $(SRCDIR)/translate.c
253 $(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c
@@ -256,10 +259,13 @@
259 $(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c
260
261 $(OBJDIR)/mkversion: $(SRCDIR)/mkversion.c
262 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
263
264 $(OBJDIR)/codecheck1: $(SRCDIR)/codecheck1.c
265 $(BCC) -o $(OBJDIR)/codecheck1 $(SRCDIR)/codecheck1.c
266
267 # WARNING. DANGER. Running the test suite modifies the repository the
268 # build is done from, i.e. the checkout belongs to. Do not sync/push
269 # the repository after running the tests.
270 test: $(OBJDIR) $(APPNAME)
271 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -304,11 +310,12 @@
310 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
311 $(OBJDIR)/cson_amalgamation.o
312 }]
313
314 writeln {
315 $(APPNAME): $(OBJDIR)/headers $(OBJDIR)/codecheck1 $(OBJ) $(EXTRAOBJ)
316 $(OBJDIR)/codecheck1 $(TRANS_SRC)
317 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
318
319 # This rule prevents make from using its default rules to try build
320 # an executable named "manifest" out of the file named "manifest.c"
321 #
@@ -505,12 +512,12 @@
512 #### The directories where the OpenSSL include and library files are located.
513 # The recommended usage here is to use the Sysinternals junction tool
514 # to create a hard link between an "openssl-1.x" sub-directory of the
515 # Fossil source code directory and the target OpenSSL source directory.
516 #
517 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
518 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
519
520 #### Either the directory where the Tcl library is installed or the Tcl
521 # source code directory resides (depending on the value of the macro
522 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
523 # this directory must have "include" and "lib" sub-directories. If
@@ -753,10 +760,11 @@
760 ifdef USE_WINDOWS
761 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
762 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
763 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
764 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
765 CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
766 CAT = type
767 CP = copy
768 GREP = find
769 MV = copy
770 RM = del /Q
@@ -765,10 +773,11 @@
773 else
774 TRANSLATE = $(OBJDIR)/translate.exe
775 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
776 MKINDEX = $(OBJDIR)/mkindex.exe
777 VERSION = $(OBJDIR)/version.exe
778 CODECHECK1 = $(OBJDIR)/codecheck1.exe
779 CAT = cat
780 CP = cp
781 GREP = grep
782 MV = mv
783 RM = rm -f
@@ -819,10 +828,13 @@
828 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
829
830 $(VERSION): $(SRCDIR)/mkversion.c
831 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
832
833 $(CODECHECK1): $(SRCDIR)/codecheck1.c
834 $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
835
836 # WARNING. DANGER. Running the test suite modifies the repository the
837 # build is done from, i.e. the checkout belongs to. Do not sync/push
838 # the repository after running the tests.
839 test: $(OBJDIR) $(APPNAME)
840 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -886,11 +898,12 @@
898
899 ifdef FOSSIL_BUILD_SSL
900 APPTARGETS += openssl
901 endif
902
903 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(CODECHECK1) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
904 $(CODECHECK1) $(TRANS_SRC)
905 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
906
907 # This rule prevents make from using its default rules to try build
908 # an executable named "manifest" out of the file named "manifest.c"
909 #
@@ -1037,12 +1050,13 @@
1050
1051 APPNAME = $(OBJDIR)\fossil$(E)
1052
1053 all: $(APPNAME)
1054
1055 $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
1056 cd $(OBJDIR)
1057 codecheck1$E $(SRC)
1058 $(DMDIR)\bin\link @link
1059
1060 $(OBJDIR)\fossil.res: $B\win\fossil.rc
1061 $(RC) $(RCFLAGS) -o$@ $**
1062
@@ -1066,11 +1080,14 @@
1080 $(BCC) -o$@ $**
1081
1082 mkindex$E: $(SRCDIR)\mkindex.c
1083 $(BCC) -o$@ $**
1084
1085 mkversion$E: $(SRCDIR)\mkversion.c
1086 $(BCC) -o$@ $**
1087
1088 codecheck1$E: $(SRCDIR)\codecheck1.c
1089 $(BCC) -o$@ $**
1090
1091 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
1092 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
1093
@@ -1084,11 +1101,11 @@
1101 $(TCC) -o$@ -c $**
1102
1103 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
1104 cp $@ $@
1105
1106 VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
1107 +$** > $@
1108
1109 page_index.h: mkindex$E $(SRC)
1110 +$** > $@
1111
@@ -1095,11 +1112,11 @@
1112 clean:
1113 -del $(OBJDIR)\*.obj
1114 -del *.obj *_.c *.h *.map
1115
1116 realclean:
1117 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E
1118
1119 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1120 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1121 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1122 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
@@ -1145,10 +1162,18 @@
1162
1163 writeln {#
1164 ##############################################################################
1165 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
1166 ##############################################################################
1167 #
1168 # This Makefile will only function correctly if used from a sub-directory
1169 # that is a direct child of the top-level directory for this project.
1170 #
1171 !if !exist("..\.fossil-settings")
1172 !error "Please change the current directory to the one containing this file."
1173 !endif
1174
1175 #
1176 # This file is automatically generated. Instead of editing this
1177 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
1178 # to regenerate this file.
1179 #
@@ -1166,10 +1191,13 @@
1191 PERLDIR = C:\Perl\bin
1192 PERL = perl.exe
1193
1194 # Uncomment to enable debug symbols
1195 # DEBUG = 1
1196
1197 # Uncomment to support Windows XP with Visual Studio 201x
1198 # FOSSIL_ENABLE_WINXP = 1
1199
1200 # Uncomment to enable JSON API
1201 # FOSSIL_ENABLE_JSON = 1
1202
1203 # Uncomment to enable miniz usage
@@ -1189,13 +1217,14 @@
1217
1218 # Uncomment to enable Tcl support
1219 # FOSSIL_ENABLE_TCL = 1
1220
1221 !ifdef FOSSIL_ENABLE_SSL
1222 SSLDIR = $(B)\compat\openssl-1.0.1j
1223 SSLINCDIR = $(SSLDIR)\inc32
1224 SSLLIBDIR = $(SSLDIR)\out32
1225 SSLLFLAGS = /nologo /opt:ref /debug
1226 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1227 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1228 !message Using 'x64' platform for OpenSSL...
1229 SSLCONFIG = VC-WIN64A no-asm
1230 SSLSETUP = ms\do_win64a.bat
@@ -1238,10 +1267,21 @@
1267 INCL = $(INCL) /I$(TCLINCDIR)
1268 !endif
1269
1270 CFLAGS = /nologo
1271 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
1272
1273 !ifdef FOSSIL_ENABLE_WINXP
1274 XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
1275 CFLAGS = $(CFLAGS) $(XPCFLAGS)
1276 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1277 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1278 !else
1279 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1280 !endif
1281 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1282 !endif
1283
1284 !ifdef DEBUG
1285 CFLAGS = $(CFLAGS) /Zi /MTd /Od
1286 LDFLAGS = $(LDFLAGS) /DEBUG
1287 !else
@@ -1344,21 +1384,29 @@
1384
1385 all: $(OX) $(APPNAME)
1386
1387 zlib:
1388 @echo Building zlib from "$(ZLIBDIR)"...
1389 !ifdef FOSSIL_ENABLE_WINXP
1390 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
1391 !else
1392 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
1393 !endif
1394
1395 !ifdef FOSSIL_ENABLE_SSL
1396 openssl:
1397 @echo Building OpenSSL from "$(SSLDIR)"...
1398 !if "$(PERLDIR)" != ""
1399 @set PATH=$(PERLDIR);$(PATH)
1400 !endif
1401 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1402 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
1403 !ifdef FOSSIL_ENABLE_WINXP
1404 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1405 !else
1406 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
1407 !endif
1408 !endif
1409
1410 !ifndef FOSSIL_ENABLE_MINIZ
1411 APPTARGETS = $(APPTARGETS) zlib
1412 !endif
@@ -1367,12 +1415,13 @@
1415 !ifdef FOSSIL_BUILD_SSL
1416 APPTARGETS = $(APPTARGETS) openssl
1417 !endif
1418 !endif
1419
1420 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
1421 cd $(OX)
1422 codecheck1$E $(SRC)
1423 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
1424
1425 $(OX)\linkopts: $B\win\Makefile.msc}
1426 set redir {>}
1427 foreach s [lsort [concat $src $AdditionalObj]] {
@@ -1395,11 +1444,14 @@
1444 $(BCC) $**
1445
1446 mkindex$E: $(SRCDIR)\mkindex.c
1447 $(BCC) $**
1448
1449 mkversion$E: $(SRCDIR)\mkversion.c
1450 $(BCC) $**
1451
1452 codecheck1$E: $(SRCDIR)\codecheck1.c
1453 $(BCC) $**
1454
1455 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
1456 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
1457
@@ -1447,10 +1499,12 @@
1499 -del mkindex$P
1500 -del makeheaders$E
1501 -del makeheaders$P
1502 -del mkversion$E
1503 -del mkversion$P
1504 -del codecheck1$E
1505 -del codecheck1$P
1506
1507 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
1508 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
1509 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
1510 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
1511
+5 -6
--- src/manifest.c
+++ src/manifest.c
@@ -378,13 +378,13 @@
378378
** if that is not the case for this artifact.
379379
*/
380380
if( !isRepeat ) g.parseCnt[0]++;
381381
z = blob_materialize(pContent);
382382
n = blob_size(pContent);
383
- if( n<=0 || z[n-1]!='\n' ){
383
+ if( pErr && (n<=0 || z[n-1]!='\n') ){
384384
blob_reset(pContent);
385
- blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length");
385
+ blob_append(pErr, n ? "not terminated with \\n" : "zero-length", -1);
386386
return 0;
387387
}
388388
389389
/* Strip off the PGP signature if there is one.
390390
*/
@@ -1589,11 +1589,11 @@
15891589
once = 0;
15901590
zTitleExpr = db_get("ticket-title-expr", "title");
15911591
zStatusColumn = db_get("ticket-status-column", "status");
15921592
}
15931593
zTitle = db_text("unknown",
1594
- "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1594
+ "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
15951595
zTitleExpr, pManifest->zTicketUuid
15961596
);
15971597
if( !isNew ){
15981598
for(i=0; i<pManifest->nField; i++){
15991599
if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
@@ -1610,11 +1610,11 @@
16101610
}
16111611
blob_appendf(&brief, "%h ticket [%s|%S].",
16121612
zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
16131613
}else{
16141614
zNewStatus = db_text("unknown",
1615
- "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1615
+ "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
16161616
zStatusColumn, pManifest->zTicketUuid
16171617
);
16181618
blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
16191619
"%d other change%s",
16201620
pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
@@ -1894,11 +1894,10 @@
18941894
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
18951895
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
18961896
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
18971897
p->rDate, rid, p->zUser, zComment,
18981898
TAG_BGCOLOR, rid,
1899
- TAG_BGCOLOR, rid,
19001899
TAG_USER, rid,
19011900
TAG_COMMENT, rid
19021901
);
19031902
fossil_free(zComment);
19041903
}
@@ -2026,11 +2025,11 @@
20262025
" Edit [%s|%S]:",
20272026
zTagUuid, zTagUuid);
20282027
branchMove = 0;
20292028
if( permitHooks && db_exists("SELECT 1 FROM event, blob"
20302029
" WHERE event.type='ci' AND event.objid=blob.rid"
2031
- " AND blob.uuid='%s'", zTagUuid) ){
2030
+ " AND blob.uuid=%Q", zTagUuid) ){
20322031
zScript = xfer_commit_code();
20332032
zUuid = zTagUuid;
20342033
}
20352034
}
20362035
zName = p->aTag[i].zName;
20372036
--- src/manifest.c
+++ src/manifest.c
@@ -378,13 +378,13 @@
378 ** if that is not the case for this artifact.
379 */
380 if( !isRepeat ) g.parseCnt[0]++;
381 z = blob_materialize(pContent);
382 n = blob_size(pContent);
383 if( n<=0 || z[n-1]!='\n' ){
384 blob_reset(pContent);
385 blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length");
386 return 0;
387 }
388
389 /* Strip off the PGP signature if there is one.
390 */
@@ -1589,11 +1589,11 @@
1589 once = 0;
1590 zTitleExpr = db_get("ticket-title-expr", "title");
1591 zStatusColumn = db_get("ticket-status-column", "status");
1592 }
1593 zTitle = db_text("unknown",
1594 "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1595 zTitleExpr, pManifest->zTicketUuid
1596 );
1597 if( !isNew ){
1598 for(i=0; i<pManifest->nField; i++){
1599 if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
@@ -1610,11 +1610,11 @@
1610 }
1611 blob_appendf(&brief, "%h ticket [%s|%S].",
1612 zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
1613 }else{
1614 zNewStatus = db_text("unknown",
1615 "SELECT %s FROM ticket WHERE tkt_uuid='%s'",
1616 zStatusColumn, pManifest->zTicketUuid
1617 );
1618 blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
1619 "%d other change%s",
1620 pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
@@ -1894,11 +1894,10 @@
1894 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
1895 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
1896 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
1897 p->rDate, rid, p->zUser, zComment,
1898 TAG_BGCOLOR, rid,
1899 TAG_BGCOLOR, rid,
1900 TAG_USER, rid,
1901 TAG_COMMENT, rid
1902 );
1903 fossil_free(zComment);
1904 }
@@ -2026,11 +2025,11 @@
2026 " Edit [%s|%S]:",
2027 zTagUuid, zTagUuid);
2028 branchMove = 0;
2029 if( permitHooks && db_exists("SELECT 1 FROM event, blob"
2030 " WHERE event.type='ci' AND event.objid=blob.rid"
2031 " AND blob.uuid='%s'", zTagUuid) ){
2032 zScript = xfer_commit_code();
2033 zUuid = zTagUuid;
2034 }
2035 }
2036 zName = p->aTag[i].zName;
2037
--- src/manifest.c
+++ src/manifest.c
@@ -378,13 +378,13 @@
378 ** if that is not the case for this artifact.
379 */
380 if( !isRepeat ) g.parseCnt[0]++;
381 z = blob_materialize(pContent);
382 n = blob_size(pContent);
383 if( pErr && (n<=0 || z[n-1]!='\n') ){
384 blob_reset(pContent);
385 blob_append(pErr, n ? "not terminated with \\n" : "zero-length", -1);
386 return 0;
387 }
388
389 /* Strip off the PGP signature if there is one.
390 */
@@ -1589,11 +1589,11 @@
1589 once = 0;
1590 zTitleExpr = db_get("ticket-title-expr", "title");
1591 zStatusColumn = db_get("ticket-status-column", "status");
1592 }
1593 zTitle = db_text("unknown",
1594 "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
1595 zTitleExpr, pManifest->zTicketUuid
1596 );
1597 if( !isNew ){
1598 for(i=0; i<pManifest->nField; i++){
1599 if( fossil_strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){
@@ -1610,11 +1610,11 @@
1610 }
1611 blob_appendf(&brief, "%h ticket [%s|%S].",
1612 zNewStatus, pManifest->zTicketUuid, pManifest->zTicketUuid);
1613 }else{
1614 zNewStatus = db_text("unknown",
1615 "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
1616 zStatusColumn, pManifest->zTicketUuid
1617 );
1618 blob_appendf(&comment, "Ticket [%s|%S] <i>%h</i> status still %h with "
1619 "%d other change%s",
1620 pManifest->zTicketUuid, pManifest->zTicketUuid, zTitle, zNewStatus,
@@ -1894,11 +1894,10 @@
1894 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"
1895 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
1896 " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
1897 p->rDate, rid, p->zUser, zComment,
1898 TAG_BGCOLOR, rid,
 
1899 TAG_USER, rid,
1900 TAG_COMMENT, rid
1901 );
1902 fossil_free(zComment);
1903 }
@@ -2026,11 +2025,11 @@
2025 " Edit [%s|%S]:",
2026 zTagUuid, zTagUuid);
2027 branchMove = 0;
2028 if( permitHooks && db_exists("SELECT 1 FROM event, blob"
2029 " WHERE event.type='ci' AND event.objid=blob.rid"
2030 " AND blob.uuid=%Q", zTagUuid) ){
2031 zScript = xfer_commit_code();
2032 zUuid = zTagUuid;
2033 }
2034 }
2035 zName = p->aTag[i].zName;
2036
+4 -4
--- src/merge3.c
+++ src/merge3.c
@@ -268,17 +268,17 @@
268268
nConflict++;
269269
while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
270270
sz++;
271271
}
272272
DEBUG( printf("CONFLICT %d\n", sz); )
273
- blob_appendf(pOut, mergeMarker[0]);
273
+ blob_append(pOut, mergeMarker[0], -1);
274274
i1 = output_one_side(pOut, pV1, aC1, i1, sz);
275
- blob_appendf(pOut, mergeMarker[1]);
275
+ blob_append(pOut, mergeMarker[1], -1);
276276
blob_copy_lines(pOut, pPivot, sz);
277
- blob_appendf(pOut, mergeMarker[2]);
277
+ blob_append(pOut, mergeMarker[2], -1);
278278
i2 = output_one_side(pOut, pV2, aC2, i2, sz);
279
- blob_appendf(pOut, mergeMarker[3]);
279
+ blob_append(pOut, mergeMarker[3], -1);
280280
}
281281
282282
/* If we are finished with an edit triple, advance to the next
283283
** triple.
284284
*/
285285
--- src/merge3.c
+++ src/merge3.c
@@ -268,17 +268,17 @@
268 nConflict++;
269 while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
270 sz++;
271 }
272 DEBUG( printf("CONFLICT %d\n", sz); )
273 blob_appendf(pOut, mergeMarker[0]);
274 i1 = output_one_side(pOut, pV1, aC1, i1, sz);
275 blob_appendf(pOut, mergeMarker[1]);
276 blob_copy_lines(pOut, pPivot, sz);
277 blob_appendf(pOut, mergeMarker[2]);
278 i2 = output_one_side(pOut, pV2, aC2, i2, sz);
279 blob_appendf(pOut, mergeMarker[3]);
280 }
281
282 /* If we are finished with an edit triple, advance to the next
283 ** triple.
284 */
285
--- src/merge3.c
+++ src/merge3.c
@@ -268,17 +268,17 @@
268 nConflict++;
269 while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
270 sz++;
271 }
272 DEBUG( printf("CONFLICT %d\n", sz); )
273 blob_append(pOut, mergeMarker[0], -1);
274 i1 = output_one_side(pOut, pV1, aC1, i1, sz);
275 blob_append(pOut, mergeMarker[1], -1);
276 blob_copy_lines(pOut, pPivot, sz);
277 blob_append(pOut, mergeMarker[2], -1);
278 i2 = output_one_side(pOut, pV2, aC2, i2, sz);
279 blob_append(pOut, mergeMarker[3], -1);
280 }
281
282 /* If we are finished with an edit triple, advance to the next
283 ** triple.
284 */
285
+3 -3
--- src/moderate.c
+++ src/moderate.c
@@ -73,11 +73,11 @@
7373
"tagxref", "srcid",
7474
"tagxref", "rid",
7575
};
7676
int i;
7777
for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
78
- if( db_exists("SELECT 1 FROM %s WHERE %s=%d",
78
+ if( db_exists("SELECT 1 FROM \"%w\" WHERE \"%w\"=%d",
7979
aTabField[i], aTabField[i+1], rid) ) return 1;
8080
}
8181
return 0;
8282
}
8383
@@ -152,15 +152,15 @@
152152
if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
153153
style_header("Pending Moderation Requests");
154154
@ <h2>All Pending Moderation Requests</h2>
155155
if( moderation_table_exists() ){
156156
blob_init(&sql, timeline_query_for_www(), -1);
157
- blob_appendf(&sql,
157
+ blob_append_sql(&sql,
158158
" AND event.objid IN (SELECT objid FROM modreq)"
159159
" ORDER BY event.mtime DESC"
160160
);
161
- db_prepare(&q, blob_str(&sql));
161
+ db_prepare(&q, "%s", blob_sql_text(&sql));
162162
www_print_timeline(&q, 0, 0, 0, 0);
163163
db_finalize(&q);
164164
}
165165
style_footer();
166166
}
167167
--- src/moderate.c
+++ src/moderate.c
@@ -73,11 +73,11 @@
73 "tagxref", "srcid",
74 "tagxref", "rid",
75 };
76 int i;
77 for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
78 if( db_exists("SELECT 1 FROM %s WHERE %s=%d",
79 aTabField[i], aTabField[i+1], rid) ) return 1;
80 }
81 return 0;
82 }
83
@@ -152,15 +152,15 @@
152 if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
153 style_header("Pending Moderation Requests");
154 @ <h2>All Pending Moderation Requests</h2>
155 if( moderation_table_exists() ){
156 blob_init(&sql, timeline_query_for_www(), -1);
157 blob_appendf(&sql,
158 " AND event.objid IN (SELECT objid FROM modreq)"
159 " ORDER BY event.mtime DESC"
160 );
161 db_prepare(&q, blob_str(&sql));
162 www_print_timeline(&q, 0, 0, 0, 0);
163 db_finalize(&q);
164 }
165 style_footer();
166 }
167
--- src/moderate.c
+++ src/moderate.c
@@ -73,11 +73,11 @@
73 "tagxref", "srcid",
74 "tagxref", "rid",
75 };
76 int i;
77 for(i=0; i<sizeof(aTabField)/sizeof(aTabField[0]); i+=2){
78 if( db_exists("SELECT 1 FROM \"%w\" WHERE \"%w\"=%d",
79 aTabField[i], aTabField[i+1], rid) ) return 1;
80 }
81 return 0;
82 }
83
@@ -152,15 +152,15 @@
152 if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
153 style_header("Pending Moderation Requests");
154 @ <h2>All Pending Moderation Requests</h2>
155 if( moderation_table_exists() ){
156 blob_init(&sql, timeline_query_for_www(), -1);
157 blob_append_sql(&sql,
158 " AND event.objid IN (SELECT objid FROM modreq)"
159 " ORDER BY event.mtime DESC"
160 );
161 db_prepare(&q, "%s", blob_sql_text(&sql));
162 www_print_timeline(&q, 0, 0, 0, 0);
163 db_finalize(&q);
164 }
165 style_footer();
166 }
167
+4 -4
--- src/name.c
+++ src/name.c
@@ -216,16 +216,16 @@
216216
char zUuid[UUID_SIZE+1];
217217
memcpy(zUuid, zTag, nTag+1);
218218
canonical16(zUuid, nTag);
219219
rid = 0;
220220
if( zType[0]=='*' ){
221
- db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zUuid);
221
+ db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid);
222222
}else{
223223
db_prepare(&q,
224224
"SELECT blob.rid"
225225
" FROM blob, event"
226
- " WHERE blob.uuid GLOB '%s*'"
226
+ " WHERE blob.uuid GLOB '%q*'"
227227
" AND event.objid=blob.rid"
228228
" AND event.type GLOB '%q'",
229229
zUuid, zType
230230
);
231231
}
@@ -259,11 +259,11 @@
259259
}else{
260260
rid = db_int(0,
261261
"SELECT event.objid"
262262
" FROM event"
263263
" WHERE event.objid=%s"
264
- " AND event.type GLOB '%q'", zTag, zType);
264
+ " AND event.type GLOB '%q'", zTag /*safe-for-%s*/, zType);
265265
}
266266
}
267267
}
268268
return rid;
269269
}
@@ -554,11 +554,11 @@
554554
"SELECT tagname"
555555
" FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
556556
" WHERE tagxref.rid=%d"
557557
" AND tag.tagid IN (5,6,7,9)"
558558
" ORDER BY 1",
559
- rid, rid
559
+ rid
560560
);
561561
cnt = 0;
562562
while( db_step(&q)==SQLITE_ROW ){
563563
const char *zPrefix = cnt++ ? ", " : "raw-tags: ";
564564
fossil_print("%s%s", zPrefix, db_column_text(&q,0));
565565
--- src/name.c
+++ src/name.c
@@ -216,16 +216,16 @@
216 char zUuid[UUID_SIZE+1];
217 memcpy(zUuid, zTag, nTag+1);
218 canonical16(zUuid, nTag);
219 rid = 0;
220 if( zType[0]=='*' ){
221 db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zUuid);
222 }else{
223 db_prepare(&q,
224 "SELECT blob.rid"
225 " FROM blob, event"
226 " WHERE blob.uuid GLOB '%s*'"
227 " AND event.objid=blob.rid"
228 " AND event.type GLOB '%q'",
229 zUuid, zType
230 );
231 }
@@ -259,11 +259,11 @@
259 }else{
260 rid = db_int(0,
261 "SELECT event.objid"
262 " FROM event"
263 " WHERE event.objid=%s"
264 " AND event.type GLOB '%q'", zTag, zType);
265 }
266 }
267 }
268 return rid;
269 }
@@ -554,11 +554,11 @@
554 "SELECT tagname"
555 " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
556 " WHERE tagxref.rid=%d"
557 " AND tag.tagid IN (5,6,7,9)"
558 " ORDER BY 1",
559 rid, rid
560 );
561 cnt = 0;
562 while( db_step(&q)==SQLITE_ROW ){
563 const char *zPrefix = cnt++ ? ", " : "raw-tags: ";
564 fossil_print("%s%s", zPrefix, db_column_text(&q,0));
565
--- src/name.c
+++ src/name.c
@@ -216,16 +216,16 @@
216 char zUuid[UUID_SIZE+1];
217 memcpy(zUuid, zTag, nTag+1);
218 canonical16(zUuid, nTag);
219 rid = 0;
220 if( zType[0]=='*' ){
221 db_prepare(&q, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid);
222 }else{
223 db_prepare(&q,
224 "SELECT blob.rid"
225 " FROM blob, event"
226 " WHERE blob.uuid GLOB '%q*'"
227 " AND event.objid=blob.rid"
228 " AND event.type GLOB '%q'",
229 zUuid, zType
230 );
231 }
@@ -259,11 +259,11 @@
259 }else{
260 rid = db_int(0,
261 "SELECT event.objid"
262 " FROM event"
263 " WHERE event.objid=%s"
264 " AND event.type GLOB '%q'", zTag /*safe-for-%s*/, zType);
265 }
266 }
267 }
268 return rid;
269 }
@@ -554,11 +554,11 @@
554 "SELECT tagname"
555 " FROM tag JOIN tagxref ON tag.tagid=tagxref.tagid"
556 " WHERE tagxref.rid=%d"
557 " AND tag.tagid IN (5,6,7,9)"
558 " ORDER BY 1",
559 rid
560 );
561 cnt = 0;
562 while( db_step(&q)==SQLITE_ROW ){
563 const char *zPrefix = cnt++ ? ", " : "raw-tags: ";
564 fossil_print("%s%s", zPrefix, db_column_text(&q,0));
565
+10 -10
--- src/path.c
+++ src/path.c
@@ -112,11 +112,11 @@
112112
** Compute the shortest path from iFrom to iTo
113113
**
114114
** If directOnly is true, then use only the "primary" links from parent to
115115
** child. In other words, ignore merges.
116116
**
117
-** Return a pointer to the beginning of the path (the iFrom node).
117
+** Return a pointer to the beginning of the path (the iFrom node).
118118
** Elements of the path can be traversed by following the PathNode.u.pTo
119119
** pointer chain.
120120
**
121121
** Return NULL if no path is found.
122122
*/
@@ -135,25 +135,25 @@
135135
if( iTo==iFrom ){
136136
path.pEnd = path.pStart;
137137
return path.pStart;
138138
}
139139
if( oneWayOnly && directOnly ){
140
- db_prepare(&s,
140
+ db_prepare(&s,
141141
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
142142
);
143143
}else if( oneWayOnly ){
144
- db_prepare(&s,
144
+ db_prepare(&s,
145145
"SELECT cid, 1 FROM plink WHERE pid=:pid "
146146
);
147147
}else if( directOnly ){
148
- db_prepare(&s,
148
+ db_prepare(&s,
149149
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
150150
"UNION ALL "
151151
"SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
152152
);
153153
}else{
154
- db_prepare(&s,
154
+ db_prepare(&s,
155155
"SELECT cid, 1 FROM plink WHERE pid=:pid "
156156
"UNION ALL "
157157
"SELECT pid, 0 FROM plink WHERE cid=:pid"
158158
);
159159
}
@@ -230,11 +230,11 @@
230230
" WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
231231
p->rid, p->rid);
232232
fossil_print("%4d: %5d %s", n, p->rid, z);
233233
fossil_free(z);
234234
if( p->u.pTo ){
235
- fossil_print(" is a %s of\n",
235
+ fossil_print(" is a %s of\n",
236236
p->u.pTo->fromIsParent ? "parent" : "child");
237237
}else{
238238
fossil_print("\n");
239239
}
240240
}
@@ -353,11 +353,11 @@
353353
/*
354354
** Compute all file name changes that occur going from checkin iFrom
355355
** to checkin iTo.
356356
**
357357
** The number of name changes is written into *pnChng. For each name
358
-** change, two integers are allocated for *piChng. The first is the
358
+** change, two integers are allocated for *piChng. The first is the
359359
** filename.fnid for the original name as seen in check-in iFrom and
360360
** the second is for new name as it is used in check-in iTo.
361361
**
362362
** Space to hold *piChng is obtained from fossil_malloc() and should
363363
** be released by the caller.
@@ -516,11 +516,11 @@
516516
g.argc -= 2;
517517
}
518518
}
519519
520520
/* Query to extract all rename operations */
521
-static const char zRenameQuery[] =
521
+static const char zRenameQuery[] =
522522
@ SELECT
523523
@ datetime(event.mtime),
524524
@ F.name AS old_name,
525525
@ T.name AS new_name,
526526
@ blob.uuid
@@ -531,11 +531,11 @@
531531
@ AND event.objid=mlink.mid
532532
@ AND event.type='ci'
533533
@ AND blob.rid=mlink.mid
534534
@ ORDER BY 1 DESC, 2;
535535
;
536
-
536
+
537537
/*
538538
** WEBPAGE: test-rename-list
539539
**
540540
** Print a list of all file rename operations throughout history.
541541
** This page is intended for for testing purposes only and may change
@@ -551,11 +551,11 @@
551551
@ <table border="1" width="100%%">
552552
@ <tr><th>Date &amp; Time</th>
553553
@ <th>Old Name</th>
554554
@ <th>New Name</th>
555555
@ <th>Check-in</th></tr>
556
- db_prepare(&q, zRenameQuery);
556
+ db_prepare(&q, "%s", zRenameQuery/*safe-for-%s*/);
557557
while( db_step(&q)==SQLITE_ROW ){
558558
const char *zDate = db_column_text(&q, 0);
559559
const char *zOld = db_column_text(&q, 1);
560560
const char *zNew = db_column_text(&q, 2);
561561
const char *zUuid = db_column_text(&q, 3);
562562
--- src/path.c
+++ src/path.c
@@ -112,11 +112,11 @@
112 ** Compute the shortest path from iFrom to iTo
113 **
114 ** If directOnly is true, then use only the "primary" links from parent to
115 ** child. In other words, ignore merges.
116 **
117 ** Return a pointer to the beginning of the path (the iFrom node).
118 ** Elements of the path can be traversed by following the PathNode.u.pTo
119 ** pointer chain.
120 **
121 ** Return NULL if no path is found.
122 */
@@ -135,25 +135,25 @@
135 if( iTo==iFrom ){
136 path.pEnd = path.pStart;
137 return path.pStart;
138 }
139 if( oneWayOnly && directOnly ){
140 db_prepare(&s,
141 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
142 );
143 }else if( oneWayOnly ){
144 db_prepare(&s,
145 "SELECT cid, 1 FROM plink WHERE pid=:pid "
146 );
147 }else if( directOnly ){
148 db_prepare(&s,
149 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
150 "UNION ALL "
151 "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
152 );
153 }else{
154 db_prepare(&s,
155 "SELECT cid, 1 FROM plink WHERE pid=:pid "
156 "UNION ALL "
157 "SELECT pid, 0 FROM plink WHERE cid=:pid"
158 );
159 }
@@ -230,11 +230,11 @@
230 " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
231 p->rid, p->rid);
232 fossil_print("%4d: %5d %s", n, p->rid, z);
233 fossil_free(z);
234 if( p->u.pTo ){
235 fossil_print(" is a %s of\n",
236 p->u.pTo->fromIsParent ? "parent" : "child");
237 }else{
238 fossil_print("\n");
239 }
240 }
@@ -353,11 +353,11 @@
353 /*
354 ** Compute all file name changes that occur going from checkin iFrom
355 ** to checkin iTo.
356 **
357 ** The number of name changes is written into *pnChng. For each name
358 ** change, two integers are allocated for *piChng. The first is the
359 ** filename.fnid for the original name as seen in check-in iFrom and
360 ** the second is for new name as it is used in check-in iTo.
361 **
362 ** Space to hold *piChng is obtained from fossil_malloc() and should
363 ** be released by the caller.
@@ -516,11 +516,11 @@
516 g.argc -= 2;
517 }
518 }
519
520 /* Query to extract all rename operations */
521 static const char zRenameQuery[] =
522 @ SELECT
523 @ datetime(event.mtime),
524 @ F.name AS old_name,
525 @ T.name AS new_name,
526 @ blob.uuid
@@ -531,11 +531,11 @@
531 @ AND event.objid=mlink.mid
532 @ AND event.type='ci'
533 @ AND blob.rid=mlink.mid
534 @ ORDER BY 1 DESC, 2;
535 ;
536
537 /*
538 ** WEBPAGE: test-rename-list
539 **
540 ** Print a list of all file rename operations throughout history.
541 ** This page is intended for for testing purposes only and may change
@@ -551,11 +551,11 @@
551 @ <table border="1" width="100%%">
552 @ <tr><th>Date &amp; Time</th>
553 @ <th>Old Name</th>
554 @ <th>New Name</th>
555 @ <th>Check-in</th></tr>
556 db_prepare(&q, zRenameQuery);
557 while( db_step(&q)==SQLITE_ROW ){
558 const char *zDate = db_column_text(&q, 0);
559 const char *zOld = db_column_text(&q, 1);
560 const char *zNew = db_column_text(&q, 2);
561 const char *zUuid = db_column_text(&q, 3);
562
--- src/path.c
+++ src/path.c
@@ -112,11 +112,11 @@
112 ** Compute the shortest path from iFrom to iTo
113 **
114 ** If directOnly is true, then use only the "primary" links from parent to
115 ** child. In other words, ignore merges.
116 **
117 ** Return a pointer to the beginning of the path (the iFrom node).
118 ** Elements of the path can be traversed by following the PathNode.u.pTo
119 ** pointer chain.
120 **
121 ** Return NULL if no path is found.
122 */
@@ -135,25 +135,25 @@
135 if( iTo==iFrom ){
136 path.pEnd = path.pStart;
137 return path.pStart;
138 }
139 if( oneWayOnly && directOnly ){
140 db_prepare(&s,
141 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
142 );
143 }else if( oneWayOnly ){
144 db_prepare(&s,
145 "SELECT cid, 1 FROM plink WHERE pid=:pid "
146 );
147 }else if( directOnly ){
148 db_prepare(&s,
149 "SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
150 "UNION ALL "
151 "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
152 );
153 }else{
154 db_prepare(&s,
155 "SELECT cid, 1 FROM plink WHERE pid=:pid "
156 "UNION ALL "
157 "SELECT pid, 0 FROM plink WHERE cid=:pid"
158 );
159 }
@@ -230,11 +230,11 @@
230 " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
231 p->rid, p->rid);
232 fossil_print("%4d: %5d %s", n, p->rid, z);
233 fossil_free(z);
234 if( p->u.pTo ){
235 fossil_print(" is a %s of\n",
236 p->u.pTo->fromIsParent ? "parent" : "child");
237 }else{
238 fossil_print("\n");
239 }
240 }
@@ -353,11 +353,11 @@
353 /*
354 ** Compute all file name changes that occur going from checkin iFrom
355 ** to checkin iTo.
356 **
357 ** The number of name changes is written into *pnChng. For each name
358 ** change, two integers are allocated for *piChng. The first is the
359 ** filename.fnid for the original name as seen in check-in iFrom and
360 ** the second is for new name as it is used in check-in iTo.
361 **
362 ** Space to hold *piChng is obtained from fossil_malloc() and should
363 ** be released by the caller.
@@ -516,11 +516,11 @@
516 g.argc -= 2;
517 }
518 }
519
520 /* Query to extract all rename operations */
521 static const char zRenameQuery[] =
522 @ SELECT
523 @ datetime(event.mtime),
524 @ F.name AS old_name,
525 @ T.name AS new_name,
526 @ blob.uuid
@@ -531,11 +531,11 @@
531 @ AND event.objid=mlink.mid
532 @ AND event.type='ci'
533 @ AND blob.rid=mlink.mid
534 @ ORDER BY 1 DESC, 2;
535 ;
536
537 /*
538 ** WEBPAGE: test-rename-list
539 **
540 ** Print a list of all file rename operations throughout history.
541 ** This page is intended for for testing purposes only and may change
@@ -551,11 +551,11 @@
551 @ <table border="1" width="100%%">
552 @ <tr><th>Date &amp; Time</th>
553 @ <th>Old Name</th>
554 @ <th>New Name</th>
555 @ <th>Check-in</th></tr>
556 db_prepare(&q, "%s", zRenameQuery/*safe-for-%s*/);
557 while( db_step(&q)==SQLITE_ROW ){
558 const char *zDate = db_column_text(&q, 0);
559 const char *zOld = db_column_text(&q, 1);
560 const char *zNew = db_column_text(&q, 2);
561 const char *zUuid = db_column_text(&q, 3);
562
+18 -14
--- src/printf.c
+++ src/printf.c
@@ -44,19 +44,20 @@
4444
#define etBLOB 11 /* Blob objects. %b */
4545
#define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */
4646
#define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */
4747
#define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
4848
NULL pointers replaced by SQL NULL. %Q */
49
-#define etPOINTER 15 /* The %p conversion */
50
-#define etHTMLIZE 16 /* Make text safe for HTML */
51
-#define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */
52
-#define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */
53
-#define etFOSSILIZE 19 /* The fossil header encoding format. */
54
-#define etPATH 20 /* Path type */
55
-#define etWIKISTR 21 /* Timeline comment text rendered from a char*: %w */
49
+#define etSQLESCAPE3 15 /* Double '"' characters within an indentifier. %w */
50
+#define etPOINTER 16 /* The %p conversion */
51
+#define etHTMLIZE 17 /* Make text safe for HTML */
52
+#define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */
53
+#define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */
54
+#define etFOSSILIZE 20 /* The fossil header encoding format. */
55
+#define etPATH 21 /* Path type */
56
+#define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
5657
#define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
57
-#define etROOT 24 /* String value of g.zTop: % */
58
+#define etROOT 24 /* String value of g.zTop: %R */
5859
5960
6061
/*
6162
** An "etByte" is an 8-bit unsigned value.
6263
*/
@@ -96,15 +97,16 @@
9697
{ 'z', 0, 6, etDYNSTRING, 0, 0 },
9798
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
9899
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
99100
{ 'b', 0, 2, etBLOB, 0, 0 },
100101
{ 'B', 0, 2, etBLOBSQL, 0, 0 },
101
- { 'w', 0, 2, etWIKISTR, 0, 0 },
102
+ { 'W', 0, 2, etWIKISTR, 0, 0 },
102103
{ 'h', 0, 4, etHTMLIZE, 0, 0 },
103104
{ 'R', 0, 0, etROOT, 0, 0 },
104105
{ 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
105106
{ 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
107
+ { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
106108
{ 'F', 0, 4, etFOSSILIZE, 0, 0 },
107109
{ 'S', 0, 4, etSTRINGID, 0, 0 },
108110
{ 'c', 0, 0, etCHARX, 0, 0 },
109111
{ 'o', 8, 0, etRADIX, 0, 2 },
110112
{ 'u', 10, 0, etRADIX, 0, 0 },
@@ -661,35 +663,37 @@
661663
length = j;
662664
assert( length==n+cnt+2 );
663665
break;
664666
}
665667
case etSQLESCAPE:
666
- case etSQLESCAPE2: {
668
+ case etSQLESCAPE2:
669
+ case etSQLESCAPE3: {
667670
int i, j, n, ch, isnull;
668671
int needQuote;
669672
int limit = flag_alternateform ? va_arg(ap,int) : -1;
673
+ char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */
670674
char *escarg = va_arg(ap,char*);
671675
isnull = escarg==0;
672676
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
673677
if( limit<0 ) limit = strlen(escarg);
674678
for(i=n=0; i<limit; i++){
675
- if( escarg[i]=='\'' ) n++;
679
+ if( escarg[i]==q ) n++;
676680
}
677681
needQuote = !isnull && xtype==etSQLESCAPE2;
678682
n += i + 1 + needQuote*2;
679683
if( n>etBUFSIZE ){
680684
bufpt = zExtra = fossil_malloc( n );
681685
}else{
682686
bufpt = buf;
683687
}
684688
j = 0;
685
- if( needQuote ) bufpt[j++] = '\'';
689
+ if( needQuote ) bufpt[j++] = q;
686690
for(i=0; i<limit; i++){
687691
bufpt[j++] = ch = escarg[i];
688
- if( ch=='\'' ) bufpt[j++] = ch;
692
+ if( ch==q ) bufpt[j++] = ch;
689693
}
690
- if( needQuote ) bufpt[j++] = '\'';
694
+ if( needQuote ) bufpt[j++] = q;
691695
bufpt[j] = 0;
692696
length = j;
693697
if( precision>=0 && precision<length ) length = precision;
694698
break;
695699
}
696700
--- src/printf.c
+++ src/printf.c
@@ -44,19 +44,20 @@
44 #define etBLOB 11 /* Blob objects. %b */
45 #define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */
46 #define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */
47 #define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
48 NULL pointers replaced by SQL NULL. %Q */
49 #define etPOINTER 15 /* The %p conversion */
50 #define etHTMLIZE 16 /* Make text safe for HTML */
51 #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */
52 #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */
53 #define etFOSSILIZE 19 /* The fossil header encoding format. */
54 #define etPATH 20 /* Path type */
55 #define etWIKISTR 21 /* Timeline comment text rendered from a char*: %w */
 
56 #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
57 #define etROOT 24 /* String value of g.zTop: % */
58
59
60 /*
61 ** An "etByte" is an 8-bit unsigned value.
62 */
@@ -96,15 +97,16 @@
96 { 'z', 0, 6, etDYNSTRING, 0, 0 },
97 { 'q', 0, 4, etSQLESCAPE, 0, 0 },
98 { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
99 { 'b', 0, 2, etBLOB, 0, 0 },
100 { 'B', 0, 2, etBLOBSQL, 0, 0 },
101 { 'w', 0, 2, etWIKISTR, 0, 0 },
102 { 'h', 0, 4, etHTMLIZE, 0, 0 },
103 { 'R', 0, 0, etROOT, 0, 0 },
104 { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
105 { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
 
106 { 'F', 0, 4, etFOSSILIZE, 0, 0 },
107 { 'S', 0, 4, etSTRINGID, 0, 0 },
108 { 'c', 0, 0, etCHARX, 0, 0 },
109 { 'o', 8, 0, etRADIX, 0, 2 },
110 { 'u', 10, 0, etRADIX, 0, 0 },
@@ -661,35 +663,37 @@
661 length = j;
662 assert( length==n+cnt+2 );
663 break;
664 }
665 case etSQLESCAPE:
666 case etSQLESCAPE2: {
 
667 int i, j, n, ch, isnull;
668 int needQuote;
669 int limit = flag_alternateform ? va_arg(ap,int) : -1;
 
670 char *escarg = va_arg(ap,char*);
671 isnull = escarg==0;
672 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
673 if( limit<0 ) limit = strlen(escarg);
674 for(i=n=0; i<limit; i++){
675 if( escarg[i]=='\'' ) n++;
676 }
677 needQuote = !isnull && xtype==etSQLESCAPE2;
678 n += i + 1 + needQuote*2;
679 if( n>etBUFSIZE ){
680 bufpt = zExtra = fossil_malloc( n );
681 }else{
682 bufpt = buf;
683 }
684 j = 0;
685 if( needQuote ) bufpt[j++] = '\'';
686 for(i=0; i<limit; i++){
687 bufpt[j++] = ch = escarg[i];
688 if( ch=='\'' ) bufpt[j++] = ch;
689 }
690 if( needQuote ) bufpt[j++] = '\'';
691 bufpt[j] = 0;
692 length = j;
693 if( precision>=0 && precision<length ) length = precision;
694 break;
695 }
696
--- src/printf.c
+++ src/printf.c
@@ -44,19 +44,20 @@
44 #define etBLOB 11 /* Blob objects. %b */
45 #define etBLOBSQL 12 /* Blob objects quoted for SQL. %B */
46 #define etSQLESCAPE 13 /* Strings with '\'' doubled. %q */
47 #define etSQLESCAPE2 14 /* Strings with '\'' doubled and enclosed in '',
48 NULL pointers replaced by SQL NULL. %Q */
49 #define etSQLESCAPE3 15 /* Double '"' characters within an indentifier. %w */
50 #define etPOINTER 16 /* The %p conversion */
51 #define etHTMLIZE 17 /* Make text safe for HTML */
52 #define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */
53 #define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */
54 #define etFOSSILIZE 20 /* The fossil header encoding format. */
55 #define etPATH 21 /* Path type */
56 #define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
57 #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
58 #define etROOT 24 /* String value of g.zTop: %R */
59
60
61 /*
62 ** An "etByte" is an 8-bit unsigned value.
63 */
@@ -96,15 +97,16 @@
97 { 'z', 0, 6, etDYNSTRING, 0, 0 },
98 { 'q', 0, 4, etSQLESCAPE, 0, 0 },
99 { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
100 { 'b', 0, 2, etBLOB, 0, 0 },
101 { 'B', 0, 2, etBLOBSQL, 0, 0 },
102 { 'W', 0, 2, etWIKISTR, 0, 0 },
103 { 'h', 0, 4, etHTMLIZE, 0, 0 },
104 { 'R', 0, 0, etROOT, 0, 0 },
105 { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
106 { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
107 { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
108 { 'F', 0, 4, etFOSSILIZE, 0, 0 },
109 { 'S', 0, 4, etSTRINGID, 0, 0 },
110 { 'c', 0, 0, etCHARX, 0, 0 },
111 { 'o', 8, 0, etRADIX, 0, 2 },
112 { 'u', 10, 0, etRADIX, 0, 0 },
@@ -661,35 +663,37 @@
663 length = j;
664 assert( length==n+cnt+2 );
665 break;
666 }
667 case etSQLESCAPE:
668 case etSQLESCAPE2:
669 case etSQLESCAPE3: {
670 int i, j, n, ch, isnull;
671 int needQuote;
672 int limit = flag_alternateform ? va_arg(ap,int) : -1;
673 char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote characters */
674 char *escarg = va_arg(ap,char*);
675 isnull = escarg==0;
676 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
677 if( limit<0 ) limit = strlen(escarg);
678 for(i=n=0; i<limit; i++){
679 if( escarg[i]==q ) n++;
680 }
681 needQuote = !isnull && xtype==etSQLESCAPE2;
682 n += i + 1 + needQuote*2;
683 if( n>etBUFSIZE ){
684 bufpt = zExtra = fossil_malloc( n );
685 }else{
686 bufpt = buf;
687 }
688 j = 0;
689 if( needQuote ) bufpt[j++] = q;
690 for(i=0; i<limit; i++){
691 bufpt[j++] = ch = escarg[i];
692 if( ch==q ) bufpt[j++] = ch;
693 }
694 if( needQuote ) bufpt[j++] = q;
695 bufpt[j] = 0;
696 length = j;
697 if( precision>=0 && precision<length ) length = precision;
698 break;
699 }
700
+9 -8
--- src/rebuild.c
+++ src/rebuild.c
@@ -81,12 +81,12 @@
8181
@ );
8282
;
8383
8484
static void rebuild_update_schema(void){
8585
int rc;
86
- db_multi_exec(zSchemaUpdates1);
87
- db_multi_exec(zSchemaUpdates2);
86
+ db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/);
87
+ db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/);
8888
8989
rc = db_exists("SELECT 1 FROM sqlite_master"
9090
" WHERE name='user' AND sql GLOB '* mtime *'");
9191
if( rc==0 ){
9292
db_multi_exec(
@@ -135,11 +135,11 @@
135135
if( rc==0 ){
136136
db_multi_exec(
137137
"CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
138138
"DROP TABLE reportfmt;"
139139
);
140
- db_multi_exec(zSchemaUpdates2);
140
+ db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/);
141141
db_multi_exec(
142142
"INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
143143
" SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
144144
"INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
145145
" SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
@@ -254,11 +254,12 @@
254254
/* We are doing "fossil rebuild" */
255255
manifest_crosslink(rid, pUse, MC_NONE);
256256
}else{
257257
/* We are doing "fossil deconstruct" */
258258
char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
259
- char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
259
+ char *zFile = mprintf(zFNameFormat /*works-like:"%s:%s"*/,
260
+ zUuid, zUuid+prefixLength);
260261
blob_write_to_file(pUse,zFile);
261262
free(zFile);
262263
free(zUuid);
263264
blob_reset(pUse);
264265
}
@@ -355,11 +356,11 @@
355356
);
356357
if( zTable==0 ) break;
357358
db_multi_exec("DROP TABLE %Q", zTable);
358359
free(zTable);
359360
}
360
- db_multi_exec(zRepositorySchema2);
361
+ db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
361362
ticket_create_table(0);
362363
shun_artifacts();
363364
364365
db_multi_exec(
365366
"INSERT INTO unclustered"
@@ -587,13 +588,13 @@
587588
db_begin_transaction();
588589
ttyOutput = 1;
589590
errCnt = rebuild_db(randomizeFlag, 1, doClustering);
590591
reconstruct_private_table();
591592
db_multi_exec(
592
- "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());"
593
- "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());"
594
- "REPLACE INTO config(name,value,mtime) VALUES('rebuilt','%s',now());",
593
+ "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
594
+ "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
595
+ "REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());",
595596
CONTENT_SCHEMA, AUX_SCHEMA, get_version()
596597
);
597598
if( errCnt && !forceFlag ){
598599
fossil_print(
599600
"%d errors. Rolling back changes. Use --force to force a commit.\n",
600601
--- src/rebuild.c
+++ src/rebuild.c
@@ -81,12 +81,12 @@
81 @ );
82 ;
83
84 static void rebuild_update_schema(void){
85 int rc;
86 db_multi_exec(zSchemaUpdates1);
87 db_multi_exec(zSchemaUpdates2);
88
89 rc = db_exists("SELECT 1 FROM sqlite_master"
90 " WHERE name='user' AND sql GLOB '* mtime *'");
91 if( rc==0 ){
92 db_multi_exec(
@@ -135,11 +135,11 @@
135 if( rc==0 ){
136 db_multi_exec(
137 "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
138 "DROP TABLE reportfmt;"
139 );
140 db_multi_exec(zSchemaUpdates2);
141 db_multi_exec(
142 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
143 " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
144 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
145 " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
@@ -254,11 +254,12 @@
254 /* We are doing "fossil rebuild" */
255 manifest_crosslink(rid, pUse, MC_NONE);
256 }else{
257 /* We are doing "fossil deconstruct" */
258 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
259 char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
 
260 blob_write_to_file(pUse,zFile);
261 free(zFile);
262 free(zUuid);
263 blob_reset(pUse);
264 }
@@ -355,11 +356,11 @@
355 );
356 if( zTable==0 ) break;
357 db_multi_exec("DROP TABLE %Q", zTable);
358 free(zTable);
359 }
360 db_multi_exec(zRepositorySchema2);
361 ticket_create_table(0);
362 shun_artifacts();
363
364 db_multi_exec(
365 "INSERT INTO unclustered"
@@ -587,13 +588,13 @@
587 db_begin_transaction();
588 ttyOutput = 1;
589 errCnt = rebuild_db(randomizeFlag, 1, doClustering);
590 reconstruct_private_table();
591 db_multi_exec(
592 "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());"
593 "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());"
594 "REPLACE INTO config(name,value,mtime) VALUES('rebuilt','%s',now());",
595 CONTENT_SCHEMA, AUX_SCHEMA, get_version()
596 );
597 if( errCnt && !forceFlag ){
598 fossil_print(
599 "%d errors. Rolling back changes. Use --force to force a commit.\n",
600
--- src/rebuild.c
+++ src/rebuild.c
@@ -81,12 +81,12 @@
81 @ );
82 ;
83
84 static void rebuild_update_schema(void){
85 int rc;
86 db_multi_exec("%s", zSchemaUpdates1 /*safe-for-%s*/);
87 db_multi_exec("%s", zSchemaUpdates2 /*safe-for-%s*/);
88
89 rc = db_exists("SELECT 1 FROM sqlite_master"
90 " WHERE name='user' AND sql GLOB '* mtime *'");
91 if( rc==0 ){
92 db_multi_exec(
@@ -135,11 +135,11 @@
135 if( rc==0 ){
136 db_multi_exec(
137 "CREATE TEMP TABLE old_fmt AS SELECT * FROM reportfmt;"
138 "DROP TABLE reportfmt;"
139 );
140 db_multi_exec("%s", zSchemaUpdates2/*safe-for-%s*/);
141 db_multi_exec(
142 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
143 " SELECT rn, owner, title, cols, sqlcode, now() FROM old_fmt;"
144 "INSERT OR IGNORE INTO reportfmt(rn,owner,title,cols,sqlcode,mtime)"
145 " SELECT rn, owner, title || ' (' || rn || ')', cols, sqlcode, now()"
@@ -254,11 +254,12 @@
254 /* We are doing "fossil rebuild" */
255 manifest_crosslink(rid, pUse, MC_NONE);
256 }else{
257 /* We are doing "fossil deconstruct" */
258 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
259 char *zFile = mprintf(zFNameFormat /*works-like:"%s:%s"*/,
260 zUuid, zUuid+prefixLength);
261 blob_write_to_file(pUse,zFile);
262 free(zFile);
263 free(zUuid);
264 blob_reset(pUse);
265 }
@@ -355,11 +356,11 @@
356 );
357 if( zTable==0 ) break;
358 db_multi_exec("DROP TABLE %Q", zTable);
359 free(zTable);
360 }
361 db_multi_exec("%s", zRepositorySchema2/*safe-for-%s*/);
362 ticket_create_table(0);
363 shun_artifacts();
364
365 db_multi_exec(
366 "INSERT INTO unclustered"
@@ -587,13 +588,13 @@
588 db_begin_transaction();
589 ttyOutput = 1;
590 errCnt = rebuild_db(randomizeFlag, 1, doClustering);
591 reconstruct_private_table();
592 db_multi_exec(
593 "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
594 "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
595 "REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());",
596 CONTENT_SCHEMA, AUX_SCHEMA, get_version()
597 );
598 if( errCnt && !forceFlag ){
599 fossil_print(
600 "%d errors. Rolling back changes. Use --force to force a commit.\n",
601
+5 -7
--- src/report.c
+++ src/report.c
@@ -436,11 +436,11 @@
436436
if( zOwner==0 ) zOwner = g.zLogin;
437437
style_submenu_element("Cancel", "Cancel", "reportlist");
438438
if( rn>0 ){
439439
style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
440440
}
441
- style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
441
+ style_header("%s", rn>0 ? "Edit Report Format":"Create New Report Format");
442442
if( zErr ){
443443
@ <blockquote class="reportError">%h(zErr)</blockquote>
444444
}
445445
@ <form action="rptedit" method="post"><div>
446446
@ <input type="hidden" name="rn" value="%d(rn)" />
@@ -1070,11 +1070,11 @@
10701070
}
10711071
if( g.perm.NewTkt ){
10721072
style_submenu_element("New Ticket", "Create a new ticket",
10731073
"%s/tktnew", g.zTop);
10741074
}
1075
- style_header(zTitle);
1075
+ style_header("%s", zTitle);
10761076
output_color_key(zClrKey, 1,
10771077
"border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
10781078
@ <table border="1" cellpadding="2" cellspacing="0" class="report"
10791079
@ id="reportTable">
10801080
sState.rn = rn;
@@ -1112,21 +1112,19 @@
11121112
** show all reports, which can be used for ticket show.
11131113
** Output is written to stdout as tab delimited table
11141114
*/
11151115
void rpt_list_reports(void){
11161116
Stmt q;
1117
- const char aRptOutFrmt[] = "%s\t%s\n";
1118
-
11191117
fossil_print("Available reports:\n");
1120
- fossil_print(aRptOutFrmt,"report number","report title");
1121
- fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
1118
+ fossil_print("%s\t%s\n","report number","report title");
1119
+ fossil_print("%s\t%s\n",zFullTicketRptRn,zFullTicketRptTitle);
11221120
db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
11231121
while( db_step(&q)==SQLITE_ROW ){
11241122
const char *zRn = db_column_text(&q, 0);
11251123
const char *zTitle = db_column_text(&q, 1);
11261124
1127
- fossil_print(aRptOutFrmt,zRn,zTitle);
1125
+ fossil_print("%s\t%s\n",zRn,zTitle);
11281126
}
11291127
db_finalize(&q);
11301128
}
11311129
11321130
/*
11331131
--- src/report.c
+++ src/report.c
@@ -436,11 +436,11 @@
436 if( zOwner==0 ) zOwner = g.zLogin;
437 style_submenu_element("Cancel", "Cancel", "reportlist");
438 if( rn>0 ){
439 style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
440 }
441 style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
442 if( zErr ){
443 @ <blockquote class="reportError">%h(zErr)</blockquote>
444 }
445 @ <form action="rptedit" method="post"><div>
446 @ <input type="hidden" name="rn" value="%d(rn)" />
@@ -1070,11 +1070,11 @@
1070 }
1071 if( g.perm.NewTkt ){
1072 style_submenu_element("New Ticket", "Create a new ticket",
1073 "%s/tktnew", g.zTop);
1074 }
1075 style_header(zTitle);
1076 output_color_key(zClrKey, 1,
1077 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
1078 @ <table border="1" cellpadding="2" cellspacing="0" class="report"
1079 @ id="reportTable">
1080 sState.rn = rn;
@@ -1112,21 +1112,19 @@
1112 ** show all reports, which can be used for ticket show.
1113 ** Output is written to stdout as tab delimited table
1114 */
1115 void rpt_list_reports(void){
1116 Stmt q;
1117 const char aRptOutFrmt[] = "%s\t%s\n";
1118
1119 fossil_print("Available reports:\n");
1120 fossil_print(aRptOutFrmt,"report number","report title");
1121 fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
1122 db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
1123 while( db_step(&q)==SQLITE_ROW ){
1124 const char *zRn = db_column_text(&q, 0);
1125 const char *zTitle = db_column_text(&q, 1);
1126
1127 fossil_print(aRptOutFrmt,zRn,zTitle);
1128 }
1129 db_finalize(&q);
1130 }
1131
1132 /*
1133
--- src/report.c
+++ src/report.c
@@ -436,11 +436,11 @@
436 if( zOwner==0 ) zOwner = g.zLogin;
437 style_submenu_element("Cancel", "Cancel", "reportlist");
438 if( rn>0 ){
439 style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
440 }
441 style_header("%s", rn>0 ? "Edit Report Format":"Create New Report Format");
442 if( zErr ){
443 @ <blockquote class="reportError">%h(zErr)</blockquote>
444 }
445 @ <form action="rptedit" method="post"><div>
446 @ <input type="hidden" name="rn" value="%d(rn)" />
@@ -1070,11 +1070,11 @@
1070 }
1071 if( g.perm.NewTkt ){
1072 style_submenu_element("New Ticket", "Create a new ticket",
1073 "%s/tktnew", g.zTop);
1074 }
1075 style_header("%s", zTitle);
1076 output_color_key(zClrKey, 1,
1077 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
1078 @ <table border="1" cellpadding="2" cellspacing="0" class="report"
1079 @ id="reportTable">
1080 sState.rn = rn;
@@ -1112,21 +1112,19 @@
1112 ** show all reports, which can be used for ticket show.
1113 ** Output is written to stdout as tab delimited table
1114 */
1115 void rpt_list_reports(void){
1116 Stmt q;
 
 
1117 fossil_print("Available reports:\n");
1118 fossil_print("%s\t%s\n","report number","report title");
1119 fossil_print("%s\t%s\n",zFullTicketRptRn,zFullTicketRptTitle);
1120 db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
1121 while( db_step(&q)==SQLITE_ROW ){
1122 const char *zRn = db_column_text(&q, 0);
1123 const char *zTitle = db_column_text(&q, 1);
1124
1125 fossil_print("%s\t%s\n",zRn,zTitle);
1126 }
1127 db_finalize(&q);
1128 }
1129
1130 /*
1131
+10 -10
--- src/rss.c
+++ src/rss.c
@@ -76,11 +76,11 @@
7676
7777
if( zType[0]!='a' ){
7878
if( zType[0]=='c' && !g.perm.Read ) zType = "x";
7979
if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
8080
if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
81
- blob_appendf(&bSQL, " AND event.type=%Q", zType);
81
+ blob_append_sql(&bSQL, " AND event.type=%Q", zType);
8282
}else{
8383
if( !g.perm.Read ){
8484
if( g.perm.RdTkt && g.perm.RdWiki ){
8585
blob_append(&bSQL, " AND event.type!='ci'", -1);
8686
}else if( g.perm.RdTkt ){
@@ -122,18 +122,18 @@
122122
}else{
123123
nTagId = 0;
124124
}
125125
126126
if( nTagId==-1 ){
127
- blob_appendf(&bSQL, " AND 0");
127
+ blob_append_sql(&bSQL, " AND 0");
128128
}else if( nTagId!=0 ){
129
- blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
129
+ blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
130130
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
131131
}
132132
133133
if( zFilename ){
134
- blob_appendf(&bSQL,
134
+ blob_append_sql(&bSQL,
135135
" AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
136136
zFilename, filename_collation()
137137
);
138138
}
139139
@@ -160,11 +160,11 @@
160160
@ <link>%s(g.zBaseURL)</link>
161161
@ <description>%h(zProjectDescr)</description>
162162
@ <pubDate>%s(zPubDate)</pubDate>
163163
@ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
164164
free(zPubDate);
165
- db_prepare(&q, blob_str(&bSQL));
165
+ db_prepare(&q, "%s", blob_sql_text(&bSQL));
166166
blob_reset( &bSQL );
167167
while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
168168
const char *zId = db_column_text(&q, 1);
169169
const char *zCom = db_column_text(&q, 3);
170170
const char *zAuthor = db_column_text(&q, 4);
@@ -280,11 +280,11 @@
280280
281281
blob_zero(&bSQL);
282282
blob_append( &bSQL, zSQL1, -1 );
283283
284284
if( zType[0]!='a' ){
285
- blob_appendf(&bSQL, " AND event.type=%Q", zType);
285
+ blob_append_sql(&bSQL, " AND event.type=%Q", zType);
286286
}
287287
288288
if( zTicketUuid ){
289289
nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
290290
zTicketUuid);
@@ -306,18 +306,18 @@
306306
}else{
307307
nTagId = 0;
308308
}
309309
310310
if( nTagId==-1 ){
311
- blob_appendf(&bSQL, " AND 0");
311
+ blob_append_sql(&bSQL, " AND 0");
312312
}else if( nTagId!=0 ){
313
- blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
313
+ blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
314314
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
315315
}
316316
317317
if( zFilename ){
318
- blob_appendf(&bSQL,
318
+ blob_append_sql(&bSQL,
319319
" AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
320320
zFilename, filename_collation()
321321
);
322322
}
323323
@@ -343,11 +343,11 @@
343343
fossil_print("<description>%h</description>\n", zProjectDescr);
344344
fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
345345
fossil_print("<generator>Fossil version %s %s</generator>\n",
346346
MANIFEST_VERSION, MANIFEST_DATE);
347347
free(zPubDate);
348
- db_prepare(&q, blob_str(&bSQL));
348
+ db_prepare(&q, "%s", blob_sql_text(&bSQL));
349349
blob_reset( &bSQL );
350350
while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
351351
const char *zId = db_column_text(&q, 1);
352352
const char *zCom = db_column_text(&q, 3);
353353
const char *zAuthor = db_column_text(&q, 4);
354354
--- src/rss.c
+++ src/rss.c
@@ -76,11 +76,11 @@
76
77 if( zType[0]!='a' ){
78 if( zType[0]=='c' && !g.perm.Read ) zType = "x";
79 if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
80 if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
81 blob_appendf(&bSQL, " AND event.type=%Q", zType);
82 }else{
83 if( !g.perm.Read ){
84 if( g.perm.RdTkt && g.perm.RdWiki ){
85 blob_append(&bSQL, " AND event.type!='ci'", -1);
86 }else if( g.perm.RdTkt ){
@@ -122,18 +122,18 @@
122 }else{
123 nTagId = 0;
124 }
125
126 if( nTagId==-1 ){
127 blob_appendf(&bSQL, " AND 0");
128 }else if( nTagId!=0 ){
129 blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
130 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
131 }
132
133 if( zFilename ){
134 blob_appendf(&bSQL,
135 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
136 zFilename, filename_collation()
137 );
138 }
139
@@ -160,11 +160,11 @@
160 @ <link>%s(g.zBaseURL)</link>
161 @ <description>%h(zProjectDescr)</description>
162 @ <pubDate>%s(zPubDate)</pubDate>
163 @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
164 free(zPubDate);
165 db_prepare(&q, blob_str(&bSQL));
166 blob_reset( &bSQL );
167 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
168 const char *zId = db_column_text(&q, 1);
169 const char *zCom = db_column_text(&q, 3);
170 const char *zAuthor = db_column_text(&q, 4);
@@ -280,11 +280,11 @@
280
281 blob_zero(&bSQL);
282 blob_append( &bSQL, zSQL1, -1 );
283
284 if( zType[0]!='a' ){
285 blob_appendf(&bSQL, " AND event.type=%Q", zType);
286 }
287
288 if( zTicketUuid ){
289 nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
290 zTicketUuid);
@@ -306,18 +306,18 @@
306 }else{
307 nTagId = 0;
308 }
309
310 if( nTagId==-1 ){
311 blob_appendf(&bSQL, " AND 0");
312 }else if( nTagId!=0 ){
313 blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
314 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
315 }
316
317 if( zFilename ){
318 blob_appendf(&bSQL,
319 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
320 zFilename, filename_collation()
321 );
322 }
323
@@ -343,11 +343,11 @@
343 fossil_print("<description>%h</description>\n", zProjectDescr);
344 fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
345 fossil_print("<generator>Fossil version %s %s</generator>\n",
346 MANIFEST_VERSION, MANIFEST_DATE);
347 free(zPubDate);
348 db_prepare(&q, blob_str(&bSQL));
349 blob_reset( &bSQL );
350 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
351 const char *zId = db_column_text(&q, 1);
352 const char *zCom = db_column_text(&q, 3);
353 const char *zAuthor = db_column_text(&q, 4);
354
--- src/rss.c
+++ src/rss.c
@@ -76,11 +76,11 @@
76
77 if( zType[0]!='a' ){
78 if( zType[0]=='c' && !g.perm.Read ) zType = "x";
79 if( zType[0]=='w' && !g.perm.RdWiki ) zType = "x";
80 if( zType[0]=='t' && !g.perm.RdTkt ) zType = "x";
81 blob_append_sql(&bSQL, " AND event.type=%Q", zType);
82 }else{
83 if( !g.perm.Read ){
84 if( g.perm.RdTkt && g.perm.RdWiki ){
85 blob_append(&bSQL, " AND event.type!='ci'", -1);
86 }else if( g.perm.RdTkt ){
@@ -122,18 +122,18 @@
122 }else{
123 nTagId = 0;
124 }
125
126 if( nTagId==-1 ){
127 blob_append_sql(&bSQL, " AND 0");
128 }else if( nTagId!=0 ){
129 blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
130 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
131 }
132
133 if( zFilename ){
134 blob_append_sql(&bSQL,
135 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
136 zFilename, filename_collation()
137 );
138 }
139
@@ -160,11 +160,11 @@
160 @ <link>%s(g.zBaseURL)</link>
161 @ <description>%h(zProjectDescr)</description>
162 @ <pubDate>%s(zPubDate)</pubDate>
163 @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
164 free(zPubDate);
165 db_prepare(&q, "%s", blob_sql_text(&bSQL));
166 blob_reset( &bSQL );
167 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
168 const char *zId = db_column_text(&q, 1);
169 const char *zCom = db_column_text(&q, 3);
170 const char *zAuthor = db_column_text(&q, 4);
@@ -280,11 +280,11 @@
280
281 blob_zero(&bSQL);
282 blob_append( &bSQL, zSQL1, -1 );
283
284 if( zType[0]!='a' ){
285 blob_append_sql(&bSQL, " AND event.type=%Q", zType);
286 }
287
288 if( zTicketUuid ){
289 nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
290 zTicketUuid);
@@ -306,18 +306,18 @@
306 }else{
307 nTagId = 0;
308 }
309
310 if( nTagId==-1 ){
311 blob_append_sql(&bSQL, " AND 0");
312 }else if( nTagId!=0 ){
313 blob_append_sql(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
314 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
315 }
316
317 if( zFilename ){
318 blob_append_sql(&bSQL,
319 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
320 zFilename, filename_collation()
321 );
322 }
323
@@ -343,11 +343,11 @@
343 fossil_print("<description>%h</description>\n", zProjectDescr);
344 fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
345 fossil_print("<generator>Fossil version %s %s</generator>\n",
346 MANIFEST_VERSION, MANIFEST_DATE);
347 free(zPubDate);
348 db_prepare(&q, "%s", blob_sql_text(&bSQL));
349 blob_reset( &bSQL );
350 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
351 const char *zId = db_column_text(&q, 1);
352 const char *zCom = db_column_text(&q, 3);
353 const char *zAuthor = db_column_text(&q, 4);
354
+2 -2
--- src/search.c
+++ src/search.c
@@ -231,13 +231,13 @@
231231
iBest = db_int(0, "SELECT max(x) FROM srch");
232232
blob_append(&sql,
233233
"SELECT rid, uuid, date, comment, 0, 0 FROM srch "
234234
"WHERE 1 ", -1);
235235
if(!fAll){
236
- blob_appendf(&sql,"AND x>%d ", iBest/3);
236
+ blob_append_sql(&sql,"AND x>%d ", iBest/3);
237237
}
238238
blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
239
- db_prepare(&q, blob_str(&sql));
239
+ db_prepare(&q, "%s", blob_sql_text(&sql));
240240
blob_reset(&sql);
241241
print_timeline(&q, nLimit, width, 0);
242242
db_finalize(&q);
243243
}
244244
--- src/search.c
+++ src/search.c
@@ -231,13 +231,13 @@
231 iBest = db_int(0, "SELECT max(x) FROM srch");
232 blob_append(&sql,
233 "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
234 "WHERE 1 ", -1);
235 if(!fAll){
236 blob_appendf(&sql,"AND x>%d ", iBest/3);
237 }
238 blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
239 db_prepare(&q, blob_str(&sql));
240 blob_reset(&sql);
241 print_timeline(&q, nLimit, width, 0);
242 db_finalize(&q);
243 }
244
--- src/search.c
+++ src/search.c
@@ -231,13 +231,13 @@
231 iBest = db_int(0, "SELECT max(x) FROM srch");
232 blob_append(&sql,
233 "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
234 "WHERE 1 ", -1);
235 if(!fAll){
236 blob_append_sql(&sql,"AND x>%d ", iBest/3);
237 }
238 blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
239 db_prepare(&q, "%s", blob_sql_text(&sql));
240 blob_reset(&sql);
241 print_timeline(&q, nLimit, width, 0);
242 db_finalize(&q);
243 }
244
+109 -35
--- src/setup.c
+++ src/setup.c
@@ -307,11 +307,11 @@
307307
int uid, i;
308308
int higherUser = 0; /* True if user being edited is SETUP and the */
309309
/* user doing the editing is ADMIN. Disallow editing */
310310
char *inherit[128];
311311
int a[128];
312
- char *oa[128];
312
+ const char *oa[128];
313313
314314
/* Must have ADMIN privileges to access this page
315315
*/
316316
login_check_credentials();
317317
if( !g.perm.Admin ){ login_needed(); return; }
@@ -375,11 +375,11 @@
375375
return;
376376
}
377377
login_verify_csrf_secret();
378378
db_multi_exec(
379379
"REPLACE INTO user(uid,login,info,pw,cap,mtime) "
380
- "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s',now())",
380
+ "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
381381
uid, P("login"), P("info"), zPw, zCap
382382
);
383383
if( atoi(PD("all","0"))>0 ){
384384
Blob sql;
385385
char *zErr = 0;
@@ -441,47 +441,47 @@
441441
if( fossil_strcmp(zLogin, "developer") ){
442442
char *z1, *z2;
443443
z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
444444
while( z1 && *z1 ){
445445
inherit[0x7f & *(z1++)] =
446
- "<span class=\"ueditInheritDeveloper\"><sub>D</sub></span>";
446
+ "<span class=\"ueditInheritDeveloper\"><sub>[D]</sub></span>";
447447
}
448448
free(z2);
449449
}
450450
if( fossil_strcmp(zLogin, "reader") ){
451451
char *z1, *z2;
452452
z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
453453
while( z1 && *z1 ){
454454
inherit[0x7f & *(z1++)] =
455
- "<span class=\"ueditInheritReader\"><sub>R</sub></span>";
455
+ "<span class=\"ueditInheritReader\"><sub>[R]</sub></span>";
456456
}
457457
free(z2);
458458
}
459459
if( fossil_strcmp(zLogin, "anonymous") ){
460460
char *z1, *z2;
461461
z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
462462
while( z1 && *z1 ){
463463
inherit[0x7f & *(z1++)] =
464
- "<span class=\"ueditInheritAnonymous\"><sub>A</sub></span>";
464
+ "<span class=\"ueditInheritAnonymous\"><sub>[A]</sub></span>";
465465
}
466466
free(z2);
467467
}
468468
if( fossil_strcmp(zLogin, "nobody") ){
469469
char *z1, *z2;
470470
z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
471471
while( z1 && *z1 ){
472472
inherit[0x7f & *(z1++)] =
473
- "<span class=\"ueditInheritNobody\"><sub>N</sub></span>";
473
+ "<span class=\"ueditInheritNobody\"><sub>[N]</sub></span>";
474474
}
475475
free(z2);
476476
}
477477
478478
/* Begin generating the page
479479
*/
480480
style_submenu_element("Cancel", "Cancel", "setup_ulist");
481481
if( uid ){
482
- style_header(mprintf("Edit User %h", zLogin));
482
+ style_header("Edit User %h", zLogin);
483483
}else{
484484
style_header("Add A New User");
485485
}
486486
@ <div class="ueditCapBox">
487487
@ <form action="%s(g.zPath)" method="post"><div>
@@ -489,10 +489,47 @@
489489
if( login_is_special(zLogin) ){
490490
@ <input type="hidden" name="login" value="%s(zLogin)">
491491
@ <input type="hidden" name="info" value="">
492492
@ <input type="hidden" name="pw" value="*">
493493
}
494
+ @ <script type='text/javascript'>
495
+ @ function updateCapabilityString(){
496
+ @ /*
497
+ @ ** This function updates the "#usetupEditCapability" span content
498
+ @ ** with the capabilities selected by the interactive user, based
499
+ @ ** upon the state of the capability checkboxes.
500
+ @ */
501
+ @ try {
502
+ @ var inputs = document.getElementsByTagName('input');
503
+ @ if( inputs && inputs.length ){
504
+ @ var output = document.getElementById('usetupEditCapability');
505
+ @ if( output ){
506
+ @ var permsIds = [], x = 0;
507
+ @ for(var i = 0; i < inputs.length; i++){
508
+ @ var e = inputs[i];
509
+ @ if( !e.name || !e.type ) continue;
510
+ @ if( e.type.toLowerCase()!=='checkbox' ) continue;
511
+ @ if( e.name.length===2 && e.name[0]==='a' ){
512
+ @ // looks like a capability checkbox
513
+ @ if( e.checked ){
514
+ @ // grab the second character of the element
515
+ @ // name, which is the textual flag for this
516
+ @ // capability, and then add it to the result
517
+ @ // array.
518
+ @ permsIds[x++] = e.name[1];
519
+ @ }
520
+ @ }
521
+ @ }
522
+ @ permsIds.sort();
523
+ @ output.innerHTML = permsIds.join('');
524
+ @ }
525
+ @ }
526
+ @ } catch (e) {
527
+ @ /* ignore errors */
528
+ @ }
529
+ @ }
530
+ @ </script>
494531
@ <table>
495532
@ <tr>
496533
@ <td class="usetupEditLabel">User ID:</td>
497534
if( uid ){
498535
@ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td>
@@ -516,64 +553,96 @@
516553
@ <td class="usetupEditLabel">Capabilities:</td>
517554
@ <td>
518555
#define B(x) inherit[x]
519556
@ <table border=0><tr><td valign="top">
520557
if( g.perm.Setup ){
521
- @ <label><input type="checkbox" name="as"%s(oa['s']) />
558
+ @ <label><input type="checkbox" name="as"%s(oa['s'])
559
+ @ onchange="updateCapabilityString()"/>
522560
@ Setup%s(B('s'))</label><br />
523561
}
524
- @ <label><input type="checkbox" name="aa"%s(oa['a']) />
562
+ @ <label><input type="checkbox" name="aa"%s(oa['a'])
563
+ @ onchange="updateCapabilityString()" />
525564
@ Admin%s(B('a'))</label><br />
526
- @ <label><input type="checkbox" name="ad"%s(oa['d']) />
565
+ @ <label><input type="checkbox" name="ad"%s(oa['d'])
566
+ @ onchange="updateCapabilityString()" />
527567
@ Delete%s(B('d'))</label><br />
528
- @ <label><input type="checkbox" name="ae"%s(oa['e']) />
568
+ @ <label><input type="checkbox" name="ae"%s(oa['e'])
569
+ @ onchange="updateCapabilityString()" />
529570
@ Email%s(B('e'))</label><br />
530
- @ <label><input type="checkbox" name="ap"%s(oa['p']) />
571
+ @ <label><input type="checkbox" name="ap"%s(oa['p'])
572
+ @ onchange="updateCapabilityString()" />
531573
@ Password%s(B('p'))</label><br />
532
- @ <label><input type="checkbox" name="ai"%s(oa['i']) />
574
+ @ <label><input type="checkbox" name="ai"%s(oa['i'])
575
+ @ onchange="updateCapabilityString()" />
533576
@ Check-In%s(B('i'))</label><br />
534
- @ <label><input type="checkbox" name="ao"%s(oa['o']) />
577
+ @ <label><input type="checkbox" name="ao"%s(oa['o'])
578
+ @ onchange="updateCapabilityString()" />
535579
@ Check-Out%s(B('o'))</label><br />
536
- @ <label><input type="checkbox" name="ah"%s(oa['h']) />
580
+ @ <label><input type="checkbox" name="ah"%s(oa['h'])
581
+ @ onchange="updateCapabilityString()" />
537582
@ Hyperlinks%s(B('h'))</label><br />
538
- @ <label><input type="checkbox" name="ab"%s(oa['b']) />
583
+ @ <label><input type="checkbox" name="ab"%s(oa['b'])
584
+ @ onchange="updateCapabilityString()" />
539585
@ Attachments%s(B('b'))</label><br />
540586
@ </td><td><td width="40"></td><td valign="top">
541
- @ <label><input type="checkbox" name="au"%s(oa['u']) />
587
+ @ <label><input type="checkbox" name="au"%s(oa['u'])
588
+ @ onchange="updateCapabilityString()" />
542589
@ Reader%s(B('u'))</label><br />
543
- @ <label><input type="checkbox" name="av"%s(oa['v']) />
590
+ @ <label><input type="checkbox" name="av"%s(oa['v'])
591
+ @ onchange="updateCapabilityString()" />
544592
@ Developer%s(B('v'))</label><br />
545
- @ <label><input type="checkbox" name="ag"%s(oa['g']) />
593
+ @ <label><input type="checkbox" name="ag"%s(oa['g'])
594
+ @ onchange="updateCapabilityString()" />
546595
@ Clone%s(B('g'))</label><br />
547
- @ <label><input type="checkbox" name="aj"%s(oa['j']) />
596
+ @ <label><input type="checkbox" name="aj"%s(oa['j'])
597
+ @ onchange="updateCapabilityString()" />
548598
@ Read Wiki%s(B('j'))</label><br />
549
- @ <label><input type="checkbox" name="af"%s(oa['f']) />
599
+ @ <label><input type="checkbox" name="af"%s(oa['f'])
600
+ @ onchange="updateCapabilityString()" />
550601
@ New Wiki%s(B('f'))</label><br />
551
- @ <label><input type="checkbox" name="am"%s(oa['m']) />
602
+ @ <label><input type="checkbox" name="am"%s(oa['m'])
603
+ @ onchange="updateCapabilityString()" />
552604
@ Append Wiki%s(B('m'))</label><br />
553
- @ <label><input type="checkbox" name="ak"%s(oa['k']) />
605
+ @ <label><input type="checkbox" name="ak"%s(oa['k'])
606
+ @ onchange="updateCapabilityString()" />
554607
@ Write Wiki%s(B('k'))</label><br />
555
- @ <label><input type="checkbox" name="al"%s(oa['l']) />
608
+ @ <label><input type="checkbox" name="al"%s(oa['l'])
609
+ @ onchange="updateCapabilityString()" />
556610
@ Moderate Wiki%s(B('l'))</label><br />
557611
@ </td><td><td width="40"></td><td valign="top">
558
- @ <label><input type="checkbox" name="ar"%s(oa['r']) />
612
+ @ <label><input type="checkbox" name="ar"%s(oa['r'])
613
+ @ onchange="updateCapabilityString()" />
559614
@ Read Ticket%s(B('r'))</label><br />
560
- @ <label><input type="checkbox" name="an"%s(oa['n']) />
615
+ @ <label><input type="checkbox" name="an"%s(oa['n'])
616
+ @ onchange="updateCapabilityString()" />
561617
@ New Tickets%s(B('n'))</label><br />
562
- @ <label><input type="checkbox" name="ac"%s(oa['c']) />
618
+ @ <label><input type="checkbox" name="ac"%s(oa['c'])
619
+ @ onchange="updateCapabilityString()" />
563620
@ Append To Ticket%s(B('c'))</label><br />
564
- @ <label><input type="checkbox" name="aw"%s(oa['w']) />
621
+ @ <label><input type="checkbox" name="aw"%s(oa['w'])
622
+ @ onchange="updateCapabilityString()" />
565623
@ Write Tickets%s(B('w'))</label><br />
566
- @ <label><input type="checkbox" name="aq"%s(oa['q']) />
624
+ @ <label><input type="checkbox" name="aq"%s(oa['q'])
625
+ @ onchange="updateCapabilityString()" />
567626
@ Moderate Tickets%s(B('q'))</label><br />
568
- @ <label><input type="checkbox" name="at"%s(oa['t']) />
627
+ @ <label><input type="checkbox" name="at"%s(oa['t'])
628
+ @ onchange="updateCapabilityString()" />
569629
@ Ticket Report%s(B('t'))</label><br />
570
- @ <label><input type="checkbox" name="ax"%s(oa['x']) />
630
+ @ <label><input type="checkbox" name="ax"%s(oa['x'])
631
+ @ onchange="updateCapabilityString()" />
571632
@ Private%s(B('x'))</label><br />
572
- @ <label><input type="checkbox" name="az"%s(oa['z']) />
633
+ @ <label><input type="checkbox" name="az"%s(oa['z'])
634
+ @ onchange="updateCapabilityString()" />
573635
@ Download Zip%s(B('z'))</label>
574
- @ </td></tr></table>
636
+ @ </td></tr>
637
+ @ </table>
638
+ @ </td>
639
+ @ </tr>
640
+ @ <tr>
641
+ @ <td class="usetupEditLabel">Selected Cap.:</td>
642
+ @ <td>
643
+ @ <span id="usetupEditCapability">(missing JS?)</span>
575644
@ </td>
576645
@ </tr>
577646
if( !login_is_special(zLogin) ){
578647
@ <tr>
579648
@ <td align="right">Password:</td>
@@ -604,10 +673,11 @@
604673
@ </tr>
605674
}
606675
@ </table>
607676
@ </div></form>
608677
@ </div>
678
+ @ <script type='text/javascript'>updateCapabilityString();</script>
609679
@ <h2>Privileges And Capabilities:</h2>
610680
@ <ul>
611681
if( higherUser ){
612682
@ <li><p class="missingPriv">
613683
@ User %h(zLogin) has Setup privileges and you only have Admin privileges
@@ -1087,11 +1157,11 @@
10871157
login_check_credentials();
10881158
if( !g.perm.Setup ){
10891159
login_needed();
10901160
}
10911161
file_canonical_name(g.zRepositoryName, &fullName, 0);
1092
- zSelfRepo = mprintf(blob_str(&fullName));
1162
+ zSelfRepo = fossil_strdup(blob_str(&fullName));
10931163
blob_reset(&fullName);
10941164
if( P("join")!=0 ){
10951165
login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
10961166
}else if( P("leave") ){
10971167
login_group_leave(&zErrMsg);
@@ -1261,11 +1331,15 @@
12611331
login_needed();
12621332
}
12631333
12641334
(void) aCmdHelp; /* NOTE: Silence compiler warning. */
12651335
style_header("Settings");
1266
- db_open_local(0);
1336
+ if(!g.repositoryOpen){
1337
+ /* Provide read-only access to versioned settings,
1338
+ but only if no repo file was explicitly provided. */
1339
+ db_open_local(0);
1340
+ }
12671341
db_begin_transaction();
12681342
@ <p>This page provides a simple interface to the "fossil setting" command.
12691343
@ See the "fossil help setting" output below for further information on
12701344
@ the meaning of each setting.</p><hr />
12711345
@ <form action="%s(g.zTop)/setup_settings" method="post"><div>
12721346
--- src/setup.c
+++ src/setup.c
@@ -307,11 +307,11 @@
307 int uid, i;
308 int higherUser = 0; /* True if user being edited is SETUP and the */
309 /* user doing the editing is ADMIN. Disallow editing */
310 char *inherit[128];
311 int a[128];
312 char *oa[128];
313
314 /* Must have ADMIN privileges to access this page
315 */
316 login_check_credentials();
317 if( !g.perm.Admin ){ login_needed(); return; }
@@ -375,11 +375,11 @@
375 return;
376 }
377 login_verify_csrf_secret();
378 db_multi_exec(
379 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
380 "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s',now())",
381 uid, P("login"), P("info"), zPw, zCap
382 );
383 if( atoi(PD("all","0"))>0 ){
384 Blob sql;
385 char *zErr = 0;
@@ -441,47 +441,47 @@
441 if( fossil_strcmp(zLogin, "developer") ){
442 char *z1, *z2;
443 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
444 while( z1 && *z1 ){
445 inherit[0x7f & *(z1++)] =
446 "<span class=\"ueditInheritDeveloper\"><sub>D</sub></span>";
447 }
448 free(z2);
449 }
450 if( fossil_strcmp(zLogin, "reader") ){
451 char *z1, *z2;
452 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
453 while( z1 && *z1 ){
454 inherit[0x7f & *(z1++)] =
455 "<span class=\"ueditInheritReader\"><sub>R</sub></span>";
456 }
457 free(z2);
458 }
459 if( fossil_strcmp(zLogin, "anonymous") ){
460 char *z1, *z2;
461 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
462 while( z1 && *z1 ){
463 inherit[0x7f & *(z1++)] =
464 "<span class=\"ueditInheritAnonymous\"><sub>A</sub></span>";
465 }
466 free(z2);
467 }
468 if( fossil_strcmp(zLogin, "nobody") ){
469 char *z1, *z2;
470 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
471 while( z1 && *z1 ){
472 inherit[0x7f & *(z1++)] =
473 "<span class=\"ueditInheritNobody\"><sub>N</sub></span>";
474 }
475 free(z2);
476 }
477
478 /* Begin generating the page
479 */
480 style_submenu_element("Cancel", "Cancel", "setup_ulist");
481 if( uid ){
482 style_header(mprintf("Edit User %h", zLogin));
483 }else{
484 style_header("Add A New User");
485 }
486 @ <div class="ueditCapBox">
487 @ <form action="%s(g.zPath)" method="post"><div>
@@ -489,10 +489,47 @@
489 if( login_is_special(zLogin) ){
490 @ <input type="hidden" name="login" value="%s(zLogin)">
491 @ <input type="hidden" name="info" value="">
492 @ <input type="hidden" name="pw" value="*">
493 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494 @ <table>
495 @ <tr>
496 @ <td class="usetupEditLabel">User ID:</td>
497 if( uid ){
498 @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td>
@@ -516,64 +553,96 @@
516 @ <td class="usetupEditLabel">Capabilities:</td>
517 @ <td>
518 #define B(x) inherit[x]
519 @ <table border=0><tr><td valign="top">
520 if( g.perm.Setup ){
521 @ <label><input type="checkbox" name="as"%s(oa['s']) />
 
522 @ Setup%s(B('s'))</label><br />
523 }
524 @ <label><input type="checkbox" name="aa"%s(oa['a']) />
 
525 @ Admin%s(B('a'))</label><br />
526 @ <label><input type="checkbox" name="ad"%s(oa['d']) />
 
527 @ Delete%s(B('d'))</label><br />
528 @ <label><input type="checkbox" name="ae"%s(oa['e']) />
 
529 @ Email%s(B('e'))</label><br />
530 @ <label><input type="checkbox" name="ap"%s(oa['p']) />
 
531 @ Password%s(B('p'))</label><br />
532 @ <label><input type="checkbox" name="ai"%s(oa['i']) />
 
533 @ Check-In%s(B('i'))</label><br />
534 @ <label><input type="checkbox" name="ao"%s(oa['o']) />
 
535 @ Check-Out%s(B('o'))</label><br />
536 @ <label><input type="checkbox" name="ah"%s(oa['h']) />
 
537 @ Hyperlinks%s(B('h'))</label><br />
538 @ <label><input type="checkbox" name="ab"%s(oa['b']) />
 
539 @ Attachments%s(B('b'))</label><br />
540 @ </td><td><td width="40"></td><td valign="top">
541 @ <label><input type="checkbox" name="au"%s(oa['u']) />
 
542 @ Reader%s(B('u'))</label><br />
543 @ <label><input type="checkbox" name="av"%s(oa['v']) />
 
544 @ Developer%s(B('v'))</label><br />
545 @ <label><input type="checkbox" name="ag"%s(oa['g']) />
 
546 @ Clone%s(B('g'))</label><br />
547 @ <label><input type="checkbox" name="aj"%s(oa['j']) />
 
548 @ Read Wiki%s(B('j'))</label><br />
549 @ <label><input type="checkbox" name="af"%s(oa['f']) />
 
550 @ New Wiki%s(B('f'))</label><br />
551 @ <label><input type="checkbox" name="am"%s(oa['m']) />
 
552 @ Append Wiki%s(B('m'))</label><br />
553 @ <label><input type="checkbox" name="ak"%s(oa['k']) />
 
554 @ Write Wiki%s(B('k'))</label><br />
555 @ <label><input type="checkbox" name="al"%s(oa['l']) />
 
556 @ Moderate Wiki%s(B('l'))</label><br />
557 @ </td><td><td width="40"></td><td valign="top">
558 @ <label><input type="checkbox" name="ar"%s(oa['r']) />
 
559 @ Read Ticket%s(B('r'))</label><br />
560 @ <label><input type="checkbox" name="an"%s(oa['n']) />
 
561 @ New Tickets%s(B('n'))</label><br />
562 @ <label><input type="checkbox" name="ac"%s(oa['c']) />
 
563 @ Append To Ticket%s(B('c'))</label><br />
564 @ <label><input type="checkbox" name="aw"%s(oa['w']) />
 
565 @ Write Tickets%s(B('w'))</label><br />
566 @ <label><input type="checkbox" name="aq"%s(oa['q']) />
 
567 @ Moderate Tickets%s(B('q'))</label><br />
568 @ <label><input type="checkbox" name="at"%s(oa['t']) />
 
569 @ Ticket Report%s(B('t'))</label><br />
570 @ <label><input type="checkbox" name="ax"%s(oa['x']) />
 
571 @ Private%s(B('x'))</label><br />
572 @ <label><input type="checkbox" name="az"%s(oa['z']) />
 
573 @ Download Zip%s(B('z'))</label>
574 @ </td></tr></table>
 
 
 
 
 
 
 
575 @ </td>
576 @ </tr>
577 if( !login_is_special(zLogin) ){
578 @ <tr>
579 @ <td align="right">Password:</td>
@@ -604,10 +673,11 @@
604 @ </tr>
605 }
606 @ </table>
607 @ </div></form>
608 @ </div>
 
609 @ <h2>Privileges And Capabilities:</h2>
610 @ <ul>
611 if( higherUser ){
612 @ <li><p class="missingPriv">
613 @ User %h(zLogin) has Setup privileges and you only have Admin privileges
@@ -1087,11 +1157,11 @@
1087 login_check_credentials();
1088 if( !g.perm.Setup ){
1089 login_needed();
1090 }
1091 file_canonical_name(g.zRepositoryName, &fullName, 0);
1092 zSelfRepo = mprintf(blob_str(&fullName));
1093 blob_reset(&fullName);
1094 if( P("join")!=0 ){
1095 login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
1096 }else if( P("leave") ){
1097 login_group_leave(&zErrMsg);
@@ -1261,11 +1331,15 @@
1261 login_needed();
1262 }
1263
1264 (void) aCmdHelp; /* NOTE: Silence compiler warning. */
1265 style_header("Settings");
1266 db_open_local(0);
 
 
 
 
1267 db_begin_transaction();
1268 @ <p>This page provides a simple interface to the "fossil setting" command.
1269 @ See the "fossil help setting" output below for further information on
1270 @ the meaning of each setting.</p><hr />
1271 @ <form action="%s(g.zTop)/setup_settings" method="post"><div>
1272
--- src/setup.c
+++ src/setup.c
@@ -307,11 +307,11 @@
307 int uid, i;
308 int higherUser = 0; /* True if user being edited is SETUP and the */
309 /* user doing the editing is ADMIN. Disallow editing */
310 char *inherit[128];
311 int a[128];
312 const char *oa[128];
313
314 /* Must have ADMIN privileges to access this page
315 */
316 login_check_credentials();
317 if( !g.perm.Admin ){ login_needed(); return; }
@@ -375,11 +375,11 @@
375 return;
376 }
377 login_verify_csrf_secret();
378 db_multi_exec(
379 "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
380 "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
381 uid, P("login"), P("info"), zPw, zCap
382 );
383 if( atoi(PD("all","0"))>0 ){
384 Blob sql;
385 char *zErr = 0;
@@ -441,47 +441,47 @@
441 if( fossil_strcmp(zLogin, "developer") ){
442 char *z1, *z2;
443 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
444 while( z1 && *z1 ){
445 inherit[0x7f & *(z1++)] =
446 "<span class=\"ueditInheritDeveloper\"><sub>[D]</sub></span>";
447 }
448 free(z2);
449 }
450 if( fossil_strcmp(zLogin, "reader") ){
451 char *z1, *z2;
452 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
453 while( z1 && *z1 ){
454 inherit[0x7f & *(z1++)] =
455 "<span class=\"ueditInheritReader\"><sub>[R]</sub></span>";
456 }
457 free(z2);
458 }
459 if( fossil_strcmp(zLogin, "anonymous") ){
460 char *z1, *z2;
461 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
462 while( z1 && *z1 ){
463 inherit[0x7f & *(z1++)] =
464 "<span class=\"ueditInheritAnonymous\"><sub>[A]</sub></span>";
465 }
466 free(z2);
467 }
468 if( fossil_strcmp(zLogin, "nobody") ){
469 char *z1, *z2;
470 z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
471 while( z1 && *z1 ){
472 inherit[0x7f & *(z1++)] =
473 "<span class=\"ueditInheritNobody\"><sub>[N]</sub></span>";
474 }
475 free(z2);
476 }
477
478 /* Begin generating the page
479 */
480 style_submenu_element("Cancel", "Cancel", "setup_ulist");
481 if( uid ){
482 style_header("Edit User %h", zLogin);
483 }else{
484 style_header("Add A New User");
485 }
486 @ <div class="ueditCapBox">
487 @ <form action="%s(g.zPath)" method="post"><div>
@@ -489,10 +489,47 @@
489 if( login_is_special(zLogin) ){
490 @ <input type="hidden" name="login" value="%s(zLogin)">
491 @ <input type="hidden" name="info" value="">
492 @ <input type="hidden" name="pw" value="*">
493 }
494 @ <script type='text/javascript'>
495 @ function updateCapabilityString(){
496 @ /*
497 @ ** This function updates the "#usetupEditCapability" span content
498 @ ** with the capabilities selected by the interactive user, based
499 @ ** upon the state of the capability checkboxes.
500 @ */
501 @ try {
502 @ var inputs = document.getElementsByTagName('input');
503 @ if( inputs && inputs.length ){
504 @ var output = document.getElementById('usetupEditCapability');
505 @ if( output ){
506 @ var permsIds = [], x = 0;
507 @ for(var i = 0; i < inputs.length; i++){
508 @ var e = inputs[i];
509 @ if( !e.name || !e.type ) continue;
510 @ if( e.type.toLowerCase()!=='checkbox' ) continue;
511 @ if( e.name.length===2 && e.name[0]==='a' ){
512 @ // looks like a capability checkbox
513 @ if( e.checked ){
514 @ // grab the second character of the element
515 @ // name, which is the textual flag for this
516 @ // capability, and then add it to the result
517 @ // array.
518 @ permsIds[x++] = e.name[1];
519 @ }
520 @ }
521 @ }
522 @ permsIds.sort();
523 @ output.innerHTML = permsIds.join('');
524 @ }
525 @ }
526 @ } catch (e) {
527 @ /* ignore errors */
528 @ }
529 @ }
530 @ </script>
531 @ <table>
532 @ <tr>
533 @ <td class="usetupEditLabel">User ID:</td>
534 if( uid ){
535 @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td>
@@ -516,64 +553,96 @@
553 @ <td class="usetupEditLabel">Capabilities:</td>
554 @ <td>
555 #define B(x) inherit[x]
556 @ <table border=0><tr><td valign="top">
557 if( g.perm.Setup ){
558 @ <label><input type="checkbox" name="as"%s(oa['s'])
559 @ onchange="updateCapabilityString()"/>
560 @ Setup%s(B('s'))</label><br />
561 }
562 @ <label><input type="checkbox" name="aa"%s(oa['a'])
563 @ onchange="updateCapabilityString()" />
564 @ Admin%s(B('a'))</label><br />
565 @ <label><input type="checkbox" name="ad"%s(oa['d'])
566 @ onchange="updateCapabilityString()" />
567 @ Delete%s(B('d'))</label><br />
568 @ <label><input type="checkbox" name="ae"%s(oa['e'])
569 @ onchange="updateCapabilityString()" />
570 @ Email%s(B('e'))</label><br />
571 @ <label><input type="checkbox" name="ap"%s(oa['p'])
572 @ onchange="updateCapabilityString()" />
573 @ Password%s(B('p'))</label><br />
574 @ <label><input type="checkbox" name="ai"%s(oa['i'])
575 @ onchange="updateCapabilityString()" />
576 @ Check-In%s(B('i'))</label><br />
577 @ <label><input type="checkbox" name="ao"%s(oa['o'])
578 @ onchange="updateCapabilityString()" />
579 @ Check-Out%s(B('o'))</label><br />
580 @ <label><input type="checkbox" name="ah"%s(oa['h'])
581 @ onchange="updateCapabilityString()" />
582 @ Hyperlinks%s(B('h'))</label><br />
583 @ <label><input type="checkbox" name="ab"%s(oa['b'])
584 @ onchange="updateCapabilityString()" />
585 @ Attachments%s(B('b'))</label><br />
586 @ </td><td><td width="40"></td><td valign="top">
587 @ <label><input type="checkbox" name="au"%s(oa['u'])
588 @ onchange="updateCapabilityString()" />
589 @ Reader%s(B('u'))</label><br />
590 @ <label><input type="checkbox" name="av"%s(oa['v'])
591 @ onchange="updateCapabilityString()" />
592 @ Developer%s(B('v'))</label><br />
593 @ <label><input type="checkbox" name="ag"%s(oa['g'])
594 @ onchange="updateCapabilityString()" />
595 @ Clone%s(B('g'))</label><br />
596 @ <label><input type="checkbox" name="aj"%s(oa['j'])
597 @ onchange="updateCapabilityString()" />
598 @ Read Wiki%s(B('j'))</label><br />
599 @ <label><input type="checkbox" name="af"%s(oa['f'])
600 @ onchange="updateCapabilityString()" />
601 @ New Wiki%s(B('f'))</label><br />
602 @ <label><input type="checkbox" name="am"%s(oa['m'])
603 @ onchange="updateCapabilityString()" />
604 @ Append Wiki%s(B('m'))</label><br />
605 @ <label><input type="checkbox" name="ak"%s(oa['k'])
606 @ onchange="updateCapabilityString()" />
607 @ Write Wiki%s(B('k'))</label><br />
608 @ <label><input type="checkbox" name="al"%s(oa['l'])
609 @ onchange="updateCapabilityString()" />
610 @ Moderate Wiki%s(B('l'))</label><br />
611 @ </td><td><td width="40"></td><td valign="top">
612 @ <label><input type="checkbox" name="ar"%s(oa['r'])
613 @ onchange="updateCapabilityString()" />
614 @ Read Ticket%s(B('r'))</label><br />
615 @ <label><input type="checkbox" name="an"%s(oa['n'])
616 @ onchange="updateCapabilityString()" />
617 @ New Tickets%s(B('n'))</label><br />
618 @ <label><input type="checkbox" name="ac"%s(oa['c'])
619 @ onchange="updateCapabilityString()" />
620 @ Append To Ticket%s(B('c'))</label><br />
621 @ <label><input type="checkbox" name="aw"%s(oa['w'])
622 @ onchange="updateCapabilityString()" />
623 @ Write Tickets%s(B('w'))</label><br />
624 @ <label><input type="checkbox" name="aq"%s(oa['q'])
625 @ onchange="updateCapabilityString()" />
626 @ Moderate Tickets%s(B('q'))</label><br />
627 @ <label><input type="checkbox" name="at"%s(oa['t'])
628 @ onchange="updateCapabilityString()" />
629 @ Ticket Report%s(B('t'))</label><br />
630 @ <label><input type="checkbox" name="ax"%s(oa['x'])
631 @ onchange="updateCapabilityString()" />
632 @ Private%s(B('x'))</label><br />
633 @ <label><input type="checkbox" name="az"%s(oa['z'])
634 @ onchange="updateCapabilityString()" />
635 @ Download Zip%s(B('z'))</label>
636 @ </td></tr>
637 @ </table>
638 @ </td>
639 @ </tr>
640 @ <tr>
641 @ <td class="usetupEditLabel">Selected Cap.:</td>
642 @ <td>
643 @ <span id="usetupEditCapability">(missing JS?)</span>
644 @ </td>
645 @ </tr>
646 if( !login_is_special(zLogin) ){
647 @ <tr>
648 @ <td align="right">Password:</td>
@@ -604,10 +673,11 @@
673 @ </tr>
674 }
675 @ </table>
676 @ </div></form>
677 @ </div>
678 @ <script type='text/javascript'>updateCapabilityString();</script>
679 @ <h2>Privileges And Capabilities:</h2>
680 @ <ul>
681 if( higherUser ){
682 @ <li><p class="missingPriv">
683 @ User %h(zLogin) has Setup privileges and you only have Admin privileges
@@ -1087,11 +1157,11 @@
1157 login_check_credentials();
1158 if( !g.perm.Setup ){
1159 login_needed();
1160 }
1161 file_canonical_name(g.zRepositoryName, &fullName, 0);
1162 zSelfRepo = fossil_strdup(blob_str(&fullName));
1163 blob_reset(&fullName);
1164 if( P("join")!=0 ){
1165 login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
1166 }else if( P("leave") ){
1167 login_group_leave(&zErrMsg);
@@ -1261,11 +1331,15 @@
1331 login_needed();
1332 }
1333
1334 (void) aCmdHelp; /* NOTE: Silence compiler warning. */
1335 style_header("Settings");
1336 if(!g.repositoryOpen){
1337 /* Provide read-only access to versioned settings,
1338 but only if no repo file was explicitly provided. */
1339 db_open_local(0);
1340 }
1341 db_begin_transaction();
1342 @ <p>This page provides a simple interface to the "fossil setting" command.
1343 @ See the "fossil help setting" output below for further information on
1344 @ the meaning of each setting.</p><hr />
1345 @ <form action="%s(g.zTop)/setup_settings" method="post"><div>
1346
+14 -2
--- src/shell.c
+++ src/shell.c
@@ -880,11 +880,11 @@
880880
for(i=0; i<nArg; i++){
881881
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
882882
}
883883
fprintf(p->out,"%s",p->newline);
884884
}
885
- if( azArg>0 ){
885
+ if( nArg>0 ){
886886
for(i=0; i<nArg; i++){
887887
output_csv(p, azArg[i], i<nArg-1);
888888
}
889889
fprintf(p->out,"%s",p->newline);
890890
}
@@ -1351,18 +1351,20 @@
13511351
}
13521352
sqlite3_finalize(pExplain);
13531353
sqlite3_free(zEQP);
13541354
}
13551355
1356
+#if USE_SYSTEM_SQLITE+0==1
13561357
/* Output TESTCTRL_EXPLAIN text of requested */
1357
- if( pArg && pArg->mode==MODE_Explain ){
1358
+ if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){
13581359
const char *zExplain = 0;
13591360
sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
13601361
if( zExplain && zExplain[0] ){
13611362
fprintf(pArg->out, "%s", zExplain);
13621363
}
13631364
}
1365
+#endif
13641366
13651367
/* If the shell is currently in ".explain" mode, gather the extra
13661368
** data required to add indents to the output.*/
13671369
if( pArg && pArg->mode==MODE_Explain ){
13681370
explain_data_prepare(pArg, pStmt);
@@ -3098,10 +3100,19 @@
30983100
rc = 1;
30993101
}else{
31003102
rc = 0;
31013103
}
31023104
}else
3105
+
3106
+
3107
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3108
+ if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3109
+ extern int sqlite3SelectTrace;
3110
+ sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
3111
+ }else
3112
+#endif
3113
+
31033114
31043115
#ifdef SQLITE_DEBUG
31053116
/* Undocumented commands for internal testing. Subject to change
31063117
** without notice. */
31073118
if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
@@ -3723,10 +3734,11 @@
37233734
}
37243735
}
37253736
if( nSql ){
37263737
if( !_all_whitespace(zSql) ){
37273738
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
3739
+ errCnt++;
37283740
}
37293741
free(zSql);
37303742
}
37313743
free(zLine);
37323744
return errCnt>0;
37333745
--- src/shell.c
+++ src/shell.c
@@ -880,11 +880,11 @@
880 for(i=0; i<nArg; i++){
881 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
882 }
883 fprintf(p->out,"%s",p->newline);
884 }
885 if( azArg>0 ){
886 for(i=0; i<nArg; i++){
887 output_csv(p, azArg[i], i<nArg-1);
888 }
889 fprintf(p->out,"%s",p->newline);
890 }
@@ -1351,18 +1351,20 @@
1351 }
1352 sqlite3_finalize(pExplain);
1353 sqlite3_free(zEQP);
1354 }
1355
 
1356 /* Output TESTCTRL_EXPLAIN text of requested */
1357 if( pArg && pArg->mode==MODE_Explain ){
1358 const char *zExplain = 0;
1359 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1360 if( zExplain && zExplain[0] ){
1361 fprintf(pArg->out, "%s", zExplain);
1362 }
1363 }
 
1364
1365 /* If the shell is currently in ".explain" mode, gather the extra
1366 ** data required to add indents to the output.*/
1367 if( pArg && pArg->mode==MODE_Explain ){
1368 explain_data_prepare(pArg, pStmt);
@@ -3098,10 +3100,19 @@
3098 rc = 1;
3099 }else{
3100 rc = 0;
3101 }
3102 }else
 
 
 
 
 
 
 
 
 
3103
3104 #ifdef SQLITE_DEBUG
3105 /* Undocumented commands for internal testing. Subject to change
3106 ** without notice. */
3107 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
@@ -3723,10 +3734,11 @@
3723 }
3724 }
3725 if( nSql ){
3726 if( !_all_whitespace(zSql) ){
3727 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
 
3728 }
3729 free(zSql);
3730 }
3731 free(zLine);
3732 return errCnt>0;
3733
--- src/shell.c
+++ src/shell.c
@@ -880,11 +880,11 @@
880 for(i=0; i<nArg; i++){
881 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
882 }
883 fprintf(p->out,"%s",p->newline);
884 }
885 if( nArg>0 ){
886 for(i=0; i<nArg; i++){
887 output_csv(p, azArg[i], i<nArg-1);
888 }
889 fprintf(p->out,"%s",p->newline);
890 }
@@ -1351,18 +1351,20 @@
1351 }
1352 sqlite3_finalize(pExplain);
1353 sqlite3_free(zEQP);
1354 }
1355
1356 #if USE_SYSTEM_SQLITE+0==1
1357 /* Output TESTCTRL_EXPLAIN text of requested */
1358 if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){
1359 const char *zExplain = 0;
1360 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1361 if( zExplain && zExplain[0] ){
1362 fprintf(pArg->out, "%s", zExplain);
1363 }
1364 }
1365 #endif
1366
1367 /* If the shell is currently in ".explain" mode, gather the extra
1368 ** data required to add indents to the output.*/
1369 if( pArg && pArg->mode==MODE_Explain ){
1370 explain_data_prepare(pArg, pStmt);
@@ -3098,10 +3100,19 @@
3100 rc = 1;
3101 }else{
3102 rc = 0;
3103 }
3104 }else
3105
3106
3107 #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3108 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3109 extern int sqlite3SelectTrace;
3110 sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
3111 }else
3112 #endif
3113
3114
3115 #ifdef SQLITE_DEBUG
3116 /* Undocumented commands for internal testing. Subject to change
3117 ** without notice. */
3118 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
@@ -3723,10 +3734,11 @@
3734 }
3735 }
3736 if( nSql ){
3737 if( !_all_whitespace(zSql) ){
3738 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
3739 errCnt++;
3740 }
3741 free(zSql);
3742 }
3743 free(zLine);
3744 return errCnt>0;
3745
+9 -9
--- src/shun.c
+++ src/shun.c
@@ -43,12 +43,11 @@
4343
int cnt = 0;
4444
const char *zUuid = P("uuid");
4545
const char *zShun = P("shun");
4646
const char *zAccept = P("accept");
4747
const char *zRcvid = P("rcvid");
48
- int nRcvid;
49
- int nUuid;
48
+ int nRcvid = 0;
5049
int numRows = 3;
5150
char *zCanonical = 0;
5251
5352
login_check_credentials();
5453
if( !g.perm.Admin ){
@@ -79,11 +78,11 @@
7978
i++;
8079
}
8180
zCanonical[j+1] = zCanonical[j] = 0;
8281
p = zCanonical;
8382
while( *p ){
84
- nUuid = strlen(p);
83
+ int nUuid = strlen(p);
8584
if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
8685
@ <p class="generalError">Error: Bad artifact IDs.</p>
8786
fossil_free(zCanonical);
8887
zCanonical = 0;
8988
break;
@@ -98,12 +97,12 @@
9897
if( zUuid && P("sub") ){
9998
const char *p = zUuid;
10099
int allExist = 1;
101100
login_verify_csrf_secret();
102101
while( *p ){
103
- db_multi_exec("DELETE FROM shun WHERE uuid='%s'", p);
104
- if( !db_exists("SELECT 1 FROM blob WHERE uuid='%s'", p) ){
102
+ db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
103
+ if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
105104
allExist = 0;
106105
}
107106
p += UUID_SIZE+1;
108107
}
109108
if( allExist ){
@@ -128,11 +127,11 @@
128127
int rid, tagid;
129128
login_verify_csrf_secret();
130129
while( *p ){
131130
db_multi_exec(
132131
"INSERT OR IGNORE INTO shun(uuid,mtime)"
133
- " VALUES('%s', now())", p);
132
+ " VALUES(%Q, now())", p);
134133
db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
135134
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
136135
if( rid ){
137136
db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
138137
}
@@ -152,11 +151,12 @@
152151
@ They will be removed from the repository the next time the repository
153152
@ is rebuilt using the <b>fossil rebuild</b> command-line</p>
154153
}
155154
if( zRcvid ){
156155
nRcvid = atoi(zRcvid);
157
- numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", nRcvid);
156
+ numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d",
157
+ nRcvid);
158158
}
159159
@ <p>A shunned artifact will not be pushed nor accepted in a pull and the
160160
@ artifact content will be purged from the repository the next time the
161161
@ repository is rebuilt. A list of shunned artifacts can be seen at the
162162
@ bottom of this page.</p>
@@ -183,11 +183,11 @@
183183
login_insert_csrf_secret();
184184
@ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
185185
if( zShun ){
186186
if( strlen(zShun) ){
187187
@ %h(zShun)
188
- }else if( zRcvid ){
188
+ }else if( nRcvid ){
189189
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
190190
while( db_step(&q)==SQLITE_ROW ){
191191
@ %s(db_column_text(&q, 0))
192192
}
193193
db_finalize(&q);
@@ -210,11 +210,11 @@
210210
login_insert_csrf_secret();
211211
@ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
212212
if( zAccept ){
213213
if( strlen(zAccept) ){
214214
@ %h(zAccept)
215
- }else if( zRcvid ){
215
+ }else if( nRcvid ){
216216
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
217217
while( db_step(&q)==SQLITE_ROW ){
218218
@ %s(db_column_text(&q, 0))
219219
}
220220
db_finalize(&q);
221221
--- src/shun.c
+++ src/shun.c
@@ -43,12 +43,11 @@
43 int cnt = 0;
44 const char *zUuid = P("uuid");
45 const char *zShun = P("shun");
46 const char *zAccept = P("accept");
47 const char *zRcvid = P("rcvid");
48 int nRcvid;
49 int nUuid;
50 int numRows = 3;
51 char *zCanonical = 0;
52
53 login_check_credentials();
54 if( !g.perm.Admin ){
@@ -79,11 +78,11 @@
79 i++;
80 }
81 zCanonical[j+1] = zCanonical[j] = 0;
82 p = zCanonical;
83 while( *p ){
84 nUuid = strlen(p);
85 if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
86 @ <p class="generalError">Error: Bad artifact IDs.</p>
87 fossil_free(zCanonical);
88 zCanonical = 0;
89 break;
@@ -98,12 +97,12 @@
98 if( zUuid && P("sub") ){
99 const char *p = zUuid;
100 int allExist = 1;
101 login_verify_csrf_secret();
102 while( *p ){
103 db_multi_exec("DELETE FROM shun WHERE uuid='%s'", p);
104 if( !db_exists("SELECT 1 FROM blob WHERE uuid='%s'", p) ){
105 allExist = 0;
106 }
107 p += UUID_SIZE+1;
108 }
109 if( allExist ){
@@ -128,11 +127,11 @@
128 int rid, tagid;
129 login_verify_csrf_secret();
130 while( *p ){
131 db_multi_exec(
132 "INSERT OR IGNORE INTO shun(uuid,mtime)"
133 " VALUES('%s', now())", p);
134 db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
135 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
136 if( rid ){
137 db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
138 }
@@ -152,11 +151,12 @@
152 @ They will be removed from the repository the next time the repository
153 @ is rebuilt using the <b>fossil rebuild</b> command-line</p>
154 }
155 if( zRcvid ){
156 nRcvid = atoi(zRcvid);
157 numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d", nRcvid);
 
158 }
159 @ <p>A shunned artifact will not be pushed nor accepted in a pull and the
160 @ artifact content will be purged from the repository the next time the
161 @ repository is rebuilt. A list of shunned artifacts can be seen at the
162 @ bottom of this page.</p>
@@ -183,11 +183,11 @@
183 login_insert_csrf_secret();
184 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
185 if( zShun ){
186 if( strlen(zShun) ){
187 @ %h(zShun)
188 }else if( zRcvid ){
189 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
190 while( db_step(&q)==SQLITE_ROW ){
191 @ %s(db_column_text(&q, 0))
192 }
193 db_finalize(&q);
@@ -210,11 +210,11 @@
210 login_insert_csrf_secret();
211 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
212 if( zAccept ){
213 if( strlen(zAccept) ){
214 @ %h(zAccept)
215 }else if( zRcvid ){
216 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
217 while( db_step(&q)==SQLITE_ROW ){
218 @ %s(db_column_text(&q, 0))
219 }
220 db_finalize(&q);
221
--- src/shun.c
+++ src/shun.c
@@ -43,12 +43,11 @@
43 int cnt = 0;
44 const char *zUuid = P("uuid");
45 const char *zShun = P("shun");
46 const char *zAccept = P("accept");
47 const char *zRcvid = P("rcvid");
48 int nRcvid = 0;
 
49 int numRows = 3;
50 char *zCanonical = 0;
51
52 login_check_credentials();
53 if( !g.perm.Admin ){
@@ -79,11 +78,11 @@
78 i++;
79 }
80 zCanonical[j+1] = zCanonical[j] = 0;
81 p = zCanonical;
82 while( *p ){
83 int nUuid = strlen(p);
84 if( nUuid!=UUID_SIZE || !validate16(p, nUuid) ){
85 @ <p class="generalError">Error: Bad artifact IDs.</p>
86 fossil_free(zCanonical);
87 zCanonical = 0;
88 break;
@@ -98,12 +97,12 @@
97 if( zUuid && P("sub") ){
98 const char *p = zUuid;
99 int allExist = 1;
100 login_verify_csrf_secret();
101 while( *p ){
102 db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
103 if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
104 allExist = 0;
105 }
106 p += UUID_SIZE+1;
107 }
108 if( allExist ){
@@ -128,11 +127,11 @@
127 int rid, tagid;
128 login_verify_csrf_secret();
129 while( *p ){
130 db_multi_exec(
131 "INSERT OR IGNORE INTO shun(uuid,mtime)"
132 " VALUES(%Q, now())", p);
133 db_multi_exec("DELETE FROM attachment WHERE src=%Q", p);
134 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", p);
135 if( rid ){
136 db_multi_exec("DELETE FROM event WHERE objid=%d", rid);
137 }
@@ -152,11 +151,12 @@
151 @ They will be removed from the repository the next time the repository
152 @ is rebuilt using the <b>fossil rebuild</b> command-line</p>
153 }
154 if( zRcvid ){
155 nRcvid = atoi(zRcvid);
156 numRows = db_int(0, "SELECT min(count(), 10) FROM blob WHERE rcvid=%d",
157 nRcvid);
158 }
159 @ <p>A shunned artifact will not be pushed nor accepted in a pull and the
160 @ artifact content will be purged from the repository the next time the
161 @ repository is rebuilt. A list of shunned artifacts can be seen at the
162 @ bottom of this page.</p>
@@ -183,11 +183,11 @@
183 login_insert_csrf_secret();
184 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
185 if( zShun ){
186 if( strlen(zShun) ){
187 @ %h(zShun)
188 }else if( nRcvid ){
189 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
190 while( db_step(&q)==SQLITE_ROW ){
191 @ %s(db_column_text(&q, 0))
192 }
193 db_finalize(&q);
@@ -210,11 +210,11 @@
210 login_insert_csrf_secret();
211 @ <textarea class="fullsize-text" cols="50" rows="%d(numRows)" name="uuid">
212 if( zAccept ){
213 if( strlen(zAccept) ){
214 @ %h(zAccept)
215 }else if( nRcvid ){
216 db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
217 while( db_step(&q)==SQLITE_ROW ){
218 @ %s(db_column_text(&q, 0))
219 }
220 db_finalize(&q);
221
+2 -2
--- src/skins.c
+++ src/skins.c
@@ -1392,18 +1392,18 @@
13921392
seen = 0;
13931393
for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
13941394
if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
13951395
seen = 1;
13961396
zCurrent = aBuiltinSkin[i].zValue;
1397
- db_multi_exec("%s", zCurrent);
1397
+ db_multi_exec("%s", zCurrent/*safe-for-%s*/);
13981398
break;
13991399
}
14001400
}
14011401
if( !seen ){
14021402
zName = skinVarName(z,0);
14031403
zCurrent = db_get(zName, 0);
1404
- db_multi_exec("%s", zCurrent);
1404
+ db_multi_exec("%s", zCurrent/*safe-for-%s*/);
14051405
}
14061406
}
14071407
14081408
style_header("Skins");
14091409
if( zErr ){
14101410
--- src/skins.c
+++ src/skins.c
@@ -1392,18 +1392,18 @@
1392 seen = 0;
1393 for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
1394 if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
1395 seen = 1;
1396 zCurrent = aBuiltinSkin[i].zValue;
1397 db_multi_exec("%s", zCurrent);
1398 break;
1399 }
1400 }
1401 if( !seen ){
1402 zName = skinVarName(z,0);
1403 zCurrent = db_get(zName, 0);
1404 db_multi_exec("%s", zCurrent);
1405 }
1406 }
1407
1408 style_header("Skins");
1409 if( zErr ){
1410
--- src/skins.c
+++ src/skins.c
@@ -1392,18 +1392,18 @@
1392 seen = 0;
1393 for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
1394 if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){
1395 seen = 1;
1396 zCurrent = aBuiltinSkin[i].zValue;
1397 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
1398 break;
1399 }
1400 }
1401 if( !seen ){
1402 zName = skinVarName(z,0);
1403 zCurrent = db_get(zName, 0);
1404 db_multi_exec("%s", zCurrent/*safe-for-%s*/);
1405 }
1406 }
1407
1408 style_header("Skins");
1409 if( zErr ){
1410
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -148,11 +148,15 @@
148148
extern int sqlite3_shell(int, char**);
149149
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
150150
db_close(1);
151151
sqlite3_shutdown();
152152
sqlite3_shell(g.argc-1, g.argv+1);
153
+ sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
153154
g.db = 0;
155
+ g.zMainDbType = 0;
156
+ g.repositoryOpen = 0;
157
+ g.localOpen = 0;
154158
}
155159
156160
/*
157161
** This routine is called by the patched sqlite3 command-line shell in order
158162
** to load the name and database connection for the open Fossil database.
159163
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -148,11 +148,15 @@
148 extern int sqlite3_shell(int, char**);
149 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
150 db_close(1);
151 sqlite3_shutdown();
152 sqlite3_shell(g.argc-1, g.argv+1);
 
153 g.db = 0;
 
 
 
154 }
155
156 /*
157 ** This routine is called by the patched sqlite3 command-line shell in order
158 ** to load the name and database connection for the open Fossil database.
159
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -148,11 +148,15 @@
148 extern int sqlite3_shell(int, char**);
149 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
150 db_close(1);
151 sqlite3_shutdown();
152 sqlite3_shell(g.argc-1, g.argv+1);
153 sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit);
154 g.db = 0;
155 g.zMainDbType = 0;
156 g.repositoryOpen = 0;
157 g.localOpen = 0;
158 }
159
160 /*
161 ** This routine is called by the patched sqlite3 command-line shell in order
162 ** to load the name and database connection for the open Fossil database.
163
+1210 -975
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -231,11 +231,11 @@
231231
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
232232
** [sqlite_version()] and [sqlite_source_id()].
233233
*/
234234
#define SQLITE_VERSION "3.8.7"
235235
#define SQLITE_VERSION_NUMBER 3008007
236
-#define SQLITE_SOURCE_ID "2014-09-20 00:35:05 59e2c9df02d7e988c5ad44c560ead1e5288b12e7"
236
+#define SQLITE_SOURCE_ID "2014-10-17 11:24:17 e4ab094f8afce0817f4074e823fabe59fc29ebb4"
237237
238238
/*
239239
** CAPI3REF: Run-Time Library Version Numbers
240240
** KEYWORDS: sqlite3_version, sqlite3_sourceid
241241
**
@@ -2791,13 +2791,13 @@
27912791
** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
27922792
** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
27932793
** an English language description of the error following a failure of any
27942794
** of the sqlite3_open() routines.
27952795
**
2796
-** ^The default encoding for the database will be UTF-8 if
2797
-** sqlite3_open() or sqlite3_open_v2() is called and
2798
-** UTF-16 in the native byte order if sqlite3_open16() is used.
2796
+** ^The default encoding will be UTF-8 for databases created using
2797
+** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases
2798
+** created using sqlite3_open16() will be UTF-16 in the native byte order.
27992799
**
28002800
** Whether or not an error occurs when it is opened, resources
28012801
** associated with the [database connection] handle should be released by
28022802
** passing it to [sqlite3_close()] when it is no longer required.
28032803
**
@@ -2881,17 +2881,18 @@
28812881
** ^SQLite uses the path component of the URI as the name of the disk file
28822882
** which contains the database. ^If the path begins with a '/' character,
28832883
** then it is interpreted as an absolute path. ^If the path does not begin
28842884
** with a '/' (meaning that the authority section is omitted from the URI)
28852885
** then the path is interpreted as a relative path.
2886
-** ^On windows, the first component of an absolute path
2887
-** is a drive specification (e.g. "C:").
2886
+** ^(On windows, the first component of an absolute path
2887
+** is a drive specification (e.g. "C:").)^
28882888
**
28892889
** [[core URI query parameters]]
28902890
** The query component of a URI may contain parameters that are interpreted
28912891
** either by SQLite itself, or by a [VFS | custom VFS implementation].
2892
-** SQLite interprets the following three query parameters:
2892
+** SQLite and its built-in [VFSes] interpret the
2893
+** following query parameters:
28932894
**
28942895
** <ul>
28952896
** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
28962897
** a VFS object that provides the operating system interface that should
28972898
** be used to access the database file on disk. ^If this option is set to
@@ -2922,15 +2923,13 @@
29222923
** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
29232924
** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
29242925
** a URI filename, its value overrides any behavior requested by setting
29252926
** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
29262927
**
2927
-** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
2928
-** "1") or "false" (or "off" or "no" or "0") to indicate that the
2928
+** <li> <b>psow</b>: ^The psow parameter indicates whether or not the
29292929
** [powersafe overwrite] property does or does not apply to the
2930
-** storage media on which the database file resides. ^The psow query
2931
-** parameter only works for the built-in unix and Windows VFSes.
2930
+** storage media on which the database file resides.
29322931
**
29332932
** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
29342933
** which if set disables file locking in rollback journal modes. This
29352934
** is useful for accessing a database on a filesystem that does not
29362935
** support locking. Caution: Database corruption might result if two
@@ -3521,15 +3520,14 @@
35213520
** terminated. If any NUL characters occur at byte offsets less than
35223521
** the value of the fourth parameter then the resulting string value will
35233522
** contain embedded NULs. The result of expressions involving strings
35243523
** with embedded NULs is undefined.
35253524
**
3526
-** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3527
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3525
+** ^The fifth argument to the BLOB and string binding interfaces
3526
+** is a destructor used to dispose of the BLOB or
35283527
** string after SQLite has finished with it. ^The destructor is called
3529
-** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
3530
-** sqlite3_bind_text(), or sqlite3_bind_text16() fails.
3528
+** to dispose of the BLOB or string even if the call to bind API fails.
35313529
** ^If the fifth argument is
35323530
** the special value [SQLITE_STATIC], then SQLite assumes that the
35333531
** information is in static, unmanaged space and does not need to be freed.
35343532
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
35353533
** SQLite makes its own private copy of the data immediately, before
@@ -3536,11 +3534,11 @@
35363534
** the sqlite3_bind_*() routine returns.
35373535
**
35383536
** ^The sixth argument to sqlite3_bind_text64() must be one of
35393537
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
35403538
** to specify the encoding of the text in the third parameter. If
3541
-** the sixth argument to sqlite3_bind_text64() is not how of the
3539
+** the sixth argument to sqlite3_bind_text64() is not one of the
35423540
** allowed values shown above, or if the text encoding is different
35433541
** from the encoding specified by the sixth parameter, then the behavior
35443542
** is undefined.
35453543
**
35463544
** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
@@ -4572,11 +4570,11 @@
45724570
**
45734571
** ^The sqlite3_result_null() interface sets the return value
45744572
** of the application-defined function to be NULL.
45754573
**
45764574
** ^The sqlite3_result_text(), sqlite3_result_text16(),
4577
-** sqlite3_result_text16le(), and sqlite3_result_text16be()
4575
+** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
45784576
** set the return value of the application-defined function to be
45794577
** a text string which is represented as UTF-8, UTF-16 native byte order,
45804578
** UTF-16 little endian, or UTF-16 big endian, respectively.
45814579
** ^The sqlite3_result_text64() interface sets the return value of an
45824580
** application-defined function to be a text string in an encoding
@@ -6332,11 +6330,11 @@
63326330
#define SQLITE_TESTCTRL_RESERVE 14
63336331
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
63346332
#define SQLITE_TESTCTRL_ISKEYWORD 16
63356333
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
63366334
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
6337
-#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
6335
+#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
63386336
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
63396337
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
63406338
#define SQLITE_TESTCTRL_BYTEORDER 22
63416339
#define SQLITE_TESTCTRL_ISINIT 23
63426340
#define SQLITE_TESTCTRL_SORTER_MMAP 24
@@ -7946,11 +7944,11 @@
79467944
** A macro to hint to the compiler that a function should not be
79477945
** inlined.
79487946
*/
79497947
#if defined(__GNUC__)
79507948
# define SQLITE_NOINLINE __attribute__((noinline))
7951
-#elif defined(_MSC_VER)
7949
+#elif defined(_MSC_VER) && _MSC_VER>=1310
79527950
# define SQLITE_NOINLINE __declspec(noinline)
79537951
#else
79547952
# define SQLITE_NOINLINE
79557953
#endif
79567954
@@ -8519,10 +8517,15 @@
85198517
** Macros to compute minimum and maximum of two numbers.
85208518
*/
85218519
#define MIN(A,B) ((A)<(B)?(A):(B))
85228520
#define MAX(A,B) ((A)>(B)?(A):(B))
85238521
8522
+/*
8523
+** Swap two objects of type TYPE.
8524
+*/
8525
+#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
8526
+
85248527
/*
85258528
** Check to see if this machine uses EBCDIC. (Yes, believe it or
85268529
** not, there are still machines out there that use EBCDIC.)
85278530
*/
85288531
#if 'A' == '\301'
@@ -8756,10 +8759,20 @@
87568759
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
87578760
#elif SQLITE_ENABLE_STAT3_OR_STAT4
87588761
# undef SQLITE_ENABLE_STAT3_OR_STAT4
87598762
#endif
87608763
8764
+/*
8765
+** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
8766
+** the Select query generator tracing logic is turned on.
8767
+*/
8768
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE)
8769
+# define SELECTTRACE_ENABLED 1
8770
+#else
8771
+# define SELECTTRACE_ENABLED 0
8772
+#endif
8773
+
87618774
/*
87628775
** An instance of the following structure is used to store the busy-handler
87638776
** callback for a given sqlite handle.
87648777
**
87658778
** The sqlite.busyHandler member of the sqlite struct contains the busy
@@ -8895,10 +8908,11 @@
88958908
typedef struct SrcList SrcList;
88968909
typedef struct StrAccum StrAccum;
88978910
typedef struct Table Table;
88988911
typedef struct TableLock TableLock;
88998912
typedef struct Token Token;
8913
+typedef struct TreeView TreeView;
89008914
typedef struct Trigger Trigger;
89018915
typedef struct TriggerPrg TriggerPrg;
89028916
typedef struct TriggerStep TriggerStep;
89038917
typedef struct UnpackedRecord UnpackedRecord;
89048918
typedef struct VTable VTable;
@@ -11308,10 +11322,11 @@
1130811322
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
1130911323
int nSample; /* Number of elements in aSample[] */
1131011324
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
1131111325
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
1131211326
IndexSample *aSample; /* Samples of the left-most key */
11327
+ tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this table */
1131311328
#endif
1131411329
};
1131511330
1131611331
/*
1131711332
** Allowed values for Index.idxType
@@ -11738,11 +11753,11 @@
1173811753
#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
1173911754
#define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
1174011755
#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
1174111756
#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
1174211757
#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
11743
-#define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */
11758
+ /* 0x0080 // not currently used */
1174411759
#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
1174511760
#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
1174611761
#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
1174711762
#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
1174811763
#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
@@ -11823,10 +11838,13 @@
1182311838
struct Select {
1182411839
ExprList *pEList; /* The fields of the result */
1182511840
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
1182611841
u16 selFlags; /* Various SF_* values */
1182711842
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
11843
+#if SELECTTRACE_ENABLED
11844
+ char zSelName[12]; /* Symbolic name of this SELECT use for debugging */
11845
+#endif
1182811846
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
1182911847
u64 nSelectRow; /* Estimated number of result rows */
1183011848
SrcList *pSrc; /* The FROM clause */
1183111849
Expr *pWhere; /* The WHERE clause */
1183211850
ExprList *pGroupBy; /* The GROUP BY clause */
@@ -12081,10 +12099,14 @@
1208112099
yDbMask cookieMask; /* Bitmask of schema verified databases */
1208212100
int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
1208312101
int regRowid; /* Register holding rowid of CREATE TABLE entry */
1208412102
int regRoot; /* Register holding root page number for new objects */
1208512103
int nMaxArg; /* Max args passed to user function by sub-program */
12104
+#if SELECTTRACE_ENABLED
12105
+ int nSelect; /* Number of SELECT statements seen */
12106
+ int nSelectIndent; /* How far to indent SELECTTRACE() output */
12107
+#endif
1208612108
#ifndef SQLITE_OMIT_SHARED_CACHE
1208712109
int nTableLock; /* Number of locks in aTableLock */
1208812110
TableLock *aTableLock; /* Required table locks for shared-cache mode */
1208912111
#endif
1209012112
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
@@ -12160,15 +12182,15 @@
1216012182
1216112183
/*
1216212184
** Bitfield flags for P5 value in various opcodes.
1216312185
*/
1216412186
#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */
12187
+#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
1216512188
#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
1216612189
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
1216712190
#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
1216812191
#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
12169
-#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
1217012192
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
1217112193
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
1217212194
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
1217312195
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
1217412196
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
@@ -12428,10 +12450,21 @@
1242812450
Select *pSelect; /* The definition of this CTE */
1242912451
const char *zErr; /* Error message for circular references */
1243012452
} a[1];
1243112453
};
1243212454
12455
+#ifdef SQLITE_DEBUG
12456
+/*
12457
+** An instance of the TreeView object is used for printing the content of
12458
+** data structures on sqlite3DebugPrintf() using a tree-like view.
12459
+*/
12460
+struct TreeView {
12461
+ int iLevel; /* Which level of the tree we are on */
12462
+ u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */
12463
+};
12464
+#endif /* SQLITE_DEBUG */
12465
+
1243312466
/*
1243412467
** Assuming zIn points to the first byte of a UTF-8 character,
1243512468
** advance zIn to point to the first byte of the next UTF-8 character.
1243612469
*/
1243712470
#define SQLITE_SKIP_UTF8(zIn) { \
@@ -12493,10 +12526,11 @@
1249312526
# define sqlite3Isalpha(x) isalpha((unsigned char)(x))
1249412527
# define sqlite3Isdigit(x) isdigit((unsigned char)(x))
1249512528
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
1249612529
# define sqlite3Tolower(x) tolower((unsigned char)(x))
1249712530
#endif
12531
+SQLITE_PRIVATE int sqlite3IsIdChar(u8);
1249812532
1249912533
/*
1250012534
** Internal function prototypes
1250112535
*/
1250212536
#define sqlite3StrICmp sqlite3_stricmp
@@ -12591,29 +12625,18 @@
1259112625
#endif
1259212626
#if defined(SQLITE_TEST)
1259312627
SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
1259412628
#endif
1259512629
12596
-/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
12597
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
12598
-SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe*);
12599
-SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
12600
-SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe*);
12601
-SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe*);
12602
-SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe*);
12603
-SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe*);
12604
-SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe*, Select*);
12605
-SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe*, Expr*);
12606
-SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe*, ExprList*);
12607
-SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe*);
12608
-#else
12609
-# define sqlite3ExplainBegin(X)
12610
-# define sqlite3ExplainSelect(A,B)
12611
-# define sqlite3ExplainExpr(A,B)
12612
-# define sqlite3ExplainExprList(A,B)
12613
-# define sqlite3ExplainFinish(X)
12614
-# define sqlite3VdbeExplanation(X) 0
12630
+#if defined(SQLITE_DEBUG)
12631
+SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView*,u8);
12632
+SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView*);
12633
+SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView*, const char*, ...);
12634
+SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView*, const char*, u8);
12635
+SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
12636
+SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
12637
+SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
1261512638
#endif
1261612639
1261712640
1261812641
SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
1261912642
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
@@ -12791,11 +12814,11 @@
1279112814
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
1279212815
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
1279312816
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
1279412817
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
1279512818
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
12796
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
12819
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
1279712820
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
1279812821
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
1279912822
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
1280012823
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
1280112824
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
@@ -12815,10 +12838,15 @@
1281512838
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
1281612839
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
1281712840
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
1281812841
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
1281912842
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
12843
+#if SELECTTRACE_ENABLED
12844
+SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
12845
+#else
12846
+# define sqlite3SelectSetName(A,B)
12847
+#endif
1282012848
SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
1282112849
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
1282212850
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
1282312851
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
1282412852
SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
@@ -13292,14 +13320,13 @@
1329213320
# define sqlite3MemdebugSetType(X,Y) /* no-op */
1329313321
# define sqlite3MemdebugHasType(X,Y) 1
1329413322
# define sqlite3MemdebugNoType(X,Y) 1
1329513323
#endif
1329613324
#define MEMTYPE_HEAP 0x01 /* General heap allocations */
13297
-#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
13325
+#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
1329813326
#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
1329913327
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
13300
-#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
1330113328
1330213329
/*
1330313330
** Threading interface
1330413331
*/
1330513332
#if SQLITE_MAX_WORKER_THREADS>0
@@ -13439,10 +13466,17 @@
1343913466
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
1344013467
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
1344113468
};
1344213469
#endif
1344313470
13471
+/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
13472
+** compatibility for legacy applications, the URI filename capability is
13473
+** disabled by default.
13474
+**
13475
+** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
13476
+** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
13477
+*/
1344413478
#ifndef SQLITE_USE_URI
1344513479
# define SQLITE_USE_URI 0
1344613480
#endif
1344713481
1344813482
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
@@ -13945,11 +13979,11 @@
1394513979
1394613980
/* Since ArraySize(azCompileOpt) is normally in single digits, a
1394713981
** linear search is adequate. No need for a binary search. */
1394813982
for(i=0; i<ArraySize(azCompileOpt); i++){
1394913983
if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
13950
- && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0
13984
+ && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
1395113985
){
1395213986
return 1;
1395313987
}
1395413988
}
1395513989
return 0;
@@ -14060,21 +14094,19 @@
1406014094
#ifdef SQLITE_DEBUG
1406114095
u8 seekOp; /* Most recent seek operation on this cursor */
1406214096
#endif
1406314097
i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
1406414098
u8 nullRow; /* True if pointing to a row with no data */
14065
- u8 rowidIsValid; /* True if lastRowid is valid */
1406614099
u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
1406714100
Bool isEphemeral:1; /* True for an ephemeral table */
1406814101
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
1406914102
Bool isTable:1; /* True if a table requiring integer keys */
1407014103
Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
1407114104
Pgno pgnoRoot; /* Root page of the open btree cursor */
1407214105
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
1407314106
i64 seqCount; /* Sequence counter */
1407414107
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
14075
- i64 lastRowid; /* Rowid being deleted by OP_Delete */
1407614108
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
1407714109
1407814110
/* Cached information about the header for the data record that the
1407914111
** cursor is currently pointing to. Only valid if cacheStatus matches
1408014112
** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -14087,10 +14119,11 @@
1408714119
u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
1408814120
u32 payloadSize; /* Total number of bytes in the record */
1408914121
u32 szRow; /* Byte available in aRow */
1409014122
u32 iHdrOffset; /* Offset to next unparsed byte of the header */
1409114123
const u8 *aRow; /* Data for the current row, if all on one page */
14124
+ u32 *aOffset; /* Pointer to aType[nField] */
1409214125
u32 aType[1]; /* Type values for all entries in the record */
1409314126
/* 2*nField extra array elements allocated for aType[], beyond the one
1409414127
** static element declared in the structure. nField total array slots for
1409514128
** aType[] and nField+1 array slots for aOffset[] */
1409614129
};
@@ -14163,11 +14196,11 @@
1416314196
int n; /* Number of characters in string value, excluding '\0' */
1416414197
char *z; /* String or BLOB value */
1416514198
/* ShallowCopy only needs to copy the information above */
1416614199
char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
1416714200
int szMalloc; /* Size of the zMalloc allocation */
14168
- int iPadding1; /* Padding for 8-byte alignment */
14201
+ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
1416914202
sqlite3 *db; /* The associated database connection */
1417014203
void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
1417114204
#ifdef SQLITE_DEBUG
1417214205
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
1417314206
void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
@@ -14259,11 +14292,10 @@
1425914292
*/
1426014293
struct sqlite3_context {
1426114294
Mem *pOut; /* The return value is stored here */
1426214295
FuncDef *pFunc; /* Pointer to function information */
1426314296
Mem *pMem; /* Memory cell used to store aggregate context */
14264
- CollSeq *pColl; /* Collating sequence */
1426514297
Vdbe *pVdbe; /* The VM that owns this context */
1426614298
int iOp; /* Instruction number of OP_Function */
1426714299
int isError; /* Error code returned by the function. */
1426814300
u8 skipFlag; /* Skip accumulator loading if true */
1426914301
u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
@@ -14348,14 +14380,10 @@
1434814380
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
1434914381
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
1435014382
i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
1435114383
char *zSql; /* Text of the SQL statement that generated this */
1435214384
void *pFree; /* Free this when deleting the vdbe */
14353
-#ifdef SQLITE_ENABLE_TREE_EXPLAIN
14354
- Explain *pExplain; /* The explainer */
14355
- char *zExplain; /* Explanation of data structures */
14356
-#endif
1435714385
VdbeFrame *pFrame; /* Parent frame */
1435814386
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
1435914387
int nFrame; /* Number of frames in pFrame list */
1436014388
u32 expmask; /* Binding to these vars invalidates VM */
1436114389
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
@@ -14376,10 +14404,11 @@
1437614404
** Function prototypes
1437714405
*/
1437814406
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
1437914407
void sqliteVdbePopStack(Vdbe*,int);
1438014408
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
14409
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
1438114410
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
1438214411
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
1438314412
#endif
1438414413
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
1438514414
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
@@ -14675,11 +14704,11 @@
1467514704
sqlite3VdbeClearObject(db, pVdbe);
1467614705
sqlite3DbFree(db, pVdbe);
1467714706
}
1467814707
db->pnBytesFreed = 0;
1467914708
14680
- *pHighwater = 0;
14709
+ *pHighwater = 0; /* IMP: R-64479-57858 */
1468114710
*pCurrent = nByte;
1468214711
1468314712
break;
1468414713
}
1468514714
@@ -14700,21 +14729,23 @@
1470014729
if( db->aDb[i].pBt ){
1470114730
Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
1470214731
sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
1470314732
}
1470414733
}
14705
- *pHighwater = 0;
14734
+ *pHighwater = 0; /* IMP: R-42420-56072 */
14735
+ /* IMP: R-54100-20147 */
14736
+ /* IMP: R-29431-39229 */
1470614737
*pCurrent = nRet;
1470714738
break;
1470814739
}
1470914740
1471014741
/* Set *pCurrent to non-zero if there are unresolved deferred foreign
1471114742
** key constraints. Set *pCurrent to zero if all foreign key constraints
1471214743
** have been satisfied. The *pHighwater is always set to zero.
1471314744
*/
1471414745
case SQLITE_DBSTATUS_DEFERRED_FKS: {
14715
- *pHighwater = 0;
14746
+ *pHighwater = 0; /* IMP: R-11967-56545 */
1471614747
*pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
1471714748
break;
1471814749
}
1471914750
1472014751
default: {
@@ -17098,11 +17129,11 @@
1709817129
** allocation p. Also return true if p==NULL.
1709917130
**
1710017131
** This routine is designed for use within an assert() statement, to
1710117132
** verify the type of an allocation. For example:
1710217133
**
17103
-** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
17134
+** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
1710417135
*/
1710517136
SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
1710617137
int rc = 1;
1710717138
if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
1710817139
struct MemBlockHdr *pHdr;
@@ -17120,11 +17151,11 @@
1712017151
** allocation p. Also return true if p==NULL.
1712117152
**
1712217153
** This routine is designed for use within an assert() statement, to
1712317154
** verify the type of an allocation. For example:
1712417155
**
17125
-** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
17156
+** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
1712617157
*/
1712717158
SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
1712817159
int rc = 1;
1712917160
if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
1713017161
struct MemBlockHdr *pHdr;
@@ -20195,11 +20226,11 @@
2019520226
mallocWithAlarm((int)n, &p);
2019620227
sqlite3_mutex_leave(mem0.mutex);
2019720228
}else{
2019820229
p = sqlite3GlobalConfig.m.xMalloc((int)n);
2019920230
}
20200
- assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */
20231
+ assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */
2020120232
return p;
2020220233
}
2020320234
2020420235
/*
2020520236
** This version of the memory allocation is for use by the application.
@@ -20332,39 +20363,41 @@
2033220363
** Return the size of a memory allocation previously obtained from
2033320364
** sqlite3Malloc() or sqlite3_malloc().
2033420365
*/
2033520366
SQLITE_PRIVATE int sqlite3MallocSize(void *p){
2033620367
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20337
- assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
2033820368
return sqlite3GlobalConfig.m.xSize(p);
2033920369
}
2034020370
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
2034120371
if( db==0 ){
20372
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20373
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
2034220374
return sqlite3MallocSize(p);
2034320375
}else{
2034420376
assert( sqlite3_mutex_held(db->mutex) );
2034520377
if( isLookaside(db, p) ){
2034620378
return db->lookaside.sz;
2034720379
}else{
20348
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20349
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20350
- assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20380
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20381
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
2035120382
return sqlite3GlobalConfig.m.xSize(p);
2035220383
}
2035320384
}
2035420385
}
2035520386
SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
20387
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20388
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
2035620389
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
2035720390
}
2035820391
2035920392
/*
2036020393
** Free memory previously obtained from sqlite3Malloc().
2036120394
*/
2036220395
SQLITE_API void sqlite3_free(void *p){
2036320396
if( p==0 ) return; /* IMP: R-49053-54554 */
20364
- assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
2036520397
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20398
+ assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
2036620399
if( sqlite3GlobalConfig.bMemstat ){
2036720400
sqlite3_mutex_enter(mem0.mutex);
2036820401
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
2036920402
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
2037020403
sqlite3GlobalConfig.m.xFree(p);
@@ -20404,12 +20437,12 @@
2040420437
db->lookaside.pFree = pBuf;
2040520438
db->lookaside.nOut--;
2040620439
return;
2040720440
}
2040820441
}
20409
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20410
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20442
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20443
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
2041120444
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
2041220445
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
2041320446
sqlite3_free(p);
2041420447
}
2041520448
@@ -20417,15 +20450,17 @@
2041720450
** Change the size of an existing memory allocation
2041820451
*/
2041920452
SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
2042020453
int nOld, nNew, nDiff;
2042120454
void *pNew;
20455
+ assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20456
+ assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
2042220457
if( pOld==0 ){
20423
- return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
20458
+ return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
2042420459
}
2042520460
if( nBytes==0 ){
20426
- sqlite3_free(pOld); /* IMP: R-31593-10574 */
20461
+ sqlite3_free(pOld); /* IMP: R-26507-47431 */
2042720462
return 0;
2042820463
}
2042920464
if( nBytes>=0x7fffff00 ){
2043020465
/* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
2043120466
return 0;
@@ -20443,12 +20478,10 @@
2044320478
nDiff = nNew - nOld;
2044420479
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
2044520480
mem0.alarmThreshold-nDiff ){
2044620481
sqlite3MallocAlarm(nDiff);
2044720482
}
20448
- assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20449
- assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
2045020483
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
2045120484
if( pNew==0 && mem0.alarmCallback ){
2045220485
sqlite3MallocAlarm((int)nBytes);
2045320486
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
2045420487
}
@@ -20458,11 +20491,11 @@
2045820491
}
2045920492
sqlite3_mutex_leave(mem0.mutex);
2046020493
}else{
2046120494
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
2046220495
}
20463
- assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
20496
+ assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */
2046420497
return pNew;
2046520498
}
2046620499
2046720500
/*
2046820501
** The public interface to sqlite3Realloc. Make sure that the memory
@@ -20470,11 +20503,11 @@
2047020503
*/
2047120504
SQLITE_API void *sqlite3_realloc(void *pOld, int n){
2047220505
#ifndef SQLITE_OMIT_AUTOINIT
2047320506
if( sqlite3_initialize() ) return 0;
2047420507
#endif
20475
- if( n<0 ) n = 0;
20508
+ if( n<0 ) n = 0; /* IMP: R-26507-47431 */
2047620509
return sqlite3Realloc(pOld, n);
2047720510
}
2047820511
SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
2047920512
#ifndef SQLITE_OMIT_AUTOINIT
2048020513
if( sqlite3_initialize() ) return 0;
@@ -20557,12 +20590,12 @@
2055720590
#endif
2055820591
p = sqlite3Malloc(n);
2055920592
if( !p && db ){
2056020593
db->mallocFailed = 1;
2056120594
}
20562
- sqlite3MemdebugSetType(p, MEMTYPE_DB |
20563
- ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20595
+ sqlite3MemdebugSetType(p,
20596
+ (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
2056420597
return p;
2056520598
}
2056620599
2056720600
/*
2056820601
** Resize the block of memory pointed to by p to n bytes. If the
@@ -20584,19 +20617,18 @@
2058420617
if( pNew ){
2058520618
memcpy(pNew, p, db->lookaside.sz);
2058620619
sqlite3DbFree(db, p);
2058720620
}
2058820621
}else{
20589
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20590
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20622
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20623
+ assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
2059120624
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
2059220625
pNew = sqlite3_realloc64(p, n);
2059320626
if( !pNew ){
20594
- sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
2059520627
db->mallocFailed = 1;
2059620628
}
20597
- sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
20629
+ sqlite3MemdebugSetType(pNew,
2059820630
(db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
2059920631
}
2060020632
}
2060120633
return pNew;
2060220634
}
@@ -21757,10 +21789,73 @@
2175721789
fprintf(stdout,"%s", zBuf);
2175821790
fflush(stdout);
2175921791
}
2176021792
#endif
2176121793
21794
+#ifdef SQLITE_DEBUG
21795
+/*************************************************************************
21796
+** Routines for implementing the "TreeView" display of hierarchical
21797
+** data structures for debugging.
21798
+**
21799
+** The main entry points (coded elsewhere) are:
21800
+** sqlite3TreeViewExpr(0, pExpr, 0);
21801
+** sqlite3TreeViewExprList(0, pList, 0, 0);
21802
+** sqlite3TreeViewSelect(0, pSelect, 0);
21803
+** Insert calls to those routines while debugging in order to display
21804
+** a diagram of Expr, ExprList, and Select objects.
21805
+**
21806
+*/
21807
+/* Add a new subitem to the tree. The moreToFollow flag indicates that this
21808
+** is not the last item in the tree. */
21809
+SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
21810
+ if( p==0 ){
21811
+ p = sqlite3_malloc( sizeof(*p) );
21812
+ if( p==0 ) return 0;
21813
+ memset(p, 0, sizeof(*p));
21814
+ }else{
21815
+ p->iLevel++;
21816
+ }
21817
+ assert( moreToFollow==0 || moreToFollow==1 );
21818
+ if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
21819
+ return p;
21820
+}
21821
+/* Finished with one layer of the tree */
21822
+SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView *p){
21823
+ if( p==0 ) return;
21824
+ p->iLevel--;
21825
+ if( p->iLevel<0 ) sqlite3_free(p);
21826
+}
21827
+/* Generate a single line of output for the tree, with a prefix that contains
21828
+** all the appropriate tree lines */
21829
+SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
21830
+ va_list ap;
21831
+ int i;
21832
+ StrAccum acc;
21833
+ char zBuf[500];
21834
+ sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
21835
+ acc.useMalloc = 0;
21836
+ if( p ){
21837
+ for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
21838
+ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
21839
+ }
21840
+ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
21841
+ }
21842
+ va_start(ap, zFormat);
21843
+ sqlite3VXPrintf(&acc, 0, zFormat, ap);
21844
+ va_end(ap);
21845
+ if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
21846
+ sqlite3StrAccumFinish(&acc);
21847
+ fprintf(stdout,"%s", zBuf);
21848
+ fflush(stdout);
21849
+}
21850
+/* Shorthand for starting a new tree item that consists of a single label */
21851
+SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
21852
+ p = sqlite3TreeViewPush(p, moreToFollow);
21853
+ sqlite3TreeViewLine(p, "%s", zLabel);
21854
+}
21855
+#endif /* SQLITE_DEBUG */
21856
+
2176221857
/*
2176321858
** variable-argument wrapper around sqlite3VXPrintf().
2176421859
*/
2176521860
SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
2176621861
va_list ap;
@@ -21996,18 +22091,18 @@
2199622091
#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
2199722092
/******************************** End Unix Pthreads *************************/
2199822093
2199922094
2200022095
/********************************* Win32 Threads ****************************/
22001
-#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
22096
+#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
2200222097
2200322098
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
2200422099
#include <process.h>
2200522100
2200622101
/* A running thread */
2200722102
struct SQLiteThread {
22008
- uintptr_t tid; /* The thread handle */
22103
+ void *tid; /* The thread handle */
2200922104
unsigned id; /* The thread identifier */
2201022105
void *(*xTask)(void*); /* The routine to run as a thread */
2201122106
void *pIn; /* Argument to xTask */
2201222107
void *pResult; /* Result of xTask */
2201322108
};
@@ -22051,11 +22146,11 @@
2205122146
if( sqlite3GlobalConfig.bCoreMutex==0 ){
2205222147
memset(p, 0, sizeof(*p));
2205322148
}else{
2205422149
p->xTask = xTask;
2205522150
p->pIn = pIn;
22056
- p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
22151
+ p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
2205722152
if( p->tid==0 ){
2205822153
memset(p, 0, sizeof(*p));
2205922154
}
2206022155
}
2206122156
if( p->xTask==0 ){
@@ -22089,11 +22184,11 @@
2208922184
if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
2209022185
sqlite3_free(p);
2209122186
return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
2209222187
}
2209322188
22094
-#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
22189
+#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */
2209522190
/******************************** End Win32 Threads *************************/
2209622191
2209722192
2209822193
/********************************* Single-Threaded **************************/
2209922194
#ifndef SQLITE_THREADS_IMPLEMENTED
@@ -29659,11 +29754,11 @@
2965929754
** methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
2966029755
**
2966129756
** * An I/O method finder function called FINDER that returns a pointer
2966229757
** to the METHOD object in the previous bullet.
2966329758
*/
29664
-#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK) \
29759
+#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \
2966529760
static const sqlite3_io_methods METHOD = { \
2966629761
VERSION, /* iVersion */ \
2966729762
CLOSE, /* xClose */ \
2966829763
unixRead, /* xRead */ \
2966929764
unixWrite, /* xWrite */ \
@@ -29674,11 +29769,11 @@
2967429769
UNLOCK, /* xUnlock */ \
2967529770
CKLOCK, /* xCheckReservedLock */ \
2967629771
unixFileControl, /* xFileControl */ \
2967729772
unixSectorSize, /* xSectorSize */ \
2967829773
unixDeviceCharacteristics, /* xDeviceCapabilities */ \
29679
- unixShmMap, /* xShmMap */ \
29774
+ SHMMAP, /* xShmMap */ \
2968029775
unixShmLock, /* xShmLock */ \
2968129776
unixShmBarrier, /* xShmBarrier */ \
2968229777
unixShmUnmap, /* xShmUnmap */ \
2968329778
unixFetch, /* xFetch */ \
2968429779
unixUnfetch, /* xUnfetch */ \
@@ -29700,29 +29795,32 @@
2970029795
posixIoMethods, /* sqlite3_io_methods object name */
2970129796
3, /* shared memory and mmap are enabled */
2970229797
unixClose, /* xClose method */
2970329798
unixLock, /* xLock method */
2970429799
unixUnlock, /* xUnlock method */
29705
- unixCheckReservedLock /* xCheckReservedLock method */
29800
+ unixCheckReservedLock, /* xCheckReservedLock method */
29801
+ unixShmMap /* xShmMap method */
2970629802
)
2970729803
IOMETHODS(
2970829804
nolockIoFinder, /* Finder function name */
2970929805
nolockIoMethods, /* sqlite3_io_methods object name */
2971029806
3, /* shared memory is disabled */
2971129807
nolockClose, /* xClose method */
2971229808
nolockLock, /* xLock method */
2971329809
nolockUnlock, /* xUnlock method */
29714
- nolockCheckReservedLock /* xCheckReservedLock method */
29810
+ nolockCheckReservedLock, /* xCheckReservedLock method */
29811
+ 0 /* xShmMap method */
2971529812
)
2971629813
IOMETHODS(
2971729814
dotlockIoFinder, /* Finder function name */
2971829815
dotlockIoMethods, /* sqlite3_io_methods object name */
2971929816
1, /* shared memory is disabled */
2972029817
dotlockClose, /* xClose method */
2972129818
dotlockLock, /* xLock method */
2972229819
dotlockUnlock, /* xUnlock method */
29723
- dotlockCheckReservedLock /* xCheckReservedLock method */
29820
+ dotlockCheckReservedLock, /* xCheckReservedLock method */
29821
+ 0 /* xShmMap method */
2972429822
)
2972529823
2972629824
#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
2972729825
IOMETHODS(
2972829826
flockIoFinder, /* Finder function name */
@@ -29729,11 +29827,12 @@
2972929827
flockIoMethods, /* sqlite3_io_methods object name */
2973029828
1, /* shared memory is disabled */
2973129829
flockClose, /* xClose method */
2973229830
flockLock, /* xLock method */
2973329831
flockUnlock, /* xUnlock method */
29734
- flockCheckReservedLock /* xCheckReservedLock method */
29832
+ flockCheckReservedLock, /* xCheckReservedLock method */
29833
+ 0 /* xShmMap method */
2973529834
)
2973629835
#endif
2973729836
2973829837
#if OS_VXWORKS
2973929838
IOMETHODS(
@@ -29741,11 +29840,12 @@
2974129840
semIoMethods, /* sqlite3_io_methods object name */
2974229841
1, /* shared memory is disabled */
2974329842
semClose, /* xClose method */
2974429843
semLock, /* xLock method */
2974529844
semUnlock, /* xUnlock method */
29746
- semCheckReservedLock /* xCheckReservedLock method */
29845
+ semCheckReservedLock, /* xCheckReservedLock method */
29846
+ 0 /* xShmMap method */
2974729847
)
2974829848
#endif
2974929849
2975029850
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
2975129851
IOMETHODS(
@@ -29753,11 +29853,12 @@
2975329853
afpIoMethods, /* sqlite3_io_methods object name */
2975429854
1, /* shared memory is disabled */
2975529855
afpClose, /* xClose method */
2975629856
afpLock, /* xLock method */
2975729857
afpUnlock, /* xUnlock method */
29758
- afpCheckReservedLock /* xCheckReservedLock method */
29858
+ afpCheckReservedLock, /* xCheckReservedLock method */
29859
+ 0 /* xShmMap method */
2975929860
)
2976029861
#endif
2976129862
2976229863
/*
2976329864
** The proxy locking method is a "super-method" in the sense that it
@@ -29778,11 +29879,12 @@
2977829879
proxyIoMethods, /* sqlite3_io_methods object name */
2977929880
1, /* shared memory is disabled */
2978029881
proxyClose, /* xClose method */
2978129882
proxyLock, /* xLock method */
2978229883
proxyUnlock, /* xUnlock method */
29783
- proxyCheckReservedLock /* xCheckReservedLock method */
29884
+ proxyCheckReservedLock, /* xCheckReservedLock method */
29885
+ 0 /* xShmMap method */
2978429886
)
2978529887
#endif
2978629888
2978729889
/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
2978829890
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
@@ -29791,11 +29893,12 @@
2979129893
nfsIoMethods, /* sqlite3_io_methods object name */
2979229894
1, /* shared memory is disabled */
2979329895
unixClose, /* xClose method */
2979429896
unixLock, /* xLock method */
2979529897
nfsUnlock, /* xUnlock method */
29796
- unixCheckReservedLock /* xCheckReservedLock method */
29898
+ unixCheckReservedLock, /* xCheckReservedLock method */
29899
+ 0 /* xShmMap method */
2979729900
)
2979829901
#endif
2979929902
2980029903
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
2980129904
/*
@@ -33384,11 +33487,15 @@
3338433487
#endif
3338533488
3338633489
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
3338733490
DWORD))aSyscall[63].pCurrent)
3338833491
33492
+#if !SQLITE_OS_WINCE
3338933493
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
33494
+#else
33495
+ { "WaitForSingleObjectEx", (SYSCALL)0, 0 },
33496
+#endif
3339033497
3339133498
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
3339233499
BOOL))aSyscall[64].pCurrent)
3339333500
3339433501
#if SQLITE_OS_WINRT
@@ -33727,11 +33834,12 @@
3372733834
#else
3372833835
osSleep(milliseconds);
3372933836
#endif
3373033837
}
3373133838
33732
-#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
33839
+#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
33840
+ SQLITE_THREADSAFE>0
3373333841
SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
3373433842
DWORD rc;
3373533843
while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
3373633844
TRUE))==WAIT_IO_COMPLETION ){}
3373733845
return rc;
@@ -39752,11 +39860,11 @@
3975239860
assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
3975339861
assert( pCache->n90pct == pCache->nMax*9/10 );
3975439862
if( createFlag==1 && (
3975539863
nPinned>=pGroup->mxPinned
3975639864
|| nPinned>=pCache->n90pct
39757
- || pcache1UnderMemoryPressure(pCache)
39865
+ || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
3975839866
)){
3975939867
return 0;
3976039868
}
3976139869
3976239870
if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
@@ -44373,17 +44481,19 @@
4437344481
if( !pNew ) rc = SQLITE_NOMEM;
4437444482
}
4437544483
4437644484
if( rc==SQLITE_OK ){
4437744485
pager_reset(pPager);
44378
- sqlite3PageFree(pPager->pTmpSpace);
44379
- pPager->pTmpSpace = pNew;
4438044486
rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
4438144487
}
4438244488
if( rc==SQLITE_OK ){
44489
+ sqlite3PageFree(pPager->pTmpSpace);
44490
+ pPager->pTmpSpace = pNew;
4438344491
pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
4438444492
pPager->pageSize = pageSize;
44493
+ }else{
44494
+ sqlite3PageFree(pNew);
4438544495
}
4438644496
}
4438744497
4438844498
*pPageSize = pPager->pageSize;
4438944499
if( rc==SQLITE_OK ){
@@ -51383,13 +51493,14 @@
5138351493
** stored in MemPage.pBt->mutex.
5138451494
*/
5138551495
struct MemPage {
5138651496
u8 isInit; /* True if previously initialized. MUST BE FIRST! */
5138751497
u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
51388
- u8 intKey; /* True if intkey flag is set */
51389
- u8 leaf; /* True if leaf flag is set */
51390
- u8 hasData; /* True if this page stores data */
51498
+ u8 intKey; /* True if table b-trees. False for index b-trees */
51499
+ u8 intKeyLeaf; /* True if the leaf of an intKey table */
51500
+ u8 noPayload; /* True if internal intKey page (thus w/o data) */
51501
+ u8 leaf; /* True if a leaf page */
5139151502
u8 hdrOffset; /* 100 for page 1. 0 otherwise */
5139251503
u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
5139351504
u8 max1bytePayload; /* min(maxLocal,127) */
5139451505
u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
5139551506
u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
@@ -51545,11 +51656,11 @@
5154551656
int nRef; /* Number of references to this structure */
5154651657
BtShared *pNext; /* Next on a list of sharable BtShared structs */
5154751658
BtLock *pLock; /* List of locks held on this shared-btree struct */
5154851659
Btree *pWriter; /* Btree with currently open write transaction */
5154951660
#endif
51550
- u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */
51661
+ u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
5155151662
};
5155251663
5155351664
/*
5155451665
** Allowed values for BtShared.btsFlags
5155551666
*/
@@ -51566,16 +51677,14 @@
5156651677
** about a cell. The parseCellPtr() function fills in this structure
5156751678
** based on information extract from the raw disk page.
5156851679
*/
5156951680
typedef struct CellInfo CellInfo;
5157051681
struct CellInfo {
51571
- i64 nKey; /* The key for INTKEY tables, or number of bytes in key */
51572
- u8 *pCell; /* Pointer to the start of cell content */
51573
- u32 nData; /* Number of bytes of data */
51574
- u32 nPayload; /* Total amount of payload */
51575
- u16 nHeader; /* Size of the cell content header in bytes */
51576
- u16 nLocal; /* Amount of payload held locally */
51682
+ i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
51683
+ u8 *pPayload; /* Pointer to the start of payload */
51684
+ u32 nPayload; /* Bytes of payload */
51685
+ u16 nLocal; /* Amount of payload held locally, not on overflow */
5157751686
u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
5157851687
u16 nSize; /* Size of the cell content on the main b-tree page */
5157951688
};
5158051689
5158151690
/*
@@ -51768,10 +51877,12 @@
5176851877
u8 *aPgRef; /* 1 bit per page in the db (see above) */
5176951878
Pgno nPage; /* Number of pages in the database */
5177051879
int mxErr; /* Stop accumulating errors when this reaches zero */
5177151880
int nErr; /* Number of messages written to zErrMsg so far */
5177251881
int mallocFailed; /* A memory allocation error has occurred */
51882
+ const char *zPfx; /* Error message prefix */
51883
+ int v1, v2; /* Values for up to two %d fields in zPfx */
5177351884
StrAccum errMsg; /* Accumulate the error message text here */
5177451885
};
5177551886
5177651887
/*
5177751888
** Routines to read or write a two- and four-byte big-endian integer values.
@@ -52554,11 +52665,13 @@
5255452665
){
5255552666
BtCursor *p;
5255652667
BtShared *pBt = pBtree->pBt;
5255752668
assert( sqlite3BtreeHoldsMutex(pBtree) );
5255852669
for(p=pBt->pCursor; p; p=p->pNext){
52559
- if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){
52670
+ if( (p->curFlags & BTCF_Incrblob)!=0
52671
+ && (isClearTable || p->info.nKey==iRow)
52672
+ ){
5256052673
p->eState = CURSOR_INVALID;
5256152674
}
5256252675
}
5256352676
}
5256452677
@@ -52727,13 +52840,13 @@
5272752840
** the cursors if and when a cursor is found that actually requires saving.
5272852841
** The common case is that no cursors need to be saved, so this routine is
5272952842
** broken out from its caller to avoid unnecessary stack pointer movement.
5273052843
*/
5273152844
static int SQLITE_NOINLINE saveCursorsOnList(
52732
- BtCursor *p, /* The first cursor that needs saving */
52733
- Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
52734
- BtCursor *pExcept /* Do not save this cursor */
52845
+ BtCursor *p, /* The first cursor that needs saving */
52846
+ Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
52847
+ BtCursor *pExcept /* Do not save this cursor */
5273552848
){
5273652849
do{
5273752850
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
5273852851
if( p->eState==CURSOR_VALID ){
5273952852
int rc = saveCursorPosition(p);
@@ -52841,11 +52954,11 @@
5284152954
**
5284252955
** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
5284352956
** back to where it ought to be if this routine returns true.
5284452957
*/
5284552958
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
52846
- return pCur && pCur->eState!=CURSOR_VALID;
52959
+ return pCur->eState!=CURSOR_VALID;
5284752960
}
5284852961
5284952962
/*
5285052963
** This routine restores a cursor back to its original position after it
5285152964
** has been moved by some outside activity (such as a btree rebalance or
@@ -53035,51 +53148,48 @@
5303553148
/*
5303653149
** Parse a cell content block and fill in the CellInfo structure. There
5303753150
** are two versions of this function. btreeParseCell() takes a
5303853151
** cell index as the second argument and btreeParseCellPtr()
5303953152
** takes a pointer to the body of the cell as its second argument.
53040
-**
53041
-** Within this file, the parseCell() macro can be called instead of
53042
-** btreeParseCellPtr(). Using some compilers, this will be faster.
5304353153
*/
5304453154
static void btreeParseCellPtr(
5304553155
MemPage *pPage, /* Page containing the cell */
5304653156
u8 *pCell, /* Pointer to the cell text. */
5304753157
CellInfo *pInfo /* Fill in this structure */
5304853158
){
53049
- u16 n; /* Number bytes in cell content header */
53159
+ u8 *pIter; /* For scanning through pCell */
5305053160
u32 nPayload; /* Number of bytes of cell payload */
5305153161
5305253162
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
53053
-
53054
- pInfo->pCell = pCell;
5305553163
assert( pPage->leaf==0 || pPage->leaf==1 );
53056
- n = pPage->childPtrSize;
53057
- assert( n==4-4*pPage->leaf );
53058
- if( pPage->intKey ){
53059
- if( pPage->hasData ){
53060
- assert( n==0 );
53061
- n = getVarint32(pCell, nPayload);
53062
- }else{
53063
- nPayload = 0;
53064
- }
53065
- n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
53066
- pInfo->nData = nPayload;
53067
- }else{
53068
- pInfo->nData = 0;
53069
- n += getVarint32(&pCell[n], nPayload);
53164
+ if( pPage->intKeyLeaf ){
53165
+ assert( pPage->childPtrSize==0 );
53166
+ pIter = pCell + getVarint32(pCell, nPayload);
53167
+ pIter += getVarint(pIter, (u64*)&pInfo->nKey);
53168
+ }else if( pPage->noPayload ){
53169
+ assert( pPage->childPtrSize==4 );
53170
+ pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
53171
+ pInfo->nPayload = 0;
53172
+ pInfo->nLocal = 0;
53173
+ pInfo->iOverflow = 0;
53174
+ pInfo->pPayload = 0;
53175
+ return;
53176
+ }else{
53177
+ pIter = pCell + pPage->childPtrSize;
53178
+ pIter += getVarint32(pIter, nPayload);
5307053179
pInfo->nKey = nPayload;
5307153180
}
5307253181
pInfo->nPayload = nPayload;
53073
- pInfo->nHeader = n;
53182
+ pInfo->pPayload = pIter;
5307453183
testcase( nPayload==pPage->maxLocal );
5307553184
testcase( nPayload==pPage->maxLocal+1 );
53076
- if( likely(nPayload<=pPage->maxLocal) ){
53185
+ if( nPayload<=pPage->maxLocal ){
5307753186
/* This is the (easy) common case where the entire payload fits
5307853187
** on the local page. No overflow is required.
5307953188
*/
53080
- if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4;
53189
+ pInfo->nSize = nPayload + (u16)(pIter - pCell);
53190
+ if( pInfo->nSize<4 ) pInfo->nSize = 4;
5308153191
pInfo->nLocal = (u16)nPayload;
5308253192
pInfo->iOverflow = 0;
5308353193
}else{
5308453194
/* If the payload will not fit completely on the local page, we have
5308553195
** to decide how much to store locally and how much to spill onto
@@ -53102,33 +53212,32 @@
5310253212
if( surplus <= maxLocal ){
5310353213
pInfo->nLocal = (u16)surplus;
5310453214
}else{
5310553215
pInfo->nLocal = (u16)minLocal;
5310653216
}
53107
- pInfo->iOverflow = (u16)(pInfo->nLocal + n);
53217
+ pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
5310853218
pInfo->nSize = pInfo->iOverflow + 4;
5310953219
}
5311053220
}
53111
-#define parseCell(pPage, iCell, pInfo) \
53112
- btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
5311353221
static void btreeParseCell(
5311453222
MemPage *pPage, /* Page containing the cell */
5311553223
int iCell, /* The cell index. First cell is 0 */
5311653224
CellInfo *pInfo /* Fill in this structure */
5311753225
){
53118
- parseCell(pPage, iCell, pInfo);
53226
+ btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo);
5311953227
}
5312053228
5312153229
/*
5312253230
** Compute the total number of bytes that a Cell needs in the cell
5312353231
** data area of the btree-page. The return number includes the cell
5312453232
** data header and the local payload, but not any overflow page or
5312553233
** the space used by the cell pointer.
5312653234
*/
5312753235
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
53128
- u8 *pIter = &pCell[pPage->childPtrSize];
53129
- u32 nSize;
53236
+ u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
53237
+ u8 *pEnd; /* End mark for a varint */
53238
+ u32 nSize; /* Size value to return */
5313053239
5313153240
#ifdef SQLITE_DEBUG
5313253241
/* The value returned by this function should always be the same as
5313353242
** the (CellInfo.nSize) value found by doing a full parse of the
5313453243
** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
@@ -53135,47 +53244,48 @@
5313553244
** this function verifies that this invariant is not violated. */
5313653245
CellInfo debuginfo;
5313753246
btreeParseCellPtr(pPage, pCell, &debuginfo);
5313853247
#endif
5313953248
53249
+ if( pPage->noPayload ){
53250
+ pEnd = &pIter[9];
53251
+ while( (*pIter++)&0x80 && pIter<pEnd );
53252
+ assert( pPage->childPtrSize==4 );
53253
+ return (u16)(pIter - pCell);
53254
+ }
53255
+ nSize = *pIter;
53256
+ if( nSize>=0x80 ){
53257
+ pEnd = &pIter[9];
53258
+ nSize &= 0x7f;
53259
+ do{
53260
+ nSize = (nSize<<7) | (*++pIter & 0x7f);
53261
+ }while( *(pIter)>=0x80 && pIter<pEnd );
53262
+ }
53263
+ pIter++;
5314053264
if( pPage->intKey ){
53141
- u8 *pEnd;
53142
- if( pPage->hasData ){
53143
- pIter += getVarint32(pIter, nSize);
53144
- }else{
53145
- nSize = 0;
53146
- }
53147
-
5314853265
/* pIter now points at the 64-bit integer key value, a variable length
5314953266
** integer. The following block moves pIter to point at the first byte
5315053267
** past the end of the key value. */
5315153268
pEnd = &pIter[9];
5315253269
while( (*pIter++)&0x80 && pIter<pEnd );
53153
- }else{
53154
- pIter += getVarint32(pIter, nSize);
5315553270
}
53156
-
5315753271
testcase( nSize==pPage->maxLocal );
5315853272
testcase( nSize==pPage->maxLocal+1 );
53159
- if( nSize>pPage->maxLocal ){
53273
+ if( nSize<=pPage->maxLocal ){
53274
+ nSize += (u32)(pIter - pCell);
53275
+ if( nSize<4 ) nSize = 4;
53276
+ }else{
5316053277
int minLocal = pPage->minLocal;
5316153278
nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
5316253279
testcase( nSize==pPage->maxLocal );
5316353280
testcase( nSize==pPage->maxLocal+1 );
5316453281
if( nSize>pPage->maxLocal ){
5316553282
nSize = minLocal;
5316653283
}
53167
- nSize += 4;
53168
- }
53169
- nSize += (u32)(pIter - pCell);
53170
-
53171
- /* The minimum size of any cell is 4 bytes. */
53172
- if( nSize<4 ){
53173
- nSize = 4;
53174
- }
53175
-
53176
- assert( nSize==debuginfo.nSize );
53284
+ nSize += 4 + (u16)(pIter - pCell);
53285
+ }
53286
+ assert( nSize==debuginfo.nSize || CORRUPT_DB );
5317753287
return (u16)nSize;
5317853288
}
5317953289
5318053290
#ifdef SQLITE_DEBUG
5318153291
/* This variation on cellSizePtr() is used inside of assert() statements
@@ -53194,11 +53304,10 @@
5319453304
static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
5319553305
CellInfo info;
5319653306
if( *pRC ) return;
5319753307
assert( pCell!=0 );
5319853308
btreeParseCellPtr(pPage, pCell, &info);
53199
- assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
5320053309
if( info.iOverflow ){
5320153310
Pgno ovfl = get4byte(&pCell[info.iOverflow]);
5320253311
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
5320353312
}
5320453313
}
@@ -53407,11 +53516,11 @@
5340753516
** does it detect cells or freeblocks that encrouch into the reserved bytes
5340853517
** at the end of the page. So do additional corruption checks inside this
5340953518
** routine and return SQLITE_CORRUPT if any problems are found.
5341053519
*/
5341153520
static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
53412
- u16 iPtr; /* Address of pointer to next freeblock */
53521
+ u16 iPtr; /* Address of ptr to next freeblock */
5341353522
u16 iFreeBlk; /* Address of the next freeblock */
5341453523
u8 hdr; /* Page header size. 0 or 100 */
5341553524
u8 nFrag = 0; /* Reduction in fragmentation */
5341653525
u16 iOrigSize = iSize; /* Original value of iSize */
5341753526
u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
@@ -53459,13 +53568,13 @@
5345953568
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
5346053569
iSize = iEnd - iStart;
5346153570
iFreeBlk = get2byte(&data[iFreeBlk]);
5346253571
}
5346353572
53464
- /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
53465
- ** in the page header) then check to see if iStart should be coalesced
53466
- ** onto the end of iPtr.
53573
+ /* If iPtr is another freeblock (that is, if iPtr is not the freelist
53574
+ ** pointer in the page header) then check to see if iStart should be
53575
+ ** coalesced onto the end of iPtr.
5346753576
*/
5346853577
if( iPtr>hdr+1 ){
5346953578
int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
5347053579
if( iPtrEnd+3>=iStart ){
5347153580
if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
@@ -53515,16 +53624,18 @@
5351553624
flagByte &= ~PTF_LEAF;
5351653625
pPage->childPtrSize = 4-4*pPage->leaf;
5351753626
pBt = pPage->pBt;
5351853627
if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
5351953628
pPage->intKey = 1;
53520
- pPage->hasData = pPage->leaf;
53629
+ pPage->intKeyLeaf = pPage->leaf;
53630
+ pPage->noPayload = !pPage->leaf;
5352153631
pPage->maxLocal = pBt->maxLeaf;
5352253632
pPage->minLocal = pBt->minLeaf;
5352353633
}else if( flagByte==PTF_ZERODATA ){
5352453634
pPage->intKey = 0;
53525
- pPage->hasData = 0;
53635
+ pPage->intKeyLeaf = 0;
53636
+ pPage->noPayload = 0;
5352653637
pPage->maxLocal = pBt->maxLocal;
5352753638
pPage->minLocal = pBt->minLocal;
5352853639
}else{
5352953640
return SQLITE_CORRUPT_BKPT;
5353053641
}
@@ -54175,11 +54286,12 @@
5417554286
#endif
5417654287
}
5417754288
5417854289
/*
5417954290
** Make sure pBt->pTmpSpace points to an allocation of
54180
-** MX_CELL_SIZE(pBt) bytes.
54291
+** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
54292
+** pointer.
5418154293
*/
5418254294
static void allocateTempSpace(BtShared *pBt){
5418354295
if( !pBt->pTmpSpace ){
5418454296
pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
5418554297
@@ -54190,21 +54302,32 @@
5419054302
** can mean that fillInCell() only initializes the first 2 or 3
5419154303
** bytes of pTmpSpace, but that the first 4 bytes are copied from
5419254304
** it into a database page. This is not actually a problem, but it
5419354305
** does cause a valgrind error when the 1 or 2 bytes of unitialized
5419454306
** data is passed to system call write(). So to avoid this error,
54195
- ** zero the first 4 bytes of temp space here. */
54196
- if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4);
54307
+ ** zero the first 4 bytes of temp space here.
54308
+ **
54309
+ ** Also: Provide four bytes of initialized space before the
54310
+ ** beginning of pTmpSpace as an area available to prepend the
54311
+ ** left-child pointer to the beginning of a cell.
54312
+ */
54313
+ if( pBt->pTmpSpace ){
54314
+ memset(pBt->pTmpSpace, 0, 8);
54315
+ pBt->pTmpSpace += 4;
54316
+ }
5419754317
}
5419854318
}
5419954319
5420054320
/*
5420154321
** Free the pBt->pTmpSpace allocation
5420254322
*/
5420354323
static void freeTempSpace(BtShared *pBt){
54204
- sqlite3PageFree( pBt->pTmpSpace);
54205
- pBt->pTmpSpace = 0;
54324
+ if( pBt->pTmpSpace ){
54325
+ pBt->pTmpSpace -= 4;
54326
+ sqlite3PageFree(pBt->pTmpSpace);
54327
+ pBt->pTmpSpace = 0;
54328
+ }
5420654329
}
5420754330
5420854331
/*
5420954332
** Close an open database and invalidate all cursors.
5421054333
*/
@@ -54694,15 +54817,15 @@
5469454817
*/
5469554818
static void unlockBtreeIfUnused(BtShared *pBt){
5469654819
assert( sqlite3_mutex_held(pBt->mutex) );
5469754820
assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE );
5469854821
if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
54699
- assert( pBt->pPage1->aData );
54822
+ MemPage *pPage1 = pBt->pPage1;
54823
+ assert( pPage1->aData );
5470054824
assert( sqlite3PagerRefcount(pBt->pPager)==1 );
54701
- assert( pBt->pPage1->aData );
54702
- releasePage(pBt->pPage1);
5470354825
pBt->pPage1 = 0;
54826
+ releasePage(pPage1);
5470454827
}
5470554828
}
5470654829
5470754830
/*
5470854831
** If pBt points to an empty file then convert that empty file
@@ -55739,10 +55862,14 @@
5573955862
assert( pBt->pPage1 && pBt->pPage1->aData );
5574055863
5574155864
if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
5574255865
return SQLITE_READONLY;
5574355866
}
55867
+ if( wrFlag ){
55868
+ allocateTempSpace(pBt);
55869
+ if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
55870
+ }
5574455871
if( iTable==1 && btreePagecount(pBt)==0 ){
5574555872
assert( wrFlag==0 );
5574655873
iTable = 0;
5574755874
}
5574855875
@@ -55928,12 +56055,13 @@
5592856055
** to return an integer result code for historical reasons.
5592956056
*/
5593056057
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
5593156058
assert( cursorHoldsMutex(pCur) );
5593256059
assert( pCur->eState==CURSOR_VALID );
56060
+ assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
5593356061
getCellInfo(pCur);
55934
- *pSize = pCur->info.nData;
56062
+ *pSize = pCur->info.nPayload;
5593556063
return SQLITE_OK;
5593656064
}
5593756065
5593856066
/*
5593956067
** Given the page number of an overflow page in the database (parameter
@@ -56080,34 +56208,32 @@
5608056208
unsigned char *pBuf, /* Write the bytes into this buffer */
5608156209
int eOp /* zero to read. non-zero to write. */
5608256210
){
5608356211
unsigned char *aPayload;
5608456212
int rc = SQLITE_OK;
56085
- u32 nKey;
5608656213
int iIdx = 0;
5608756214
MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
5608856215
BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
5608956216
#ifdef SQLITE_DIRECT_OVERFLOW_READ
56090
- int bEnd; /* True if reading to end of data */
56217
+ unsigned char * const pBufStart = pBuf;
56218
+ int bEnd; /* True if reading to end of data */
5609156219
#endif
5609256220
5609356221
assert( pPage );
5609456222
assert( pCur->eState==CURSOR_VALID );
5609556223
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
5609656224
assert( cursorHoldsMutex(pCur) );
56097
- assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */
56225
+ assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */
5609856226
5609956227
getCellInfo(pCur);
56100
- aPayload = pCur->info.pCell + pCur->info.nHeader;
56101
- nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
56228
+ aPayload = pCur->info.pPayload;
5610256229
#ifdef SQLITE_DIRECT_OVERFLOW_READ
56103
- bEnd = (offset+amt==nKey+pCur->info.nData);
56230
+ bEnd = offset+amt==pCur->info.nPayload;
5610456231
#endif
56232
+ assert( offset+amt <= pCur->info.nPayload );
5610556233
56106
- if( NEVER(offset+amt > nKey+pCur->info.nData)
56107
- || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
56108
- ){
56234
+ if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){
5610956235
/* Trying to read or write past the end of the data is an error */
5611056236
return SQLITE_CORRUPT_BKPT;
5611156237
}
5611256238
5611356239
/* Check if data must be read/written to/from the btree page itself. */
@@ -56159,11 +56285,13 @@
5615956285
5616056286
/* If the overflow page-list cache has been allocated and the
5616156287
** entry for the first required overflow page is valid, skip
5616256288
** directly to it.
5616356289
*/
56164
- if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){
56290
+ if( (pCur->curFlags & BTCF_ValidOvfl)!=0
56291
+ && pCur->aOverflow[offset/ovflSize]
56292
+ ){
5616556293
iIdx = (offset/ovflSize);
5616656294
nextPage = pCur->aOverflow[iIdx];
5616756295
offset = (offset%ovflSize);
5616856296
}
5616956297
@@ -56212,10 +56340,11 @@
5621256340
** 2) data is required from the start of this overflow page, and
5621356341
** 3) the database is file-backed, and
5621456342
** 4) there is no open write-transaction, and
5621556343
** 5) the database is not a WAL database,
5621656344
** 6) all data from the page is being read.
56345
+ ** 7) at least 4 bytes have already been read into the output buffer
5621756346
**
5621856347
** then data can be read directly from the database file into the
5621956348
** output buffer, bypassing the page-cache altogether. This speeds
5622056349
** up loading large records that span many overflow pages.
5622156350
*/
@@ -56223,13 +56352,15 @@
5622356352
&& offset==0 /* (2) */
5622456353
&& (bEnd || a==ovflSize) /* (6) */
5622556354
&& pBt->inTransaction==TRANS_READ /* (4) */
5622656355
&& (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
5622756356
&& pBt->pPage1->aData[19]==0x01 /* (5) */
56357
+ && &pBuf[-4]>=pBufStart /* (7) */
5622856358
){
5622956359
u8 aSave[4];
5623056360
u8 *aWrite = &pBuf[-4];
56361
+ assert( aWrite>=pBufStart ); /* hence (7) */
5623156362
memcpy(aSave, aWrite, 4);
5623256363
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
5623356364
nextPage = get4byte(aWrite);
5623456365
memcpy(aWrite, aSave, 4);
5623556366
}else
@@ -56337,11 +56468,11 @@
5633756468
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
5633856469
assert( cursorHoldsMutex(pCur) );
5633956470
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
5634056471
assert( pCur->info.nSize>0 );
5634156472
*pAmt = pCur->info.nLocal;
56342
- return (void*)(pCur->info.pCell + pCur->info.nHeader);
56473
+ return (void*)pCur->info.pPayload;
5634356474
}
5634456475
5634556476
5634656477
/*
5634756478
** For the entry that cursor pCur is point to, return as
@@ -56765,11 +56896,11 @@
5676556896
pCur->aiIdx[pCur->iPage] = (u16)idx;
5676656897
if( xRecordCompare==0 ){
5676756898
for(;;){
5676856899
i64 nCellKey;
5676956900
pCell = findCell(pPage, idx) + pPage->childPtrSize;
56770
- if( pPage->hasData ){
56901
+ if( pPage->intKeyLeaf ){
5677156902
while( 0x80 <= *(pCell++) ){
5677256903
if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
5677356904
}
5677456905
}
5677556906
getVarint(pCell, (u64*)&nCellKey);
@@ -57024,13 +57155,13 @@
5702457155
** was already pointing to the first entry in the database before
5702557156
** this routine was called, then set *pRes=1.
5702657157
**
5702757158
** The main entry point is sqlite3BtreePrevious(). That routine is optimized
5702857159
** for the common case of merely decrementing the cell counter BtCursor.aiIdx
57029
-** to the previous cell on the current page. The (slower) btreePrevious() helper
57030
-** routine is called when it is necessary to move to a different page or
57031
-** to restore the cursor.
57160
+** to the previous cell on the current page. The (slower) btreePrevious()
57161
+** helper routine is called when it is necessary to move to a different page
57162
+** or to restore the cursor.
5703257163
**
5703357164
** The calling function will set *pRes to 0 or 1. The initial *pRes value
5703457165
** will be 1 if the cursor being stepped corresponds to an SQL index and
5703557166
** if this routine could have been skipped if that SQL index had been
5703657167
** a unique index. Otherwise the caller will have set *pRes to zero.
@@ -57048,12 +57179,11 @@
5704857179
assert( *pRes==0 );
5704957180
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
5705057181
assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
5705157182
assert( pCur->info.nSize==0 );
5705257183
if( pCur->eState!=CURSOR_VALID ){
57053
- assert( pCur->eState>=CURSOR_REQUIRESEEK );
57054
- rc = btreeRestoreCursorPosition(pCur);
57184
+ rc = restoreCursorPosition(pCur);
5705557185
if( rc!=SQLITE_OK ){
5705657186
return rc;
5705757187
}
5705857188
if( CURSOR_INVALID==pCur->eState ){
5705957189
*pRes = 1;
@@ -57354,11 +57484,11 @@
5735457484
if( rc ) goto end_allocate_page;
5735557485
if( closest<k-1 ){
5735657486
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
5735757487
}
5735857488
put4byte(&aData[4], k-1);
57359
- noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
57489
+ noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
5736057490
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
5736157491
if( rc==SQLITE_OK ){
5736257492
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
5736357493
if( rc!=SQLITE_OK ){
5736457494
releasePage(*ppPage);
@@ -57387,11 +57517,11 @@
5738757517
** content for any page that really does lie past the end of the database
5738857518
** file on disk. So the effects of disabling the no-content optimization
5738957519
** here are confined to those pages that lie between the end of the
5739057520
** database image and the end of the database file.
5739157521
*/
57392
- int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;
57522
+ int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0;
5739357523
5739457524
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
5739557525
if( rc ) return rc;
5739657526
pBt->nPage++;
5739757527
if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
@@ -57586,22 +57716,29 @@
5758657716
*pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
5758757717
}
5758857718
}
5758957719
5759057720
/*
57591
-** Free any overflow pages associated with the given Cell.
57721
+** Free any overflow pages associated with the given Cell. Write the
57722
+** local Cell size (the number of bytes on the original page, omitting
57723
+** overflow) into *pnSize.
5759257724
*/
57593
-static int clearCell(MemPage *pPage, unsigned char *pCell){
57725
+static int clearCell(
57726
+ MemPage *pPage, /* The page that contains the Cell */
57727
+ unsigned char *pCell, /* First byte of the Cell */
57728
+ u16 *pnSize /* Write the size of the Cell here */
57729
+){
5759457730
BtShared *pBt = pPage->pBt;
5759557731
CellInfo info;
5759657732
Pgno ovflPgno;
5759757733
int rc;
5759857734
int nOvfl;
5759957735
u32 ovflPageSize;
5760057736
5760157737
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
5760257738
btreeParseCellPtr(pPage, pCell, &info);
57739
+ *pnSize = info.nSize;
5760357740
if( info.iOverflow==0 ){
5760457741
return SQLITE_OK; /* No overflow pages. Return without doing anything */
5760557742
}
5760657743
if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
5760757744
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
@@ -57681,54 +57818,87 @@
5768157818
unsigned char *pPrior;
5768257819
unsigned char *pPayload;
5768357820
BtShared *pBt = pPage->pBt;
5768457821
Pgno pgnoOvfl = 0;
5768557822
int nHeader;
57686
- CellInfo info;
5768757823
5768857824
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
5768957825
5769057826
/* pPage is not necessarily writeable since pCell might be auxiliary
5769157827
** buffer space that is separate from the pPage buffer area */
5769257828
assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
5769357829
|| sqlite3PagerIswriteable(pPage->pDbPage) );
5769457830
5769557831
/* Fill in the header. */
57696
- nHeader = 0;
57697
- if( !pPage->leaf ){
57698
- nHeader += 4;
57699
- }
57700
- if( pPage->hasData ){
57701
- nHeader += putVarint32(&pCell[nHeader], nData+nZero);
57832
+ nHeader = pPage->childPtrSize;
57833
+ nPayload = nData + nZero;
57834
+ if( pPage->intKeyLeaf ){
57835
+ nHeader += putVarint32(&pCell[nHeader], nPayload);
5770257836
}else{
57703
- nData = nZero = 0;
57837
+ assert( nData==0 );
57838
+ assert( nZero==0 );
5770457839
}
5770557840
nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
57706
- btreeParseCellPtr(pPage, pCell, &info);
57707
- assert( info.nHeader==nHeader );
57708
- assert( info.nKey==nKey );
57709
- assert( info.nData==(u32)(nData+nZero) );
5771057841
57711
- /* Fill in the payload */
57712
- nPayload = nData + nZero;
57842
+ /* Fill in the payload size */
5771357843
if( pPage->intKey ){
5771457844
pSrc = pData;
5771557845
nSrc = nData;
5771657846
nData = 0;
5771757847
}else{
5771857848
if( NEVER(nKey>0x7fffffff || pKey==0) ){
5771957849
return SQLITE_CORRUPT_BKPT;
5772057850
}
57721
- nPayload += (int)nKey;
57851
+ nPayload = (int)nKey;
5772257852
pSrc = pKey;
5772357853
nSrc = (int)nKey;
5772457854
}
57725
- *pnSize = info.nSize;
57726
- spaceLeft = info.nLocal;
57855
+ if( nPayload<=pPage->maxLocal ){
57856
+ n = nHeader + nPayload;
57857
+ testcase( n==3 );
57858
+ testcase( n==4 );
57859
+ if( n<4 ) n = 4;
57860
+ *pnSize = n;
57861
+ spaceLeft = nPayload;
57862
+ pPrior = pCell;
57863
+ }else{
57864
+ int mn = pPage->minLocal;
57865
+ n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
57866
+ testcase( n==pPage->maxLocal );
57867
+ testcase( n==pPage->maxLocal+1 );
57868
+ if( n > pPage->maxLocal ) n = mn;
57869
+ spaceLeft = n;
57870
+ *pnSize = n + nHeader + 4;
57871
+ pPrior = &pCell[nHeader+n];
57872
+ }
5772757873
pPayload = &pCell[nHeader];
57728
- pPrior = &pCell[info.iOverflow];
5772957874
57875
+ /* At this point variables should be set as follows:
57876
+ **
57877
+ ** nPayload Total payload size in bytes
57878
+ ** pPayload Begin writing payload here
57879
+ ** spaceLeft Space available at pPayload. If nPayload>spaceLeft,
57880
+ ** that means content must spill into overflow pages.
57881
+ ** *pnSize Size of the local cell (not counting overflow pages)
57882
+ ** pPrior Where to write the pgno of the first overflow page
57883
+ **
57884
+ ** Use a call to btreeParseCellPtr() to verify that the values above
57885
+ ** were computed correctly.
57886
+ */
57887
+#if SQLITE_DEBUG
57888
+ {
57889
+ CellInfo info;
57890
+ btreeParseCellPtr(pPage, pCell, &info);
57891
+ assert( nHeader=(int)(info.pPayload - pCell) );
57892
+ assert( info.nKey==nKey );
57893
+ assert( *pnSize == info.nSize );
57894
+ assert( spaceLeft == info.nLocal );
57895
+ assert( pPrior == &pCell[info.iOverflow] );
57896
+ }
57897
+#endif
57898
+
57899
+ /* Write the payload into the local Cell and any extra into overflow pages */
5773057900
while( nPayload>0 ){
5773157901
if( spaceLeft==0 ){
5773257902
#ifndef SQLITE_OMIT_AUTOVACUUM
5773357903
Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
5773457904
if( pBt->autoVacuum ){
@@ -57865,15 +58035,10 @@
5786558035
** pTemp is not null. Regardless of pTemp, allocate a new entry
5786658036
** in pPage->apOvfl[] and make it point to the cell content (either
5786758037
** in pTemp or the original pCell) and also record its index.
5786858038
** Allocating a new entry in pPage->aCell[] implies that
5786958039
** pPage->nOverflow is incremented.
57870
-**
57871
-** If nSkip is non-zero, then do not copy the first nSkip bytes of the
57872
-** cell. The caller will overwrite them after this function returns. If
57873
-** nSkip is non-zero, then pCell may not point to an invalid memory location
57874
-** (but pCell+nSkip is always valid).
5787558040
*/
5787658041
static void insertCell(
5787758042
MemPage *pPage, /* Page into which we are copying */
5787858043
int i, /* New cell becomes the i-th cell of the page */
5787958044
u8 *pCell, /* Content of the new cell */
@@ -57886,11 +58051,10 @@
5788658051
int j; /* Loop counter */
5788758052
int end; /* First byte past the last cell pointer in data[] */
5788858053
int ins; /* Index in data[] where new cell pointer is inserted */
5788958054
int cellOffset; /* Address of first cell pointer in data[] */
5789058055
u8 *data; /* The content of the whole page */
57891
- int nSkip = (iChild ? 4 : 0);
5789258056
5789358057
if( *pRC ) return;
5789458058
5789558059
assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
5789658060
assert( MX_CELL(pPage->pBt)<=10921 );
@@ -57904,11 +58068,11 @@
5790458068
** might be less than 8 (leaf-size + pointer) on the interior node. Hence
5790558069
** the term after the || in the following assert(). */
5790658070
assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
5790758071
if( pPage->nOverflow || sz+2>pPage->nFree ){
5790858072
if( pTemp ){
57909
- memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
58073
+ memcpy(pTemp, pCell, sz);
5791058074
pCell = pTemp;
5791158075
}
5791258076
if( iChild ){
5791358077
put4byte(pCell, iChild);
5791458078
}
@@ -57933,11 +58097,11 @@
5793358097
** if it returns success */
5793458098
assert( idx >= end+2 );
5793558099
assert( idx+sz <= (int)pPage->pBt->usableSize );
5793658100
pPage->nCell++;
5793758101
pPage->nFree -= (u16)(2 + sz);
57938
- memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
58102
+ memcpy(&data[idx], pCell, sz);
5793958103
if( iChild ){
5794058104
put4byte(&data[idx], iChild);
5794158105
}
5794258106
memmove(&data[ins+2], &data[ins], end-ins);
5794358107
put2byte(&data[ins], idx);
@@ -58432,11 +58596,11 @@
5843258596
**
5843358597
** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
5843458598
** leafData: 1 if pPage holds key+data and pParent holds only keys.
5843558599
*/
5843658600
leafCorrection = apOld[0]->leaf*4;
58437
- leafData = apOld[0]->hasData;
58601
+ leafData = apOld[0]->intKeyLeaf;
5843858602
for(i=0; i<nOld; i++){
5843958603
int limit;
5844058604
5844158605
/* Before doing anything else, take a copy of the i'th original sibling
5844258606
** The rest of this function will use data from the copies rather
@@ -59008,11 +59172,11 @@
5900859172
int const iIdx = pCur->aiIdx[iPage-1];
5900959173
5901059174
rc = sqlite3PagerWrite(pParent->pDbPage);
5901159175
if( rc==SQLITE_OK ){
5901259176
#ifndef SQLITE_OMIT_QUICKBALANCE
59013
- if( pPage->hasData
59177
+ if( pPage->intKeyLeaf
5901459178
&& pPage->nOverflow==1
5901559179
&& pPage->aiOvfl[0]==pPage->nCell
5901659180
&& pParent->pgno!=1
5901759181
&& pParent->nCell==iIdx
5901859182
){
@@ -59127,11 +59291,12 @@
5912759291
assert( pCur->skipNext!=SQLITE_OK );
5912859292
return pCur->skipNext;
5912959293
}
5913059294
5913159295
assert( cursorHoldsMutex(pCur) );
59132
- assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE
59296
+ assert( (pCur->curFlags & BTCF_WriteFlag)!=0
59297
+ && pBt->inTransaction==TRANS_WRITE
5913359298
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
5913459299
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
5913559300
5913659301
/* Assert that the caller has been consistent. If this cursor was opened
5913759302
** expecting an index b-tree, then the caller should be inserting blob
@@ -59160,11 +59325,12 @@
5916059325
invalidateIncrblobCursors(p, nKey, 0);
5916159326
5916259327
/* If the cursor is currently on the last row and we are appending a
5916359328
** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
5916459329
** call */
59165
- if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){
59330
+ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0
59331
+ && pCur->info.nKey==nKey-1 ){
5916659332
loc = -1;
5916759333
}
5916859334
}
5916959335
5917059336
if( !loc ){
@@ -59179,13 +59345,12 @@
5917959345
5918059346
TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
5918159347
pCur->pgnoRoot, nKey, nData, pPage->pgno,
5918259348
loc==0 ? "overwrite" : "new entry"));
5918359349
assert( pPage->isInit );
59184
- allocateTempSpace(pBt);
5918559350
newCell = pBt->pTmpSpace;
59186
- if( newCell==0 ) return SQLITE_NOMEM;
59351
+ assert( newCell!=0 );
5918759352
rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
5918859353
if( rc ) goto end_insert;
5918959354
assert( szNew==cellSizePtr(pPage, newCell) );
5919059355
assert( szNew <= MX_CELL_SIZE(pBt) );
5919159356
idx = pCur->aiIdx[pCur->iPage];
@@ -59198,12 +59363,11 @@
5919859363
}
5919959364
oldCell = findCell(pPage, idx);
5920059365
if( !pPage->leaf ){
5920159366
memcpy(newCell, oldCell, 4);
5920259367
}
59203
- szOld = cellSizePtr(pPage, oldCell);
59204
- rc = clearCell(pPage, oldCell);
59368
+ rc = clearCell(pPage, oldCell, &szOld);
5920559369
dropCell(pPage, idx, szOld, &rc);
5920659370
if( rc ) goto end_insert;
5920759371
}else if( loc<0 && pPage->nCell>0 ){
5920859372
assert( pPage->leaf );
5920959373
idx = ++pCur->aiIdx[pCur->iPage];
@@ -59261,10 +59425,11 @@
5926159425
int rc; /* Return code */
5926259426
MemPage *pPage; /* Page to delete cell from */
5926359427
unsigned char *pCell; /* Pointer to cell to delete */
5926459428
int iCellIdx; /* Index of cell to delete */
5926559429
int iCellDepth; /* Depth of node containing pCell */
59430
+ u16 szCell; /* Size of the cell being deleted */
5926659431
5926759432
assert( cursorHoldsMutex(pCur) );
5926859433
assert( pBt->inTransaction==TRANS_WRITE );
5926959434
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
5927059435
assert( pCur->curFlags & BTCF_WriteFlag );
@@ -59309,12 +59474,12 @@
5930959474
invalidateIncrblobCursors(p, pCur->info.nKey, 0);
5931059475
}
5931159476
5931259477
rc = sqlite3PagerWrite(pPage->pDbPage);
5931359478
if( rc ) return rc;
59314
- rc = clearCell(pPage, pCell);
59315
- dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
59479
+ rc = clearCell(pPage, pCell, &szCell);
59480
+ dropCell(pPage, iCellIdx, szCell, &rc);
5931659481
if( rc ) return rc;
5931759482
5931859483
/* If the cell deleted was not located on a leaf page, then the cursor
5931959484
** is currently pointing to the largest entry in the sub-tree headed
5932059485
** by the child-page of the cell that was just deleted from an internal
@@ -59327,14 +59492,12 @@
5932759492
unsigned char *pTmp;
5932859493
5932959494
pCell = findCell(pLeaf, pLeaf->nCell-1);
5933059495
nCell = cellSizePtr(pLeaf, pCell);
5933159496
assert( MX_CELL_SIZE(pBt) >= nCell );
59332
-
59333
- allocateTempSpace(pBt);
5933459497
pTmp = pBt->pTmpSpace;
59335
-
59498
+ assert( pTmp!=0 );
5933659499
rc = sqlite3PagerWrite(pLeaf->pDbPage);
5933759500
insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
5933859501
dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
5933959502
if( rc ) return rc;
5934059503
}
@@ -59542,10 +59705,11 @@
5954259705
MemPage *pPage;
5954359706
int rc;
5954459707
unsigned char *pCell;
5954559708
int i;
5954659709
int hdr;
59710
+ u16 szCell;
5954759711
5954859712
assert( sqlite3_mutex_held(pBt->mutex) );
5954959713
if( pgno>btreePagecount(pBt) ){
5955059714
return SQLITE_CORRUPT_BKPT;
5955159715
}
@@ -59557,11 +59721,11 @@
5955759721
pCell = findCell(pPage, i);
5955859722
if( !pPage->leaf ){
5955959723
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
5956059724
if( rc ) goto cleardatabasepage_out;
5956159725
}
59562
- rc = clearCell(pPage, pCell);
59726
+ rc = clearCell(pPage, pCell, &szCell);
5956359727
if( rc ) goto cleardatabasepage_out;
5956459728
}
5956559729
if( !pPage->leaf ){
5956659730
rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
5956759731
if( rc ) goto cleardatabasepage_out;
@@ -59903,24 +60067,25 @@
5990360067
/*
5990460068
** Append a message to the error message string.
5990560069
*/
5990660070
static void checkAppendMsg(
5990760071
IntegrityCk *pCheck,
59908
- char *zMsg1,
5990960072
const char *zFormat,
5991060073
...
5991160074
){
5991260075
va_list ap;
60076
+ char zBuf[200];
5991360077
if( !pCheck->mxErr ) return;
5991460078
pCheck->mxErr--;
5991560079
pCheck->nErr++;
5991660080
va_start(ap, zFormat);
5991760081
if( pCheck->errMsg.nChar ){
5991860082
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
5991960083
}
59920
- if( zMsg1 ){
59921
- sqlite3StrAccumAppendAll(&pCheck->errMsg, zMsg1);
60084
+ if( pCheck->zPfx ){
60085
+ sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2);
60086
+ sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf);
5992260087
}
5992360088
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
5992460089
va_end(ap);
5992560090
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
5992660091
pCheck->mallocFailed = 1;
@@ -59954,18 +60119,18 @@
5995460119
** Return 1 if there are 2 or more references to the page and 0 if
5995560120
** if this is the first reference to the page.
5995660121
**
5995760122
** Also check that the page number is in bounds.
5995860123
*/
59959
-static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
60124
+static int checkRef(IntegrityCk *pCheck, Pgno iPage){
5996060125
if( iPage==0 ) return 1;
5996160126
if( iPage>pCheck->nPage ){
59962
- checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
60127
+ checkAppendMsg(pCheck, "invalid page number %d", iPage);
5996360128
return 1;
5996460129
}
5996560130
if( getPageReferenced(pCheck, iPage) ){
59966
- checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
60131
+ checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
5996760132
return 1;
5996860133
}
5996960134
setPageReferenced(pCheck, iPage);
5997060135
return 0;
5997160136
}
@@ -59978,26 +60143,25 @@
5997860143
*/
5997960144
static void checkPtrmap(
5998060145
IntegrityCk *pCheck, /* Integrity check context */
5998160146
Pgno iChild, /* Child page number */
5998260147
u8 eType, /* Expected pointer map type */
59983
- Pgno iParent, /* Expected pointer map parent page number */
59984
- char *zContext /* Context description (used for error msg) */
60148
+ Pgno iParent /* Expected pointer map parent page number */
5998560149
){
5998660150
int rc;
5998760151
u8 ePtrmapType;
5998860152
Pgno iPtrmapParent;
5998960153
5999060154
rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
5999160155
if( rc!=SQLITE_OK ){
5999260156
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
59993
- checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
60157
+ checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild);
5999460158
return;
5999560159
}
5999660160
5999760161
if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
59998
- checkAppendMsg(pCheck, zContext,
60162
+ checkAppendMsg(pCheck,
5999960163
"Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
6000060164
iChild, eType, iParent, ePtrmapType, iPtrmapParent);
6000160165
}
6000260166
}
6000360167
#endif
@@ -60008,51 +60172,50 @@
6000860172
*/
6000960173
static void checkList(
6001060174
IntegrityCk *pCheck, /* Integrity checking context */
6001160175
int isFreeList, /* True for a freelist. False for overflow page list */
6001260176
int iPage, /* Page number for first page in the list */
60013
- int N, /* Expected number of pages in the list */
60014
- char *zContext /* Context for error messages */
60177
+ int N /* Expected number of pages in the list */
6001560178
){
6001660179
int i;
6001760180
int expected = N;
6001860181
int iFirst = iPage;
6001960182
while( N-- > 0 && pCheck->mxErr ){
6002060183
DbPage *pOvflPage;
6002160184
unsigned char *pOvflData;
6002260185
if( iPage<1 ){
60023
- checkAppendMsg(pCheck, zContext,
60186
+ checkAppendMsg(pCheck,
6002460187
"%d of %d pages missing from overflow list starting at %d",
6002560188
N+1, expected, iFirst);
6002660189
break;
6002760190
}
60028
- if( checkRef(pCheck, iPage, zContext) ) break;
60191
+ if( checkRef(pCheck, iPage) ) break;
6002960192
if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
60030
- checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
60193
+ checkAppendMsg(pCheck, "failed to get page %d", iPage);
6003160194
break;
6003260195
}
6003360196
pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
6003460197
if( isFreeList ){
6003560198
int n = get4byte(&pOvflData[4]);
6003660199
#ifndef SQLITE_OMIT_AUTOVACUUM
6003760200
if( pCheck->pBt->autoVacuum ){
60038
- checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
60201
+ checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
6003960202
}
6004060203
#endif
6004160204
if( n>(int)pCheck->pBt->usableSize/4-2 ){
60042
- checkAppendMsg(pCheck, zContext,
60205
+ checkAppendMsg(pCheck,
6004360206
"freelist leaf count too big on page %d", iPage);
6004460207
N--;
6004560208
}else{
6004660209
for(i=0; i<n; i++){
6004760210
Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
6004860211
#ifndef SQLITE_OMIT_AUTOVACUUM
6004960212
if( pCheck->pBt->autoVacuum ){
60050
- checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
60213
+ checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0);
6005160214
}
6005260215
#endif
60053
- checkRef(pCheck, iFreePage, zContext);
60216
+ checkRef(pCheck, iFreePage);
6005460217
}
6005560218
N -= n;
6005660219
}
6005760220
}
6005860221
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -60061,11 +60224,11 @@
6006160224
** page in this overflow list, check that the pointer-map entry for
6006260225
** the following page matches iPage.
6006360226
*/
6006460227
if( pCheck->pBt->autoVacuum && N>0 ){
6006560228
i = get4byte(pOvflData);
60066
- checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
60229
+ checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage);
6006760230
}
6006860231
}
6006960232
#endif
6007060233
iPage = get4byte(pOvflData);
6007160234
sqlite3PagerUnref(pOvflPage);
@@ -60093,11 +60256,10 @@
6009360256
** the root of the tree.
6009460257
*/
6009560258
static int checkTreePage(
6009660259
IntegrityCk *pCheck, /* Context for the sanity check */
6009760260
int iPage, /* Page number of the page to check */
60098
- char *zParentContext, /* Parent context */
6009960261
i64 *pnParentMinKey,
6010060262
i64 *pnParentMaxKey
6010160263
){
6010260264
MemPage *pPage;
6010360265
int i, rc, depth, d2, pgno, cnt;
@@ -60104,38 +60266,42 @@
6010460266
int hdr, cellStart;
6010560267
int nCell;
6010660268
u8 *data;
6010760269
BtShared *pBt;
6010860270
int usableSize;
60109
- char zContext[100];
6011060271
char *hit = 0;
6011160272
i64 nMinKey = 0;
6011260273
i64 nMaxKey = 0;
60113
-
60114
- sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
60274
+ const char *saved_zPfx = pCheck->zPfx;
60275
+ int saved_v1 = pCheck->v1;
60276
+ int saved_v2 = pCheck->v2;
6011560277
6011660278
/* Check that the page exists
6011760279
*/
6011860280
pBt = pCheck->pBt;
6011960281
usableSize = pBt->usableSize;
6012060282
if( iPage==0 ) return 0;
60121
- if( checkRef(pCheck, iPage, zParentContext) ) return 0;
60283
+ if( checkRef(pCheck, iPage) ) return 0;
60284
+ pCheck->zPfx = "Page %d: ";
60285
+ pCheck->v1 = iPage;
6012260286
if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
60123
- checkAppendMsg(pCheck, zContext,
60287
+ checkAppendMsg(pCheck,
6012460288
"unable to get the page. error code=%d", rc);
60125
- return 0;
60289
+ depth = -1;
60290
+ goto end_of_check;
6012660291
}
6012760292
6012860293
/* Clear MemPage.isInit to make sure the corruption detection code in
6012960294
** btreeInitPage() is executed. */
6013060295
pPage->isInit = 0;
6013160296
if( (rc = btreeInitPage(pPage))!=0 ){
6013260297
assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */
60133
- checkAppendMsg(pCheck, zContext,
60298
+ checkAppendMsg(pCheck,
6013460299
"btreeInitPage() returns error code %d", rc);
6013560300
releasePage(pPage);
60136
- return 0;
60301
+ depth = -1;
60302
+ goto end_of_check;
6013760303
}
6013860304
6013960305
/* Check out all the cells.
6014060306
*/
6014160307
depth = 0;
@@ -60144,99 +60310,101 @@
6014460310
u32 sz;
6014560311
CellInfo info;
6014660312
6014760313
/* Check payload overflow pages
6014860314
*/
60149
- sqlite3_snprintf(sizeof(zContext), zContext,
60150
- "On tree page %d cell %d: ", iPage, i);
60315
+ pCheck->zPfx = "On tree page %d cell %d: ";
60316
+ pCheck->v1 = iPage;
60317
+ pCheck->v2 = i;
6015160318
pCell = findCell(pPage,i);
6015260319
btreeParseCellPtr(pPage, pCell, &info);
60153
- sz = info.nData;
60154
- if( !pPage->intKey ) sz += (int)info.nKey;
60320
+ sz = info.nPayload;
6015560321
/* For intKey pages, check that the keys are in order.
6015660322
*/
60157
- else if( i==0 ) nMinKey = nMaxKey = info.nKey;
60158
- else{
60159
- if( info.nKey <= nMaxKey ){
60160
- checkAppendMsg(pCheck, zContext,
60161
- "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
60323
+ if( pPage->intKey ){
60324
+ if( i==0 ){
60325
+ nMinKey = nMaxKey = info.nKey;
60326
+ }else if( info.nKey <= nMaxKey ){
60327
+ checkAppendMsg(pCheck,
60328
+ "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
6016260329
}
6016360330
nMaxKey = info.nKey;
6016460331
}
60165
- assert( sz==info.nPayload );
6016660332
if( (sz>info.nLocal)
6016760333
&& (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
6016860334
){
6016960335
int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
6017060336
Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
6017160337
#ifndef SQLITE_OMIT_AUTOVACUUM
6017260338
if( pBt->autoVacuum ){
60173
- checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
60339
+ checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
6017460340
}
6017560341
#endif
60176
- checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
60342
+ checkList(pCheck, 0, pgnoOvfl, nPage);
6017760343
}
6017860344
6017960345
/* Check sanity of left child page.
6018060346
*/
6018160347
if( !pPage->leaf ){
6018260348
pgno = get4byte(pCell);
6018360349
#ifndef SQLITE_OMIT_AUTOVACUUM
6018460350
if( pBt->autoVacuum ){
60185
- checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
60351
+ checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
6018660352
}
6018760353
#endif
60188
- d2 = checkTreePage(pCheck, pgno, zContext, &nMinKey, i==0 ? NULL : &nMaxKey);
60354
+ d2 = checkTreePage(pCheck, pgno, &nMinKey, i==0?NULL:&nMaxKey);
6018960355
if( i>0 && d2!=depth ){
60190
- checkAppendMsg(pCheck, zContext, "Child page depth differs");
60356
+ checkAppendMsg(pCheck, "Child page depth differs");
6019160357
}
6019260358
depth = d2;
6019360359
}
6019460360
}
6019560361
6019660362
if( !pPage->leaf ){
6019760363
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
60198
- sqlite3_snprintf(sizeof(zContext), zContext,
60199
- "On page %d at right child: ", iPage);
60364
+ pCheck->zPfx = "On page %d at right child: ";
60365
+ pCheck->v1 = iPage;
6020060366
#ifndef SQLITE_OMIT_AUTOVACUUM
6020160367
if( pBt->autoVacuum ){
60202
- checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
60368
+ checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
6020360369
}
6020460370
#endif
60205
- checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
60371
+ checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey);
6020660372
}
6020760373
6020860374
/* For intKey leaf pages, check that the min/max keys are in order
6020960375
** with any left/parent/right pages.
6021060376
*/
60377
+ pCheck->zPfx = "Page %d: ";
60378
+ pCheck->v1 = iPage;
6021160379
if( pPage->leaf && pPage->intKey ){
6021260380
/* if we are a left child page */
6021360381
if( pnParentMinKey ){
6021460382
/* if we are the left most child page */
6021560383
if( !pnParentMaxKey ){
6021660384
if( nMaxKey > *pnParentMinKey ){
60217
- checkAppendMsg(pCheck, zContext,
60385
+ checkAppendMsg(pCheck,
6021860386
"Rowid %lld out of order (max larger than parent min of %lld)",
6021960387
nMaxKey, *pnParentMinKey);
6022060388
}
6022160389
}else{
6022260390
if( nMinKey <= *pnParentMinKey ){
60223
- checkAppendMsg(pCheck, zContext,
60391
+ checkAppendMsg(pCheck,
6022460392
"Rowid %lld out of order (min less than parent min of %lld)",
6022560393
nMinKey, *pnParentMinKey);
6022660394
}
6022760395
if( nMaxKey > *pnParentMaxKey ){
60228
- checkAppendMsg(pCheck, zContext,
60396
+ checkAppendMsg(pCheck,
6022960397
"Rowid %lld out of order (max larger than parent max of %lld)",
6023060398
nMaxKey, *pnParentMaxKey);
6023160399
}
6023260400
*pnParentMinKey = nMaxKey;
6023360401
}
6023460402
/* else if we're a right child page */
6023560403
} else if( pnParentMaxKey ){
6023660404
if( nMinKey <= *pnParentMaxKey ){
60237
- checkAppendMsg(pCheck, zContext,
60405
+ checkAppendMsg(pCheck,
6023860406
"Rowid %lld out of order (min less than parent max of %lld)",
6023960407
nMinKey, *pnParentMaxKey);
6024060408
}
6024160409
}
6024260410
}
@@ -60244,10 +60412,11 @@
6024460412
/* Check for complete coverage of the page
6024560413
*/
6024660414
data = pPage->aData;
6024760415
hdr = pPage->hdrOffset;
6024860416
hit = sqlite3PageMalloc( pBt->pageSize );
60417
+ pCheck->zPfx = 0;
6024960418
if( hit==0 ){
6025060419
pCheck->mallocFailed = 1;
6025160420
}else{
6025260421
int contentOffset = get2byteNotZero(&data[hdr+5]);
6025360422
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
@@ -60261,11 +60430,12 @@
6026160430
int j;
6026260431
if( pc<=usableSize-4 ){
6026360432
size = cellSizePtr(pPage, &data[pc]);
6026460433
}
6026560434
if( (int)(pc+size-1)>=usableSize ){
60266
- checkAppendMsg(pCheck, 0,
60435
+ pCheck->zPfx = 0;
60436
+ checkAppendMsg(pCheck,
6026760437
"Corruption detected in cell %d on page %d",i,iPage);
6026860438
}else{
6026960439
for(j=pc+size-1; j>=pc; j--) hit[j]++;
6027060440
}
6027160441
}
@@ -60283,23 +60453,28 @@
6028360453
}
6028460454
for(i=cnt=0; i<usableSize; i++){
6028560455
if( hit[i]==0 ){
6028660456
cnt++;
6028760457
}else if( hit[i]>1 ){
60288
- checkAppendMsg(pCheck, 0,
60458
+ checkAppendMsg(pCheck,
6028960459
"Multiple uses for byte %d of page %d", i, iPage);
6029060460
break;
6029160461
}
6029260462
}
6029360463
if( cnt!=data[hdr+7] ){
60294
- checkAppendMsg(pCheck, 0,
60464
+ checkAppendMsg(pCheck,
6029560465
"Fragmentation of %d bytes reported as %d on page %d",
6029660466
cnt, data[hdr+7], iPage);
6029760467
}
6029860468
}
6029960469
sqlite3PageFree(hit);
6030060470
releasePage(pPage);
60471
+
60472
+end_of_check:
60473
+ pCheck->zPfx = saved_zPfx;
60474
+ pCheck->v1 = saved_v1;
60475
+ pCheck->v2 = saved_v2;
6030160476
return depth+1;
6030260477
}
6030360478
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
6030460479
6030560480
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
@@ -60336,10 +60511,13 @@
6033660511
sCheck.pPager = pBt->pPager;
6033760512
sCheck.nPage = btreePagecount(sCheck.pBt);
6033860513
sCheck.mxErr = mxErr;
6033960514
sCheck.nErr = 0;
6034060515
sCheck.mallocFailed = 0;
60516
+ sCheck.zPfx = 0;
60517
+ sCheck.v1 = 0;
60518
+ sCheck.v2 = 0;
6034160519
*pnErr = 0;
6034260520
if( sCheck.nPage==0 ){
6034360521
sqlite3BtreeLeave(p);
6034460522
return 0;
6034560523
}
@@ -60355,53 +60533,57 @@
6035560533
sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
6035660534
sCheck.errMsg.useMalloc = 2;
6035760535
6035860536
/* Check the integrity of the freelist
6035960537
*/
60538
+ sCheck.zPfx = "Main freelist: ";
6036060539
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
60361
- get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
60540
+ get4byte(&pBt->pPage1->aData[36]));
60541
+ sCheck.zPfx = 0;
6036260542
6036360543
/* Check all the tables.
6036460544
*/
6036560545
for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
6036660546
if( aRoot[i]==0 ) continue;
6036760547
#ifndef SQLITE_OMIT_AUTOVACUUM
6036860548
if( pBt->autoVacuum && aRoot[i]>1 ){
60369
- checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
60549
+ checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
6037060550
}
6037160551
#endif
60372
- checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
60552
+ sCheck.zPfx = "List of tree roots: ";
60553
+ checkTreePage(&sCheck, aRoot[i], NULL, NULL);
60554
+ sCheck.zPfx = 0;
6037360555
}
6037460556
6037560557
/* Make sure every page in the file is referenced
6037660558
*/
6037760559
for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
6037860560
#ifdef SQLITE_OMIT_AUTOVACUUM
6037960561
if( getPageReferenced(&sCheck, i)==0 ){
60380
- checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
60562
+ checkAppendMsg(&sCheck, "Page %d is never used", i);
6038160563
}
6038260564
#else
6038360565
/* If the database supports auto-vacuum, make sure no tables contain
6038460566
** references to pointer-map pages.
6038560567
*/
6038660568
if( getPageReferenced(&sCheck, i)==0 &&
6038760569
(PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
60388
- checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
60570
+ checkAppendMsg(&sCheck, "Page %d is never used", i);
6038960571
}
6039060572
if( getPageReferenced(&sCheck, i)!=0 &&
6039160573
(PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
60392
- checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
60574
+ checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
6039360575
}
6039460576
#endif
6039560577
}
6039660578
6039760579
/* Make sure this analysis did not leave any unref() pages.
6039860580
** This is an internal consistency check; an integrity check
6039960581
** of the integrity check.
6040060582
*/
6040160583
if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
60402
- checkAppendMsg(&sCheck, 0,
60584
+ checkAppendMsg(&sCheck,
6040360585
"Outstanding page count goes from %d to %d during this analysis",
6040460586
nRef, sqlite3PagerRefcount(pBt->pPager)
6040560587
);
6040660588
}
6040760589
@@ -60593,11 +60775,11 @@
6059360775
6059460776
/* Save the positions of all other cursors open on this table. This is
6059560777
** required in case any of them are holding references to an xFetch
6059660778
** version of the b-tree page modified by the accessPayload call below.
6059760779
**
60598
- ** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition()
60780
+ ** Note that pCsr must be open on a INTKEY table and saveCursorPosition()
6059960781
** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
6060060782
** saveAllCursors can only return SQLITE_OK.
6060160783
*/
6060260784
VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
6060360785
assert( rc==SQLITE_OK );
@@ -61461,11 +61643,14 @@
6146161643
/* If MEM_Dyn is set then Mem.xDel!=0.
6146261644
** Mem.xDel is might not be initialized if MEM_Dyn is clear.
6146361645
*/
6146461646
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
6146561647
61466
- /* MEM_Dyn may only be set if Mem.szMalloc==0 */
61648
+ /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we
61649
+ ** ensure that if Mem.szMalloc>0 then it is safe to do
61650
+ ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
61651
+ ** That saves a few cycles in inner loops. */
6146761652
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
6146861653
6146961654
/* Cannot be both MEM_Int and MEM_Real at the same time */
6147061655
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
6147161656
@@ -61570,11 +61755,11 @@
6157061755
}else{
6157161756
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
6157261757
}
6157361758
}
6157461759
61575
- if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
61760
+ if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
6157661761
memcpy(pMem->zMalloc, pMem->z, pMem->n);
6157761762
}
6157861763
if( (pMem->flags&MEM_Dyn)!=0 ){
6157961764
assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
6158061765
pMem->xDel((void *)(pMem->z));
@@ -61597,11 +61782,12 @@
6159761782
**
6159861783
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
6159961784
** if unable to complete the resizing.
6160061785
*/
6160161786
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
61602
- assert( szNew>=0 );
61787
+ assert( szNew>0 );
61788
+ assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
6160361789
if( pMem->szMalloc<szNew ){
6160461790
return sqlite3VdbeMemGrow(pMem, szNew, 0);
6160561791
}
6160661792
assert( (pMem->flags & MEM_Dyn)==0 );
6160761793
pMem->z = pMem->zMalloc;
@@ -62321,11 +62507,14 @@
6232162507
nAlloc += (enc==SQLITE_UTF8?1:2);
6232262508
}
6232362509
if( nByte>iLimit ){
6232462510
return SQLITE_TOOBIG;
6232562511
}
62326
- if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){
62512
+ testcase( nAlloc==0 );
62513
+ testcase( nAlloc==31 );
62514
+ testcase( nAlloc==32 );
62515
+ if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
6232762516
return SQLITE_NOMEM;
6232862517
}
6232962518
memcpy(pMem->z, z, nAlloc);
6233062519
}else if( xDel==SQLITE_DYNAMIC ){
6233162520
sqlite3VdbeMemRelease(pMem);
@@ -62424,11 +62613,11 @@
6242462613
/*
6242562614
** The pVal argument is known to be a value other than NULL.
6242662615
** Convert it into a string with encoding enc and return a pointer
6242762616
** to a zero-terminated version of that string.
6242862617
*/
62429
-SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
62618
+static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
6243062619
assert( pVal!=0 );
6243162620
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
6243262621
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
6243362622
assert( (pVal->flags & MEM_RowSet)==0 );
6243462623
assert( (pVal->flags & (MEM_Null))==0 );
@@ -63751,11 +63940,12 @@
6375163940
if( addr==p->nOp-1 ) p->nOp--;
6375263941
}
6375363942
}
6375463943
6375563944
/*
63756
-** Remove the last opcode inserted
63945
+** If the last opcode is "op" and it is not a jump destination,
63946
+** then remove it. Return true if and only if an opcode was removed.
6375763947
*/
6375863948
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
6375963949
if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
6376063950
sqlite3VdbeChangeToNoop(p, p->nOp-1);
6376163951
return 1;
@@ -64743,11 +64933,11 @@
6474364933
** the call above. */
6474464934
}else if( pCx->pCursor ){
6474564935
sqlite3BtreeCloseCursor(pCx->pCursor);
6474664936
}
6474764937
#ifndef SQLITE_OMIT_VIRTUALTABLE
64748
- if( pCx->pVtabCursor ){
64938
+ else if( pCx->pVtabCursor ){
6474964939
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
6475064940
const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
6475164941
p->inVtabMethod = 1;
6475264942
pModule->xClose(pVtabCursor);
6475364943
p->inVtabMethod = 0;
@@ -64786,13 +64976,14 @@
6478664976
static void closeAllCursors(Vdbe *p){
6478764977
if( p->pFrame ){
6478864978
VdbeFrame *pFrame;
6478964979
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
6479064980
sqlite3VdbeFrameRestore(pFrame);
64981
+ p->pFrame = 0;
64982
+ p->nFrame = 0;
6479164983
}
64792
- p->pFrame = 0;
64793
- p->nFrame = 0;
64984
+ assert( p->nFrame==0 );
6479464985
6479564986
if( p->apCsr ){
6479664987
int i;
6479764988
for(i=0; i<p->nCursor; i++){
6479864989
VdbeCursor *pC = p->apCsr[i];
@@ -64810,11 +65001,11 @@
6481065001
p->pDelFrame = pDel->pParent;
6481165002
sqlite3VdbeFrameDelete(pDel);
6481265003
}
6481365004
6481465005
/* Delete any auxdata allocations made by the VM */
64815
- sqlite3VdbeDeleteAuxData(p, -1, 0);
65006
+ if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
6481665007
assert( p->pAuxData==0 );
6481765008
}
6481865009
6481965010
/*
6482065011
** Clean up the VM after a single run.
@@ -65676,14 +65867,10 @@
6567665867
for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
6567765868
vdbeFreeOpArray(db, p->aOp, p->nOp);
6567865869
sqlite3DbFree(db, p->aColName);
6567965870
sqlite3DbFree(db, p->zSql);
6568065871
sqlite3DbFree(db, p->pFree);
65681
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
65682
- sqlite3DbFree(db, p->zExplain);
65683
- sqlite3DbFree(db, p->pExplain);
65684
-#endif
6568565872
}
6568665873
6568765874
/*
6568865875
** Delete an entire VDBE.
6568965876
*/
@@ -65720,13 +65907,11 @@
6572065907
#endif
6572165908
assert( p->deferredMoveto );
6572265909
assert( p->isTable );
6572365910
rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
6572465911
if( rc ) return rc;
65725
- p->lastRowid = p->movetoTarget;
6572665912
if( res!=0 ) return SQLITE_CORRUPT_BKPT;
65727
- p->rowidIsValid = 1;
6572865913
#ifdef SQLITE_TEST
6572965914
sqlite3_search_count++;
6573065915
#endif
6573165916
p->deferredMoveto = 0;
6573265917
p->cacheStatus = CACHE_STALE;
@@ -65747,10 +65932,21 @@
6574765932
rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
6574865933
p->cacheStatus = CACHE_STALE;
6574965934
if( isDifferentRow ) p->nullRow = 1;
6575065935
return rc;
6575165936
}
65937
+
65938
+/*
65939
+** Check to ensure that the cursor is valid. Restore the cursor
65940
+** if need be. Return any I/O error from the restore operation.
65941
+*/
65942
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
65943
+ if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65944
+ return handleMovedCursor(p);
65945
+ }
65946
+ return SQLITE_OK;
65947
+}
6575265948
6575365949
/*
6575465950
** Make sure the cursor p is ready to read or write the row to which it
6575565951
** was last positioned. Return an error code if an OOM fault or I/O error
6575665952
** prevents us from positioning the cursor to its correct position.
@@ -65765,11 +65961,11 @@
6576565961
*/
6576665962
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
6576765963
if( p->deferredMoveto ){
6576865964
return handleDeferredMoveto(p);
6576965965
}
65770
- if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65966
+ if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
6577165967
return handleMovedCursor(p);
6577265968
}
6577365969
return SQLITE_OK;
6577465970
}
6577565971
@@ -67390,10 +67586,11 @@
6739067586
void (*xDel)(void *),
6739167587
unsigned char enc
6739267588
){
6739367589
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
6739467590
assert( xDel!=SQLITE_DYNAMIC );
67591
+ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
6739567592
if( n>0x7fffffff ){
6739667593
(void)invokeValueDestructor(z, xDel, pCtx);
6739767594
}else{
6739867595
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
6739967596
}
@@ -68712,125 +68909,10 @@
6871268909
return sqlite3StrAccumFinish(&out);
6871368910
}
6871468911
6871568912
#endif /* #ifndef SQLITE_OMIT_TRACE */
6871668913
68717
-/*****************************************************************************
68718
-** The following code implements the data-structure explaining logic
68719
-** for the Vdbe.
68720
-*/
68721
-
68722
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
68723
-
68724
-/*
68725
-** Allocate a new Explain object
68726
-*/
68727
-SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
68728
- if( pVdbe ){
68729
- Explain *p;
68730
- sqlite3BeginBenignMalloc();
68731
- p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
68732
- if( p ){
68733
- p->pVdbe = pVdbe;
68734
- sqlite3_free(pVdbe->pExplain);
68735
- pVdbe->pExplain = p;
68736
- sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
68737
- SQLITE_MAX_LENGTH);
68738
- p->str.useMalloc = 2;
68739
- }else{
68740
- sqlite3EndBenignMalloc();
68741
- }
68742
- }
68743
-}
68744
-
68745
-/*
68746
-** Return true if the Explain ends with a new-line.
68747
-*/
68748
-static int endsWithNL(Explain *p){
68749
- return p && p->str.zText && p->str.nChar
68750
- && p->str.zText[p->str.nChar-1]=='\n';
68751
-}
68752
-
68753
-/*
68754
-** Append text to the indentation
68755
-*/
68756
-SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
68757
- Explain *p;
68758
- if( pVdbe && (p = pVdbe->pExplain)!=0 ){
68759
- va_list ap;
68760
- if( p->nIndent && endsWithNL(p) ){
68761
- int n = p->nIndent;
68762
- if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
68763
- sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
68764
- }
68765
- va_start(ap, zFormat);
68766
- sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap);
68767
- va_end(ap);
68768
- }
68769
-}
68770
-
68771
-/*
68772
-** Append a '\n' if there is not already one.
68773
-*/
68774
-SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe *pVdbe){
68775
- Explain *p;
68776
- if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
68777
- sqlite3StrAccumAppend(&p->str, "\n", 1);
68778
- }
68779
-}
68780
-
68781
-/*
68782
-** Push a new indentation level. Subsequent lines will be indented
68783
-** so that they begin at the current cursor position.
68784
-*/
68785
-SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe *pVdbe){
68786
- Explain *p;
68787
- if( pVdbe && (p = pVdbe->pExplain)!=0 ){
68788
- if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
68789
- const char *z = p->str.zText;
68790
- int i = p->str.nChar-1;
68791
- int x;
68792
- while( i>=0 && z[i]!='\n' ){ i--; }
68793
- x = (p->str.nChar - 1) - i;
68794
- if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
68795
- x = p->aIndent[p->nIndent-1];
68796
- }
68797
- p->aIndent[p->nIndent] = x;
68798
- }
68799
- p->nIndent++;
68800
- }
68801
-}
68802
-
68803
-/*
68804
-** Pop the indentation stack by one level.
68805
-*/
68806
-SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe *p){
68807
- if( p && p->pExplain ) p->pExplain->nIndent--;
68808
-}
68809
-
68810
-/*
68811
-** Free the indentation structure
68812
-*/
68813
-SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe *pVdbe){
68814
- if( pVdbe && pVdbe->pExplain ){
68815
- sqlite3_free(pVdbe->zExplain);
68816
- sqlite3ExplainNL(pVdbe);
68817
- pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str);
68818
- sqlite3_free(pVdbe->pExplain);
68819
- pVdbe->pExplain = 0;
68820
- sqlite3EndBenignMalloc();
68821
- }
68822
-}
68823
-
68824
-/*
68825
-** Return the explanation of a virtual machine.
68826
-*/
68827
-SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
68828
- return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
68829
-}
68830
-#endif /* defined(SQLITE_DEBUG) */
68831
-
6883268914
/************** End of vdbetrace.c *******************************************/
6883368915
/************** Begin file vdbe.c ********************************************/
6883468916
/*
6883568917
** 2001 September 15
6883668918
**
@@ -69043,10 +69125,11 @@
6904369125
if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
6904469126
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
6904569127
memset(pCx, 0, sizeof(VdbeCursor));
6904669128
pCx->iDb = iDb;
6904769129
pCx->nField = nField;
69130
+ pCx->aOffset = &pCx->aType[nField];
6904869131
if( isBtreeCursor ){
6904969132
pCx->pCursor = (BtCursor*)
6905069133
&pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
6905169134
sqlite3BtreeCursorZero(pCx->pCursor);
6905269135
}
@@ -70475,21 +70558,14 @@
7047570558
assert( pOp->p4type==P4_FUNCDEF );
7047670559
ctx.pFunc = pOp->p4.pFunc;
7047770560
ctx.iOp = pc;
7047870561
ctx.pVdbe = p;
7047970562
MemSetTypeFlag(ctx.pOut, MEM_Null);
70480
-
7048170563
ctx.fErrorOrAux = 0;
70482
- if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
70483
- assert( pOp>aOp );
70484
- assert( pOp[-1].p4type==P4_COLLSEQ );
70485
- assert( pOp[-1].opcode==OP_CollSeq );
70486
- ctx.pColl = pOp[-1].p4.pColl;
70487
- }
7048870564
db->lastRowid = lastRowid;
7048970565
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
70490
- lastRowid = db->lastRowid;
70566
+ lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
7049170567
7049270568
/* If the function returned an error, throw an exception */
7049370569
if( ctx.fErrorOrAux ){
7049470570
if( ctx.isError ){
7049570571
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
@@ -71201,11 +71277,11 @@
7120171277
memAboutToChange(p, pDest);
7120271278
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
7120371279
pC = p->apCsr[pOp->p1];
7120471280
assert( pC!=0 );
7120571281
assert( p2<pC->nField );
71206
- aOffset = pC->aType + pC->nField;
71282
+ aOffset = pC->aOffset;
7120771283
#ifndef SQLITE_OMIT_VIRTUALTABLE
7120871284
assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
7120971285
#endif
7121071286
pCrsr = pC->pCursor;
7121171287
assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
@@ -71212,11 +71288,11 @@
7121271288
assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
7121371289
7121471290
/* If the cursor cache is stale, bring it up-to-date */
7121571291
rc = sqlite3VdbeCursorMoveto(pC);
7121671292
if( rc ) goto abort_due_to_error;
71217
- if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
71293
+ if( pC->cacheStatus!=p->cacheCtr ){
7121871294
if( pC->nullRow ){
7121971295
if( pCrsr==0 ){
7122071296
assert( pC->pseudoTableReg>0 );
7122171297
pReg = &aMem[pC->pseudoTableReg];
7122271298
assert( pReg->flags & MEM_Blob );
@@ -71257,18 +71333,10 @@
7125771333
}
7125871334
pC->cacheStatus = p->cacheCtr;
7125971335
pC->iHdrOffset = getVarint32(pC->aRow, offset);
7126071336
pC->nHdrParsed = 0;
7126171337
aOffset[0] = offset;
71262
- if( avail<offset ){
71263
- /* pC->aRow does not have to hold the entire row, but it does at least
71264
- ** need to cover the header of the record. If pC->aRow does not contain
71265
- ** the complete header, then set it to zero, forcing the header to be
71266
- ** dynamically allocated. */
71267
- pC->aRow = 0;
71268
- pC->szRow = 0;
71269
- }
7127071338
7127171339
/* Make sure a corrupt database has not given us an oversize header.
7127271340
** Do this now to avoid an oversize memory allocation.
7127371341
**
7127471342
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
@@ -71279,19 +71347,36 @@
7127971347
*/
7128071348
if( offset > 98307 || offset > pC->payloadSize ){
7128171349
rc = SQLITE_CORRUPT_BKPT;
7128271350
goto op_column_error;
7128371351
}
71352
+
71353
+ if( avail<offset ){
71354
+ /* pC->aRow does not have to hold the entire row, but it does at least
71355
+ ** need to cover the header of the record. If pC->aRow does not contain
71356
+ ** the complete header, then set it to zero, forcing the header to be
71357
+ ** dynamically allocated. */
71358
+ pC->aRow = 0;
71359
+ pC->szRow = 0;
71360
+ }
71361
+
71362
+ /* The following goto is an optimization. It can be omitted and
71363
+ ** everything will still work. But OP_Column is measurably faster
71364
+ ** by skipping the subsequent conditional, which is always true.
71365
+ */
71366
+ assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
71367
+ goto op_column_read_header;
7128471368
}
7128571369
7128671370
/* Make sure at least the first p2+1 entries of the header have been
7128771371
** parsed and valid information is in aOffset[] and pC->aType[].
7128871372
*/
7128971373
if( pC->nHdrParsed<=p2 ){
7129071374
/* If there is more header available for parsing in the record, try
7129171375
** to extract additional fields up through the p2+1-th field
7129271376
*/
71377
+ op_column_read_header:
7129371378
if( pC->iHdrOffset<aOffset[0] ){
7129471379
/* Make sure zData points to enough of the record to cover the header. */
7129571380
if( pC->aRow==0 ){
7129671381
memset(&sMem, 0, sizeof(sMem));
7129771382
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
@@ -71332,19 +71417,20 @@
7133271417
if( pC->aRow==0 ){
7133371418
sqlite3VdbeMemRelease(&sMem);
7133471419
sMem.flags = MEM_Null;
7133571420
}
7133671421
71337
- /* If we have read more header data than was contained in the header,
71338
- ** or if the end of the last field appears to be past the end of the
71339
- ** record, or if the end of the last field appears to be before the end
71340
- ** of the record (when all fields present), then we must be dealing
71341
- ** with a corrupt database.
71422
+ /* The record is corrupt if any of the following are true:
71423
+ ** (1) the bytes of the header extend past the declared header size
71424
+ ** (zHdr>zEndHdr)
71425
+ ** (2) the entire header was used but not all data was used
71426
+ ** (zHdr==zEndHdr && offset!=pC->payloadSize)
71427
+ ** (3) the end of the data extends beyond the end of the record.
71428
+ ** (offset > pC->payloadSize)
7134271429
*/
71343
- if( (zHdr > zEndHdr)
71430
+ if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
7134471431
|| (offset > pC->payloadSize)
71345
- || (zHdr==zEndHdr && offset!=pC->payloadSize)
7134671432
){
7134771433
rc = SQLITE_CORRUPT_BKPT;
7134871434
goto op_column_error;
7134971435
}
7135071436
}
@@ -71531,11 +71617,11 @@
7153171617
** out how much space is required for the new record.
7153271618
*/
7153371619
pRec = pLast;
7153471620
do{
7153571621
assert( memIsValid(pRec) );
71536
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
71622
+ pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
7153771623
len = sqlite3VdbeSerialTypeLen(serial_type);
7153871624
if( pRec->flags & MEM_Zero ){
7153971625
if( nData ){
7154071626
sqlite3VdbeMemExpandBlob(pRec);
7154171627
}else{
@@ -71580,11 +71666,11 @@
7158071666
i = putVarint32(zNewRecord, nHdr);
7158171667
j = nHdr;
7158271668
assert( pData0<=pLast );
7158371669
pRec = pData0;
7158471670
do{
71585
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
71671
+ serial_type = pRec->uTemp;
7158671672
i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
7158771673
j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
7158871674
}while( (++pRec)<=pLast );
7158971675
assert( i==nHdr );
7159071676
assert( j==nByte );
@@ -72205,14 +72291,10 @@
7220572291
rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
7220672292
pCur->pKeyInfo = pKeyInfo;
7220772293
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
7220872294
sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
7220972295
72210
- /* Since it performs no memory allocation or IO, the only value that
72211
- ** sqlite3BtreeCursor() may return is SQLITE_OK. */
72212
- assert( rc==SQLITE_OK );
72213
-
7221472296
/* Set the VdbeCursor.isTable variable. Previous versions of
7221572297
** SQLite used to check if the root-page flags were sane at this point
7221672298
** and report database corruption if they were not, but this check has
7221772299
** since moved into the btree layer. */
7221872300
pCur->isTable = pOp->p4type!=P4_KEYINFO;
@@ -72483,11 +72565,10 @@
7248372565
pIn3 = &aMem[pOp->p3];
7248472566
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
7248572567
applyNumericAffinity(pIn3, 0);
7248672568
}
7248772569
iKey = sqlite3VdbeIntValue(pIn3);
72488
- pC->rowidIsValid = 0;
7248972570
7249072571
/* If the P3 value could not be converted into an integer without
7249172572
** loss of information, then special processing is required... */
7249272573
if( (pIn3->flags & MEM_Int)==0 ){
7249372574
if( (pIn3->flags & MEM_Real)==0 ){
@@ -72519,17 +72600,14 @@
7251972600
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
7252072601
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
7252172602
}
7252272603
}
7252372604
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
72605
+ pC->movetoTarget = iKey; /* Used by OP_Delete */
7252472606
if( rc!=SQLITE_OK ){
7252572607
goto abort_due_to_error;
7252672608
}
72527
- if( res==0 ){
72528
- pC->rowidIsValid = 1;
72529
- pC->lastRowid = iKey;
72530
- }
7253172609
}else{
7253272610
nField = pOp->p4.i;
7253372611
assert( pOp->p4type==P4_INT32 );
7253472612
assert( nField>0 );
7253572613
r.pKeyInfo = pC->pKeyInfo;
@@ -72555,11 +72633,10 @@
7255572633
ExpandBlob(r.aMem);
7255672634
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
7255772635
if( rc!=SQLITE_OK ){
7255872636
goto abort_due_to_error;
7255972637
}
72560
- pC->rowidIsValid = 0;
7256172638
}
7256272639
pC->deferredMoveto = 0;
7256372640
pC->cacheStatus = CACHE_STALE;
7256472641
#ifdef SQLITE_TEST
7256572642
sqlite3_search_count++;
@@ -72567,21 +72644,19 @@
7256772644
if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
7256872645
if( res<0 || (res==0 && oc==OP_SeekGT) ){
7256972646
res = 0;
7257072647
rc = sqlite3BtreeNext(pC->pCursor, &res);
7257172648
if( rc!=SQLITE_OK ) goto abort_due_to_error;
72572
- pC->rowidIsValid = 0;
7257372649
}else{
7257472650
res = 0;
7257572651
}
7257672652
}else{
7257772653
assert( oc==OP_SeekLT || oc==OP_SeekLE );
7257872654
if( res>0 || (res==0 && oc==OP_SeekLT) ){
7257972655
res = 0;
7258072656
rc = sqlite3BtreePrevious(pC->pCursor, &res);
7258172657
if( rc!=SQLITE_OK ) goto abort_due_to_error;
72582
- pC->rowidIsValid = 0;
7258372658
}else{
7258472659
/* res might be negative because the table is empty. Check to
7258572660
** see if this is the case.
7258672661
*/
7258772662
res = sqlite3BtreeEof(pC->pCursor);
@@ -72614,11 +72689,10 @@
7261472689
assert( pC->pCursor!=0 );
7261572690
assert( pC->isTable );
7261672691
pC->nullRow = 0;
7261772692
pIn2 = &aMem[pOp->p2];
7261872693
pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
72619
- pC->rowidIsValid = 0;
7262072694
pC->deferredMoveto = 1;
7262172695
break;
7262272696
}
7262372697
7262472698
@@ -72800,19 +72874,17 @@
7280072874
pCrsr = pC->pCursor;
7280172875
assert( pCrsr!=0 );
7280272876
res = 0;
7280372877
iKey = pIn3->u.i;
7280472878
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
72805
- pC->lastRowid = pIn3->u.i;
72806
- pC->rowidIsValid = res==0 ?1:0;
72879
+ pC->movetoTarget = iKey; /* Used by OP_Delete */
7280772880
pC->nullRow = 0;
7280872881
pC->cacheStatus = CACHE_STALE;
7280972882
pC->deferredMoveto = 0;
7281072883
VdbeBranchTaken(res!=0,2);
7281172884
if( res!=0 ){
7281272885
pc = pOp->p2 - 1;
72813
- assert( pC->rowidIsValid==0 );
7281472886
}
7281572887
pC->seekResult = res;
7281672888
break;
7281772889
}
7281872890
@@ -72942,36 +73014,24 @@
7294273014
** largest possible integer (9223372036854775807) then the database
7294373015
** engine starts picking positive candidate ROWIDs at random until
7294473016
** it finds one that is not previously used. */
7294573017
assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is
7294673018
** an AUTOINCREMENT table. */
72947
- /* on the first attempt, simply do one more than previous */
72948
- v = lastRowid;
72949
- v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
72950
- v++; /* ensure non-zero */
7295173019
cnt = 0;
72952
- while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
73020
+ do{
73021
+ sqlite3_randomness(sizeof(v), &v);
73022
+ v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */
73023
+ }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
7295373024
0, &res))==SQLITE_OK)
7295473025
&& (res==0)
72955
- && (++cnt<100)){
72956
- /* collision - try another random rowid */
72957
- sqlite3_randomness(sizeof(v), &v);
72958
- if( cnt<5 ){
72959
- /* try "small" random rowids for the initial attempts */
72960
- v &= 0xffffff;
72961
- }else{
72962
- v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
72963
- }
72964
- v++; /* ensure non-zero */
72965
- }
73026
+ && (++cnt<100));
7296673027
if( rc==SQLITE_OK && res==0 ){
7296773028
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
7296873029
goto abort_due_to_error;
7296973030
}
7297073031
assert( v>0 ); /* EV: R-40812-03570 */
7297173032
}
72972
- pC->rowidIsValid = 0;
7297373033
pC->deferredMoveto = 0;
7297473034
pC->cacheStatus = CACHE_STALE;
7297573035
}
7297673036
pOut->u.i = v;
7297773037
break;
@@ -73072,11 +73132,10 @@
7307273132
}
7307373133
rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
7307473134
pData->z, pData->n, nZero,
7307573135
(pOp->p5 & OPFLAG_APPEND)!=0, seekResult
7307673136
);
73077
- pC->rowidIsValid = 0;
7307873137
pC->deferredMoveto = 0;
7307973138
pC->cacheStatus = CACHE_STALE;
7308073139
7308173140
/* Invoke the update-hook if required. */
7308273141
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
@@ -73109,37 +73168,36 @@
7310973168
** pointing to. The update hook will be invoked, if it exists.
7311073169
** If P4 is not NULL then the P1 cursor must have been positioned
7311173170
** using OP_NotFound prior to invoking this opcode.
7311273171
*/
7311373172
case OP_Delete: {
73114
- i64 iKey;
7311573173
VdbeCursor *pC;
7311673174
7311773175
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
7311873176
pC = p->apCsr[pOp->p1];
7311973177
assert( pC!=0 );
7312073178
assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
73121
- iKey = pC->lastRowid; /* Only used for the update hook */
73122
-
73123
- /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
73124
- ** OP_Column on the same table without any intervening operations that
73125
- ** might move or invalidate the cursor. Hence cursor pC is always pointing
73126
- ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
73127
- ** below is always a no-op and cannot fail. We will run it anyhow, though,
73128
- ** to guard against future changes to the code generator.
73129
- **/
7313073179
assert( pC->deferredMoveto==0 );
73131
- rc = sqlite3VdbeCursorMoveto(pC);
73132
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
7313373180
73181
+#ifdef SQLITE_DEBUG
73182
+ /* The seek operation that positioned the cursor prior to OP_Delete will
73183
+ ** have also set the pC->movetoTarget field to the rowid of the row that
73184
+ ** is being deleted */
73185
+ if( pOp->p4.z && pC->isTable ){
73186
+ i64 iKey = 0;
73187
+ sqlite3BtreeKeySize(pC->pCursor, &iKey);
73188
+ assert( pC->movetoTarget==iKey );
73189
+ }
73190
+#endif
73191
+
7313473192
rc = sqlite3BtreeDelete(pC->pCursor);
7313573193
pC->cacheStatus = CACHE_STALE;
7313673194
7313773195
/* Invoke the update-hook if required. */
7313873196
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
7313973197
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
73140
- db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
73198
+ db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
7314173199
assert( pC->iDb>=0 );
7314273200
}
7314373201
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
7314473202
break;
7314573203
}
@@ -73188,23 +73246,32 @@
7318873246
pc = pOp->p2-1;
7318973247
}
7319073248
break;
7319173249
};
7319273250
73193
-/* Opcode: SorterData P1 P2 * * *
73251
+/* Opcode: SorterData P1 P2 P3 * *
7319473252
** Synopsis: r[P2]=data
7319573253
**
7319673254
** Write into register P2 the current sorter data for sorter cursor P1.
73255
+** Then clear the column header cache on cursor P3.
73256
+**
73257
+** This opcode is normally use to move a record out of the sorter and into
73258
+** a register that is the source for a pseudo-table cursor created using
73259
+** OpenPseudo. That pseudo-table cursor is the one that is identified by
73260
+** parameter P3. Clearing the P3 column cache as part of this opcode saves
73261
+** us from having to issue a separate NullRow instruction to clear that cache.
7319773262
*/
7319873263
case OP_SorterData: {
7319973264
VdbeCursor *pC;
7320073265
7320173266
pOut = &aMem[pOp->p2];
7320273267
pC = p->apCsr[pOp->p1];
7320373268
assert( isSorter(pC) );
7320473269
rc = sqlite3VdbeSorterRowkey(pC, pOut);
7320573270
assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
73271
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73272
+ p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
7320673273
break;
7320773274
}
7320873275
7320973276
/* Opcode: RowData P1 P2 * * *
7321073277
** Synopsis: r[P2]=data
@@ -73247,20 +73314,24 @@
7324773314
assert( pC!=0 );
7324873315
assert( pC->nullRow==0 );
7324973316
assert( pC->pseudoTableReg==0 );
7325073317
assert( pC->pCursor!=0 );
7325173318
pCrsr = pC->pCursor;
73252
- assert( sqlite3BtreeCursorIsValid(pCrsr) );
7325373319
7325473320
/* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
7325573321
** OP_Rewind/Op_Next with no intervening instructions that might invalidate
73256
- ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
73257
- ** a no-op and can never fail. But we leave it in place as a safety.
73322
+ ** the cursor. If this where not the case, on of the following assert()s
73323
+ ** would fail. Should this ever change (because of changes in the code
73324
+ ** generator) then the fix would be to insert a call to
73325
+ ** sqlite3VdbeCursorMoveto().
7325873326
*/
7325973327
assert( pC->deferredMoveto==0 );
73328
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
73329
+#if 0 /* Not required due to the previous to assert() statements */
7326073330
rc = sqlite3VdbeCursorMoveto(pC);
73261
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73331
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
73332
+#endif
7326273333
7326373334
if( pC->isTable==0 ){
7326473335
assert( !pC->isTable );
7326573336
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
7326673337
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -73273,11 +73344,12 @@
7327373344
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
7327473345
if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
7327573346
goto too_big;
7327673347
}
7327773348
}
73278
- if( sqlite3VdbeMemClearAndResize(pOut, n) ){
73349
+ testcase( n==0 );
73350
+ if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
7327973351
goto no_mem;
7328073352
}
7328173353
pOut->n = n;
7328273354
MemSetTypeFlag(pOut, MEM_Blob);
7328373355
if( pC->isTable==0 ){
@@ -73324,18 +73396,14 @@
7332473396
rc = pModule->xRowid(pC->pVtabCursor, &v);
7332573397
sqlite3VtabImportErrmsg(p, pVtab);
7332673398
#endif /* SQLITE_OMIT_VIRTUALTABLE */
7332773399
}else{
7332873400
assert( pC->pCursor!=0 );
73329
- rc = sqlite3VdbeCursorMoveto(pC);
73401
+ rc = sqlite3VdbeCursorRestore(pC);
7333073402
if( rc ) goto abort_due_to_error;
73331
- if( pC->rowidIsValid ){
73332
- v = pC->lastRowid;
73333
- }else{
73334
- rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73335
- assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
73336
- }
73403
+ rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73404
+ assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
7333773405
}
7333873406
pOut->u.i = v;
7333973407
break;
7334073408
}
7334173409
@@ -73350,11 +73418,10 @@
7335073418
7335173419
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
7335273420
pC = p->apCsr[pOp->p1];
7335373421
assert( pC!=0 );
7335473422
pC->nullRow = 1;
73355
- pC->rowidIsValid = 0;
7335673423
pC->cacheStatus = CACHE_STALE;
7335773424
if( pC->pCursor ){
7335873425
sqlite3BtreeClearCursor(pC->pCursor);
7335973426
}
7336073427
break;
@@ -73384,11 +73451,10 @@
7338473451
res = 0;
7338573452
assert( pCrsr!=0 );
7338673453
rc = sqlite3BtreeLast(pCrsr, &res);
7338773454
pC->nullRow = (u8)res;
7338873455
pC->deferredMoveto = 0;
73389
- pC->rowidIsValid = 0;
7339073456
pC->cacheStatus = CACHE_STALE;
7339173457
#ifdef SQLITE_DEBUG
7339273458
pC->seekOp = OP_Last;
7339373459
#endif
7339473460
if( pOp->p2>0 ){
@@ -73451,11 +73517,10 @@
7345173517
pCrsr = pC->pCursor;
7345273518
assert( pCrsr );
7345373519
rc = sqlite3BtreeFirst(pCrsr, &res);
7345473520
pC->deferredMoveto = 0;
7345573521
pC->cacheStatus = CACHE_STALE;
73456
- pC->rowidIsValid = 0;
7345773522
}
7345873523
pC->nullRow = (u8)res;
7345973524
assert( pOp->p2>0 && pOp->p2<p->nOp );
7346073525
VdbeBranchTaken(res!=0,2);
7346173526
if( res ){
@@ -73577,11 +73642,10 @@
7357773642
sqlite3_search_count++;
7357873643
#endif
7357973644
}else{
7358073645
pC->nullRow = 1;
7358173646
}
73582
- pC->rowidIsValid = 0;
7358373647
goto check_for_interrupt;
7358473648
}
7358573649
7358673650
/* Opcode: IdxInsert P1 P2 P3 * P5
7358773651
** Synopsis: key=r[P2]
@@ -73693,14 +73757,20 @@
7369373757
pC = p->apCsr[pOp->p1];
7369473758
assert( pC!=0 );
7369573759
pCrsr = pC->pCursor;
7369673760
assert( pCrsr!=0 );
7369773761
pOut->flags = MEM_Null;
73698
- rc = sqlite3VdbeCursorMoveto(pC);
73699
- if( NEVER(rc) ) goto abort_due_to_error;
73762
+ assert( pC->isTable==0 );
7370073763
assert( pC->deferredMoveto==0 );
73701
- assert( pC->isTable==0 );
73764
+
73765
+ /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
73766
+ ** out from under the cursor. That will never happend for an IdxRowid
73767
+ ** opcode, hence the NEVER() arround the check of the return value.
73768
+ */
73769
+ rc = sqlite3VdbeCursorRestore(pC);
73770
+ if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73771
+
7370273772
if( !pC->nullRow ){
7370373773
rowid = 0; /* Not needed. Only used to silence a warning. */
7370473774
rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
7370573775
if( rc!=SQLITE_OK ){
7370673776
goto abort_due_to_error;
@@ -74556,18 +74626,13 @@
7455674626
ctx.pMem = pMem = &aMem[pOp->p3];
7455774627
pMem->n++;
7455874628
sqlite3VdbeMemInit(&t, db, MEM_Null);
7455974629
ctx.pOut = &t;
7456074630
ctx.isError = 0;
74561
- ctx.pColl = 0;
74631
+ ctx.pVdbe = p;
74632
+ ctx.iOp = pc;
7456274633
ctx.skipFlag = 0;
74563
- if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
74564
- assert( pOp>p->aOp );
74565
- assert( pOp[-1].p4type==P4_COLLSEQ );
74566
- assert( pOp[-1].opcode==OP_CollSeq );
74567
- ctx.pColl = pOp[-1].p4.pColl;
74568
- }
7456974634
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
7457074635
if( ctx.isError ){
7457174636
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
7457274637
rc = ctx.isError;
7457374638
}
@@ -78162,11 +78227,11 @@
7816278227
if( rc==SQLITE_OK ){
7816378228
#if SQLITE_MAX_WORKER_THREADS
7816478229
assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
7816578230
if( pSorter->bUseThreads ){
7816678231
int iTask;
78167
- PmaReader *pReadr;
78232
+ PmaReader *pReadr = 0;
7816878233
SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
7816978234
rc = vdbeSortAllocUnpacked(pLast);
7817078235
if( rc==SQLITE_OK ){
7817178236
pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
7817278237
pSorter->pReader = pReadr;
@@ -81597,10 +81662,11 @@
8159781662
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
8159881663
pNew->addrOpenEphm[0] = -1;
8159981664
pNew->addrOpenEphm[1] = -1;
8160081665
pNew->nSelectRow = p->nSelectRow;
8160181666
pNew->pWith = withDup(db, p->pWith);
81667
+ sqlite3SelectSetName(pNew, p->zSelName);
8160281668
return pNew;
8160381669
}
8160481670
#else
8160581671
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
8160681672
assert( p==0 );
@@ -81739,36 +81805,44 @@
8173981805
}
8174081806
8174181807
/*
8174281808
** These routines are Walker callbacks. Walker.u.pi is a pointer
8174381809
** to an integer. These routines are checking an expression to see
81744
-** if it is a constant. Set *Walker.u.pi to 0 if the expression is
81810
+** if it is a constant. Set *Walker.u.i to 0 if the expression is
8174581811
** not constant.
8174681812
**
8174781813
** These callback routines are used to implement the following:
8174881814
**
81749
-** sqlite3ExprIsConstant()
81750
-** sqlite3ExprIsConstantNotJoin()
81751
-** sqlite3ExprIsConstantOrFunction()
81815
+** sqlite3ExprIsConstant() pWalker->u.i==1
81816
+** sqlite3ExprIsConstantNotJoin() pWalker->u.i==2
81817
+** sqlite3ExprIsConstantOrFunction() pWalker->u.i==3 or 4
8175281818
**
81819
+** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
81820
+** in a CREATE TABLE statement. The Walker.u.i value is 4 when parsing
81821
+** an existing schema and 3 when processing a new statement. A bound
81822
+** parameter raises an error for new statements, but is silently converted
81823
+** to NULL for existing schemas. This allows sqlite_master tables that
81824
+** contain a bound parameter because they were generated by older versions
81825
+** of SQLite to be parsed by newer versions of SQLite without raising a
81826
+** malformed schema error.
8175381827
*/
8175481828
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
8175581829
81756
- /* If pWalker->u.i is 3 then any term of the expression that comes from
81830
+ /* If pWalker->u.i is 2 then any term of the expression that comes from
8175781831
** the ON or USING clauses of a join disqualifies the expression
8175881832
** from being considered constant. */
81759
- if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){
81833
+ if( pWalker->u.i==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
8176081834
pWalker->u.i = 0;
8176181835
return WRC_Abort;
8176281836
}
8176381837
8176481838
switch( pExpr->op ){
8176581839
/* Consider functions to be constant if all their arguments are constant
81766
- ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST
81840
+ ** and either pWalker->u.i==3 or 4 or the function as the SQLITE_FUNC_CONST
8176781841
** flag. */
8176881842
case TK_FUNCTION:
81769
- if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){
81843
+ if( pWalker->u.i>=3 || ExprHasProperty(pExpr,EP_Constant) ){
8177081844
return WRC_Continue;
8177181845
}
8177281846
/* Fall through */
8177381847
case TK_ID:
8177481848
case TK_COLUMN:
@@ -81778,10 +81852,23 @@
8177881852
testcase( pExpr->op==TK_COLUMN );
8177981853
testcase( pExpr->op==TK_AGG_FUNCTION );
8178081854
testcase( pExpr->op==TK_AGG_COLUMN );
8178181855
pWalker->u.i = 0;
8178281856
return WRC_Abort;
81857
+ case TK_VARIABLE:
81858
+ if( pWalker->u.i==4 ){
81859
+ /* Silently convert bound parameters that appear inside of CREATE
81860
+ ** statements into a NULL when parsing the CREATE statement text out
81861
+ ** of the sqlite_master table */
81862
+ pExpr->op = TK_NULL;
81863
+ }else if( pWalker->u.i==3 ){
81864
+ /* A bound parameter in a CREATE statement that originates from
81865
+ ** sqlite3_prepare() causes an error */
81866
+ pWalker->u.i = 0;
81867
+ return WRC_Abort;
81868
+ }
81869
+ /* Fall through */
8178381870
default:
8178481871
testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
8178581872
testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
8178681873
return WRC_Continue;
8178781874
}
@@ -81818,11 +81905,11 @@
8181881905
** that does no originate from the ON or USING clauses of a join.
8181981906
** Return 0 if it involves variables or function calls or terms from
8182081907
** an ON or USING clause.
8182181908
*/
8182281909
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
81823
- return exprIsConst(p, 3);
81910
+ return exprIsConst(p, 2);
8182481911
}
8182581912
8182681913
/*
8182781914
** Walk an expression tree. Return 1 if the expression is constant
8182881915
** or a function call with constant arguments. Return and 0 if there
@@ -81830,12 +81917,13 @@
8183081917
**
8183181918
** For the purposes of this function, a double-quoted string (ex: "abc")
8183281919
** is considered a variable but a single-quoted string (ex: 'abc') is
8183381920
** a constant.
8183481921
*/
81835
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){
81836
- return exprIsConst(p, 2);
81922
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
81923
+ assert( isInit==0 || isInit==1 );
81924
+ return exprIsConst(p, 3+isInit);
8183781925
}
8183881926
8183981927
/*
8184081928
** If the expression p codes a constant integer that is small enough
8184181929
** to fit in a 32-bit integer, return 1 and put the value of the integer
@@ -83741,94 +83829,90 @@
8374183829
iMem = ++pParse->nMem;
8374283830
sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
8374383831
exprToRegister(pExpr, iMem);
8374483832
}
8374583833
83746
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
83834
+#ifdef SQLITE_DEBUG
8374783835
/*
8374883836
** Generate a human-readable explanation of an expression tree.
8374983837
*/
83750
-SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
83751
- int op; /* The opcode being coded */
83838
+SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
8375283839
const char *zBinOp = 0; /* Binary operator */
8375383840
const char *zUniOp = 0; /* Unary operator */
83841
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
8375483842
if( pExpr==0 ){
83755
- op = TK_NULL;
83756
- }else{
83757
- op = pExpr->op;
83843
+ sqlite3TreeViewLine(pView, "nil");
83844
+ sqlite3TreeViewPop(pView);
83845
+ return;
8375883846
}
83759
- switch( op ){
83847
+ switch( pExpr->op ){
8376083848
case TK_AGG_COLUMN: {
83761
- sqlite3ExplainPrintf(pOut, "AGG{%d:%d}",
83849
+ sqlite3TreeViewLine(pView, "AGG{%d:%d}",
8376283850
pExpr->iTable, pExpr->iColumn);
8376383851
break;
8376483852
}
8376583853
case TK_COLUMN: {
8376683854
if( pExpr->iTable<0 ){
8376783855
/* This only happens when coding check constraints */
83768
- sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
83856
+ sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
8376983857
}else{
83770
- sqlite3ExplainPrintf(pOut, "{%d:%d}",
83858
+ sqlite3TreeViewLine(pView, "{%d:%d}",
8377183859
pExpr->iTable, pExpr->iColumn);
8377283860
}
8377383861
break;
8377483862
}
8377583863
case TK_INTEGER: {
8377683864
if( pExpr->flags & EP_IntValue ){
83777
- sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue);
83865
+ sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
8377883866
}else{
83779
- sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken);
83867
+ sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
8378083868
}
8378183869
break;
8378283870
}
8378383871
#ifndef SQLITE_OMIT_FLOATING_POINT
8378483872
case TK_FLOAT: {
83785
- sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
83873
+ sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
8378683874
break;
8378783875
}
8378883876
#endif
8378983877
case TK_STRING: {
83790
- sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
83878
+ sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
8379183879
break;
8379283880
}
8379383881
case TK_NULL: {
83794
- sqlite3ExplainPrintf(pOut,"NULL");
83882
+ sqlite3TreeViewLine(pView,"NULL");
8379583883
break;
8379683884
}
8379783885
#ifndef SQLITE_OMIT_BLOB_LITERAL
8379883886
case TK_BLOB: {
83799
- sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
83887
+ sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
8380083888
break;
8380183889
}
8380283890
#endif
8380383891
case TK_VARIABLE: {
83804
- sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)",
83805
- pExpr->u.zToken, pExpr->iColumn);
83892
+ sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
83893
+ pExpr->u.zToken, pExpr->iColumn);
8380683894
break;
8380783895
}
8380883896
case TK_REGISTER: {
83809
- sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
83897
+ sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
8381083898
break;
8381183899
}
8381283900
case TK_AS: {
83813
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
83901
+ sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
83902
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
83903
+ break;
83904
+ }
83905
+ case TK_ID: {
83906
+ sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
8381483907
break;
8381583908
}
8381683909
#ifndef SQLITE_OMIT_CAST
8381783910
case TK_CAST: {
8381883911
/* Expressions of the form: CAST(pLeft AS token) */
83819
- const char *zAff = "unk";
83820
- switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){
83821
- case SQLITE_AFF_TEXT: zAff = "TEXT"; break;
83822
- case SQLITE_AFF_NONE: zAff = "NONE"; break;
83823
- case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break;
83824
- case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break;
83825
- case SQLITE_AFF_REAL: zAff = "REAL"; break;
83826
- }
83827
- sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff);
83828
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
83829
- sqlite3ExplainPrintf(pOut, ")");
83912
+ sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
83913
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
8383083914
break;
8383183915
}
8383283916
#endif /* SQLITE_OMIT_CAST */
8383383917
case TK_LT: zBinOp = "LT"; break;
8383483918
case TK_LE: zBinOp = "LE"; break;
@@ -83848,21 +83932,22 @@
8384883932
case TK_BITOR: zBinOp = "BITOR"; break;
8384983933
case TK_SLASH: zBinOp = "DIV"; break;
8385083934
case TK_LSHIFT: zBinOp = "LSHIFT"; break;
8385183935
case TK_RSHIFT: zBinOp = "RSHIFT"; break;
8385283936
case TK_CONCAT: zBinOp = "CONCAT"; break;
83937
+ case TK_DOT: zBinOp = "DOT"; break;
8385383938
8385483939
case TK_UMINUS: zUniOp = "UMINUS"; break;
8385583940
case TK_UPLUS: zUniOp = "UPLUS"; break;
8385683941
case TK_BITNOT: zUniOp = "BITNOT"; break;
8385783942
case TK_NOT: zUniOp = "NOT"; break;
8385883943
case TK_ISNULL: zUniOp = "ISNULL"; break;
8385983944
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
8386083945
8386183946
case TK_COLLATE: {
83862
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
83863
- sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
83947
+ sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
83948
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
8386483949
break;
8386583950
}
8386683951
8386783952
case TK_AGG_FUNCTION:
8386883953
case TK_FUNCTION: {
@@ -83870,45 +83955,40 @@
8387083955
if( ExprHasProperty(pExpr, EP_TokenOnly) ){
8387183956
pFarg = 0;
8387283957
}else{
8387383958
pFarg = pExpr->x.pList;
8387483959
}
83875
- if( op==TK_AGG_FUNCTION ){
83876
- sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
83960
+ if( pExpr->op==TK_AGG_FUNCTION ){
83961
+ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
8387783962
pExpr->op2, pExpr->u.zToken);
8387883963
}else{
83879
- sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
83964
+ sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
8388083965
}
8388183966
if( pFarg ){
83882
- sqlite3ExplainExprList(pOut, pFarg);
83967
+ sqlite3TreeViewExprList(pView, pFarg, 0, 0);
8388383968
}
83884
- sqlite3ExplainPrintf(pOut, ")");
8388583969
break;
8388683970
}
8388783971
#ifndef SQLITE_OMIT_SUBQUERY
8388883972
case TK_EXISTS: {
83889
- sqlite3ExplainPrintf(pOut, "EXISTS(");
83890
- sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
83891
- sqlite3ExplainPrintf(pOut,")");
83973
+ sqlite3TreeViewLine(pView, "EXISTS-expr");
83974
+ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
8389283975
break;
8389383976
}
8389483977
case TK_SELECT: {
83895
- sqlite3ExplainPrintf(pOut, "(");
83896
- sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
83897
- sqlite3ExplainPrintf(pOut, ")");
83978
+ sqlite3TreeViewLine(pView, "SELECT-expr");
83979
+ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
8389883980
break;
8389983981
}
8390083982
case TK_IN: {
83901
- sqlite3ExplainPrintf(pOut, "IN(");
83902
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
83903
- sqlite3ExplainPrintf(pOut, ",");
83983
+ sqlite3TreeViewLine(pView, "IN");
83984
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
8390483985
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
83905
- sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
83986
+ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
8390683987
}else{
83907
- sqlite3ExplainExprList(pOut, pExpr->x.pList);
83988
+ sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
8390883989
}
83909
- sqlite3ExplainPrintf(pOut, ")");
8391083990
break;
8391183991
}
8391283992
#endif /* SQLITE_OMIT_SUBQUERY */
8391383993
8391483994
/*
@@ -83924,17 +84004,14 @@
8392484004
*/
8392584005
case TK_BETWEEN: {
8392684006
Expr *pX = pExpr->pLeft;
8392784007
Expr *pY = pExpr->x.pList->a[0].pExpr;
8392884008
Expr *pZ = pExpr->x.pList->a[1].pExpr;
83929
- sqlite3ExplainPrintf(pOut, "BETWEEN(");
83930
- sqlite3ExplainExpr(pOut, pX);
83931
- sqlite3ExplainPrintf(pOut, ",");
83932
- sqlite3ExplainExpr(pOut, pY);
83933
- sqlite3ExplainPrintf(pOut, ",");
83934
- sqlite3ExplainExpr(pOut, pZ);
83935
- sqlite3ExplainPrintf(pOut, ")");
84009
+ sqlite3TreeViewLine(pView, "BETWEEN");
84010
+ sqlite3TreeViewExpr(pView, pX, 1);
84011
+ sqlite3TreeViewExpr(pView, pY, 1);
84012
+ sqlite3TreeViewExpr(pView, pZ, 0);
8393684013
break;
8393784014
}
8393884015
case TK_TRIGGER: {
8393984016
/* If the opcode is TK_TRIGGER, then the expression is a reference
8394084017
** to a column in the new.* or old.* pseudo-tables available to
@@ -83941,19 +84018,18 @@
8394184018
** trigger programs. In this case Expr.iTable is set to 1 for the
8394284019
** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
8394384020
** is set to the column of the pseudo-table to read, or to -1 to
8394484021
** read the rowid field.
8394584022
*/
83946
- sqlite3ExplainPrintf(pOut, "%s(%d)",
84023
+ sqlite3TreeViewLine(pView, "%s(%d)",
8394784024
pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
8394884025
break;
8394984026
}
8395084027
case TK_CASE: {
83951
- sqlite3ExplainPrintf(pOut, "CASE(");
83952
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
83953
- sqlite3ExplainPrintf(pOut, ",");
83954
- sqlite3ExplainExprList(pOut, pExpr->x.pList);
84028
+ sqlite3TreeViewLine(pView, "CASE");
84029
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
84030
+ sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
8395584031
break;
8395684032
}
8395784033
#ifndef SQLITE_OMIT_TRIGGER
8395884034
case TK_RAISE: {
8395984035
const char *zType = "unk";
@@ -83961,59 +84037,61 @@
8396184037
case OE_Rollback: zType = "rollback"; break;
8396284038
case OE_Abort: zType = "abort"; break;
8396384039
case OE_Fail: zType = "fail"; break;
8396484040
case OE_Ignore: zType = "ignore"; break;
8396584041
}
83966
- sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
84042
+ sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
8396784043
break;
8396884044
}
8396984045
#endif
84046
+ default: {
84047
+ sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
84048
+ break;
84049
+ }
8397084050
}
8397184051
if( zBinOp ){
83972
- sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
83973
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
83974
- sqlite3ExplainPrintf(pOut,",");
83975
- sqlite3ExplainExpr(pOut, pExpr->pRight);
83976
- sqlite3ExplainPrintf(pOut,")");
84052
+ sqlite3TreeViewLine(pView, "%s", zBinOp);
84053
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
84054
+ sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
8397784055
}else if( zUniOp ){
83978
- sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
83979
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
83980
- sqlite3ExplainPrintf(pOut,")");
83981
- }
83982
-}
83983
-#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
83984
-
83985
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
84056
+ sqlite3TreeViewLine(pView, "%s", zUniOp);
84057
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
84058
+ }
84059
+ sqlite3TreeViewPop(pView);
84060
+}
84061
+#endif /* SQLITE_DEBUG */
84062
+
84063
+#ifdef SQLITE_DEBUG
8398684064
/*
8398784065
** Generate a human-readable explanation of an expression list.
8398884066
*/
83989
-SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){
84067
+SQLITE_PRIVATE void sqlite3TreeViewExprList(
84068
+ TreeView *pView,
84069
+ const ExprList *pList,
84070
+ u8 moreToFollow,
84071
+ const char *zLabel
84072
+){
8399084073
int i;
83991
- if( pList==0 || pList->nExpr==0 ){
83992
- sqlite3ExplainPrintf(pOut, "(empty-list)");
83993
- return;
83994
- }else if( pList->nExpr==1 ){
83995
- sqlite3ExplainExpr(pOut, pList->a[0].pExpr);
84074
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
84075
+ if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
84076
+ if( pList==0 ){
84077
+ sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
8399684078
}else{
83997
- sqlite3ExplainPush(pOut);
84079
+ sqlite3TreeViewLine(pView, "%s", zLabel);
8399884080
for(i=0; i<pList->nExpr; i++){
83999
- sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
84000
- sqlite3ExplainPush(pOut);
84001
- sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
84002
- sqlite3ExplainPop(pOut);
84003
- if( pList->a[i].zName ){
84081
+ sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
84082
+#if 0
84083
+ if( pList->a[i].zName ){
8400484084
sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
8400584085
}
8400684086
if( pList->a[i].bSpanIsTab ){
8400784087
sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
8400884088
}
84009
- if( i<pList->nExpr-1 ){
84010
- sqlite3ExplainNL(pOut);
84011
- }
84089
+#endif
8401284090
}
84013
- sqlite3ExplainPop(pOut);
8401484091
}
84092
+ sqlite3TreeViewPop(pView);
8401584093
}
8401684094
#endif /* SQLITE_DEBUG */
8401784095
8401884096
/*
8401984097
** Generate code that pushes the value of every element of the given
@@ -87130,29 +87208,27 @@
8713087208
tRowcnt v;
8713187209
8713287210
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
8713387211
if( z==0 ) z = "";
8713487212
#else
87135
- if( NEVER(z==0) ) z = "";
87213
+ assert( z!=0 );
8713687214
#endif
8713787215
for(i=0; *z && i<nOut; i++){
8713887216
v = 0;
8713987217
while( (c=z[0])>='0' && c<='9' ){
8714087218
v = v*10 + c - '0';
8714187219
z++;
8714287220
}
8714387221
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87144
- if( aOut ){
87145
- aOut[i] = v;
87146
- }else
87222
+ if( aOut ) aOut[i] = v;
87223
+ if( aLog ) aLog[i] = sqlite3LogEst(v);
8714787224
#else
8714887225
assert( aOut==0 );
8714987226
UNUSED_PARAMETER(aOut);
87227
+ assert( aLog!=0 );
87228
+ aLog[i] = sqlite3LogEst(v);
8715087229
#endif
87151
- {
87152
- aLog[i] = sqlite3LogEst(v);
87153
- }
8715487230
if( *z==' ' ) z++;
8715587231
}
8715687232
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
8715787233
assert( pIndex!=0 );
8715887234
#else
@@ -87209,12 +87285,21 @@
8720987285
pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
8721087286
}
8721187287
z = argv[2];
8721287288
8721387289
if( pIndex ){
87290
+ int nCol = pIndex->nKeyCol+1;
87291
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87292
+ tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
87293
+ sizeof(tRowcnt) * nCol
87294
+ );
87295
+ if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
87296
+#else
87297
+ tRowcnt * const aiRowEst = 0;
87298
+#endif
8721487299
pIndex->bUnordered = 0;
87215
- decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
87300
+ decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
8721687301
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
8721787302
}else{
8721887303
Index fakeIdx;
8721987304
fakeIdx.szIdxRow = pTable->szTabRow;
8722087305
#ifdef SQLITE_ENABLE_COSTMULT
@@ -87269,29 +87354,42 @@
8726987354
** unique. */
8727087355
nCol = pIdx->nSampleCol-1;
8727187356
pIdx->aAvgEq[nCol] = 1;
8727287357
}
8727387358
for(iCol=0; iCol<nCol; iCol++){
87359
+ int nSample = pIdx->nSample;
8727487360
int i; /* Used to iterate through samples */
8727587361
tRowcnt sumEq = 0; /* Sum of the nEq values */
87276
- tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
8727787362
tRowcnt avgEq = 0;
87278
- tRowcnt nDLt = pFinal->anDLt[iCol];
87363
+ tRowcnt nRow; /* Number of rows in index */
87364
+ i64 nSum100 = 0; /* Number of terms contributing to sumEq */
87365
+ i64 nDist100; /* Number of distinct values in index */
87366
+
87367
+ if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
87368
+ nRow = pFinal->anLt[iCol];
87369
+ nDist100 = (i64)100 * pFinal->anDLt[iCol];
87370
+ nSample--;
87371
+ }else{
87372
+ nRow = pIdx->aiRowEst[0];
87373
+ nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
87374
+ }
8727987375
8728087376
/* Set nSum to the number of distinct (iCol+1) field prefixes that
87281
- ** occur in the stat4 table for this index before pFinal. Set
87282
- ** sumEq to the sum of the nEq values for column iCol for the same
87283
- ** set (adding the value only once where there exist duplicate
87284
- ** prefixes). */
87285
- for(i=0; i<(pIdx->nSample-1); i++){
87286
- if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
87377
+ ** occur in the stat4 table for this index. Set sumEq to the sum of
87378
+ ** the nEq values for column iCol for the same set (adding the value
87379
+ ** only once where there exist duplicate prefixes). */
87380
+ for(i=0; i<nSample; i++){
87381
+ if( i==(pIdx->nSample-1)
87382
+ || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol]
87383
+ ){
8728787384
sumEq += aSample[i].anEq[iCol];
87288
- nSum++;
87385
+ nSum100 += 100;
8728987386
}
8729087387
}
87291
- if( nDLt>nSum ){
87292
- avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
87388
+
87389
+ if( nDist100>nSum100 ){
87390
+ avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
8729387391
}
8729487392
if( avgEq==0 ) avgEq = 1;
8729587393
pIdx->aAvgEq[iCol] = avgEq;
8729687394
}
8729787395
}
@@ -87538,10 +87636,15 @@
8753887636
if( rc==SQLITE_OK ){
8753987637
int lookasideEnabled = db->lookaside.bEnabled;
8754087638
db->lookaside.bEnabled = 0;
8754187639
rc = loadStat4(db, sInfo.zDatabase);
8754287640
db->lookaside.bEnabled = lookasideEnabled;
87641
+ }
87642
+ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
87643
+ Index *pIdx = sqliteHashData(i);
87644
+ sqlite3_free(pIdx->aiRowEst);
87645
+ pIdx->aiRowEst = 0;
8754387646
}
8754487647
#endif
8754587648
8754687649
if( rc==SQLITE_NOMEM ){
8754787650
db->mallocFailed = 1;
@@ -88832,10 +88935,13 @@
8883288935
#endif
8883388936
if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
8883488937
sqlite3ExprDelete(db, p->pPartIdxWhere);
8883588938
sqlite3DbFree(db, p->zColAff);
8883688939
if( p->isResized ) sqlite3DbFree(db, p->azColl);
88940
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
88941
+ sqlite3_free(p->aiRowEst);
88942
+#endif
8883788943
sqlite3DbFree(db, p);
8883888944
}
8883988945
8884088946
/*
8884188947
** For the index called zIdxName which is found in the database iDb,
@@ -89633,11 +89739,11 @@
8963389739
Column *pCol;
8963489740
sqlite3 *db = pParse->db;
8963589741
p = pParse->pNewTable;
8963689742
if( p!=0 ){
8963789743
pCol = &(p->aCol[p->nCol-1]);
89638
- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
89744
+ if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
8963989745
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
8964089746
pCol->zName);
8964189747
}else{
8964289748
/* A copy of pExpr is used instead of the original, as pExpr contains
8964389749
** tokens that point to volatile memory. The 'span' of the expression
@@ -91141,11 +91247,11 @@
9114191247
pIndex->nKeyCol); VdbeCoverage(v);
9114291248
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
9114391249
}else{
9114491250
addr2 = sqlite3VdbeCurrentAddr(v);
9114591251
}
91146
- sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
91252
+ sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
9114791253
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
9114891254
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
9114991255
sqlite3ReleaseTempReg(pParse, regRecord);
9115091256
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
9115191257
sqlite3VdbeJumpHere(v, addr1);
@@ -94030,11 +94136,14 @@
9403094136
9403194137
/*
9403294138
** Return the collating function associated with a function.
9403394139
*/
9403494140
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
94035
- return context->pColl;
94141
+ VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
94142
+ assert( pOp->opcode==OP_CollSeq );
94143
+ assert( pOp->p4type==P4_COLLSEQ );
94144
+ return pOp->p4.pColl;
9403694145
}
9403794146
9403894147
/*
9403994148
** Indicate that the accumulator load should be skipped on this
9404094149
** iteration of the aggregate loop.
@@ -94575,14 +94684,16 @@
9457594684
** character is exactly one byte in size. Also, all characters are
9457694685
** able to participate in upper-case-to-lower-case mappings in EBCDIC
9457794686
** whereas only characters less than 0x80 do in ASCII.
9457894687
*/
9457994688
#if defined(SQLITE_EBCDIC)
94580
-# define sqlite3Utf8Read(A) (*((*A)++))
94581
-# define GlobUpperToLower(A) A = sqlite3UpperToLower[A]
94689
+# define sqlite3Utf8Read(A) (*((*A)++))
94690
+# define GlobUpperToLower(A) A = sqlite3UpperToLower[A]
94691
+# define GlobUpperToLowerAscii(A) A = sqlite3UpperToLower[A]
9458294692
#else
94583
-# define GlobUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
94693
+# define GlobUpperToLower(A) if( A<=0x7f ){ A = sqlite3UpperToLower[A]; }
94694
+# define GlobUpperToLowerAscii(A) A = sqlite3UpperToLower[A]
9458494695
#endif
9458594696
9458694697
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
9458794698
/* The correct SQL-92 behavior is for the LIKE operator to ignore
9458894699
** case. Thus 'a' LIKE 'A' would be true. */
@@ -94591,11 +94702,11 @@
9459194702
** is case sensitive causing 'a' LIKE 'A' to be false */
9459294703
static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
9459394704
9459494705
/*
9459594706
** Compare two UTF-8 strings for equality where the first string can
94596
-** potentially be a "glob" expression. Return true (1) if they
94707
+** potentially be a "glob" or "like" expression. Return true (1) if they
9459794708
** are the same and false (0) if they are different.
9459894709
**
9459994710
** Globbing rules:
9460094711
**
9460194712
** '*' Matches any sequence of zero or more characters.
@@ -94611,120 +94722,147 @@
9461194722
** in the list by making it the first character after '[' or '^'. A
9461294723
** range of characters can be specified using '-'. Example:
9461394724
** "[a-z]" matches any single lower-case letter. To match a '-', make
9461494725
** it the last character in the list.
9461594726
**
94727
+** Like matching rules:
94728
+**
94729
+** '%' Matches any sequence of zero or more characters
94730
+**
94731
+*** '_' Matches any one character
94732
+**
94733
+** Ec Where E is the "esc" character and c is any other
94734
+** character, including '%', '_', and esc, match exactly c.
94735
+**
94736
+** The comments through this routine usually assume glob matching.
94737
+**
9461694738
** This routine is usually quick, but can be N**2 in the worst case.
94617
-**
94618
-** Hints: to match '*' or '?', put them in "[]". Like this:
94619
-**
94620
-** abc[*]xyz Matches "abc*xyz" only
9462194739
*/
9462294740
static int patternCompare(
9462394741
const u8 *zPattern, /* The glob pattern */
9462494742
const u8 *zString, /* The string to compare against the glob */
9462594743
const struct compareInfo *pInfo, /* Information about how to do the compare */
9462694744
u32 esc /* The escape character */
9462794745
){
94628
- u32 c, c2;
94629
- int invert;
94630
- int seen;
94631
- u8 matchOne = pInfo->matchOne;
94632
- u8 matchAll = pInfo->matchAll;
94633
- u8 matchSet = pInfo->matchSet;
94634
- u8 noCase = pInfo->noCase;
94635
- int prevEscape = 0; /* True if the previous character was 'escape' */
94746
+ u32 c, c2; /* Next pattern and input string chars */
94747
+ u32 matchOne = pInfo->matchOne; /* "?" or "_" */
94748
+ u32 matchAll = pInfo->matchAll; /* "*" or "%" */
94749
+ u32 matchOther; /* "[" or the escape character */
94750
+ u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */
94751
+ const u8 *zEscaped = 0; /* One past the last escaped input char */
94752
+
94753
+ /* The GLOB operator does not have an ESCAPE clause. And LIKE does not
94754
+ ** have the matchSet operator. So we either have to look for one or
94755
+ ** the other, never both. Hence the single variable matchOther is used
94756
+ ** to store the one we have to look for.
94757
+ */
94758
+ matchOther = esc ? esc : pInfo->matchSet;
9463694759
9463794760
while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
94638
- if( c==matchAll && !prevEscape ){
94761
+ if( c==matchAll ){ /* Match "*" */
94762
+ /* Skip over multiple "*" characters in the pattern. If there
94763
+ ** are also "?" characters, skip those as well, but consume a
94764
+ ** single character of the input string for each "?" skipped */
9463994765
while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
9464094766
|| c == matchOne ){
9464194767
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
9464294768
return 0;
9464394769
}
9464494770
}
9464594771
if( c==0 ){
94646
- return 1;
94647
- }else if( c==esc ){
94648
- c = sqlite3Utf8Read(&zPattern);
94649
- if( c==0 ){
94650
- return 0;
94651
- }
94652
- }else if( c==matchSet ){
94653
- assert( esc==0 ); /* This is GLOB, not LIKE */
94654
- assert( matchSet<0x80 ); /* '[' is a single-byte character */
94655
- while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
94656
- SQLITE_SKIP_UTF8(zString);
94657
- }
94658
- return *zString!=0;
94659
- }
94660
- while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
94661
- if( noCase ){
94662
- GlobUpperToLower(c2);
94663
- GlobUpperToLower(c);
94664
- while( c2 != 0 && c2 != c ){
94665
- c2 = sqlite3Utf8Read(&zString);
94666
- GlobUpperToLower(c2);
94667
- }
94668
- }else{
94669
- while( c2 != 0 && c2 != c ){
94670
- c2 = sqlite3Utf8Read(&zString);
94671
- }
94672
- }
94673
- if( c2==0 ) return 0;
94674
- if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
94675
- }
94676
- return 0;
94677
- }else if( c==matchOne && !prevEscape ){
94678
- if( sqlite3Utf8Read(&zString)==0 ){
94679
- return 0;
94680
- }
94681
- }else if( c==matchSet ){
94682
- u32 prior_c = 0;
94683
- assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
94684
- seen = 0;
94685
- invert = 0;
94686
- c = sqlite3Utf8Read(&zString);
94687
- if( c==0 ) return 0;
94688
- c2 = sqlite3Utf8Read(&zPattern);
94689
- if( c2=='^' ){
94690
- invert = 1;
94691
- c2 = sqlite3Utf8Read(&zPattern);
94692
- }
94693
- if( c2==']' ){
94694
- if( c==']' ) seen = 1;
94695
- c2 = sqlite3Utf8Read(&zPattern);
94696
- }
94697
- while( c2 && c2!=']' ){
94698
- if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
94699
- c2 = sqlite3Utf8Read(&zPattern);
94700
- if( c>=prior_c && c<=c2 ) seen = 1;
94701
- prior_c = 0;
94702
- }else{
94703
- if( c==c2 ){
94704
- seen = 1;
94705
- }
94706
- prior_c = c2;
94707
- }
94708
- c2 = sqlite3Utf8Read(&zPattern);
94709
- }
94710
- if( c2==0 || (seen ^ invert)==0 ){
94711
- return 0;
94712
- }
94713
- }else if( esc==c && !prevEscape ){
94714
- prevEscape = 1;
94715
- }else{
94716
- c2 = sqlite3Utf8Read(&zString);
94717
- if( noCase ){
94718
- GlobUpperToLower(c);
94719
- GlobUpperToLower(c2);
94720
- }
94721
- if( c!=c2 ){
94722
- return 0;
94723
- }
94724
- prevEscape = 0;
94725
- }
94772
+ return 1; /* "*" at the end of the pattern matches */
94773
+ }else if( c==matchOther ){
94774
+ if( esc ){
94775
+ c = sqlite3Utf8Read(&zPattern);
94776
+ if( c==0 ) return 0;
94777
+ }else{
94778
+ /* "[...]" immediately follows the "*". We have to do a slow
94779
+ ** recursive search in this case, but it is an unusual case. */
94780
+ assert( matchOther<0x80 ); /* '[' is a single-byte character */
94781
+ while( *zString
94782
+ && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
94783
+ SQLITE_SKIP_UTF8(zString);
94784
+ }
94785
+ return *zString!=0;
94786
+ }
94787
+ }
94788
+
94789
+ /* At this point variable c contains the first character of the
94790
+ ** pattern string past the "*". Search in the input string for the
94791
+ ** first matching character and recursively contine the match from
94792
+ ** that point.
94793
+ **
94794
+ ** For a case-insensitive search, set variable cx to be the same as
94795
+ ** c but in the other case and search the input string for either
94796
+ ** c or cx.
94797
+ */
94798
+ if( c<=0x80 ){
94799
+ u32 cx;
94800
+ if( noCase ){
94801
+ cx = sqlite3Toupper(c);
94802
+ c = sqlite3Tolower(c);
94803
+ }else{
94804
+ cx = c;
94805
+ }
94806
+ while( (c2 = *(zString++))!=0 ){
94807
+ if( c2!=c && c2!=cx ) continue;
94808
+ if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
94809
+ }
94810
+ }else{
94811
+ while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
94812
+ if( c2!=c ) continue;
94813
+ if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
94814
+ }
94815
+ }
94816
+ return 0;
94817
+ }
94818
+ if( c==matchOther ){
94819
+ if( esc ){
94820
+ c = sqlite3Utf8Read(&zPattern);
94821
+ if( c==0 ) return 0;
94822
+ zEscaped = zPattern;
94823
+ }else{
94824
+ u32 prior_c = 0;
94825
+ int seen = 0;
94826
+ int invert = 0;
94827
+ c = sqlite3Utf8Read(&zString);
94828
+ if( c==0 ) return 0;
94829
+ c2 = sqlite3Utf8Read(&zPattern);
94830
+ if( c2=='^' ){
94831
+ invert = 1;
94832
+ c2 = sqlite3Utf8Read(&zPattern);
94833
+ }
94834
+ if( c2==']' ){
94835
+ if( c==']' ) seen = 1;
94836
+ c2 = sqlite3Utf8Read(&zPattern);
94837
+ }
94838
+ while( c2 && c2!=']' ){
94839
+ if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
94840
+ c2 = sqlite3Utf8Read(&zPattern);
94841
+ if( c>=prior_c && c<=c2 ) seen = 1;
94842
+ prior_c = 0;
94843
+ }else{
94844
+ if( c==c2 ){
94845
+ seen = 1;
94846
+ }
94847
+ prior_c = c2;
94848
+ }
94849
+ c2 = sqlite3Utf8Read(&zPattern);
94850
+ }
94851
+ if( c2==0 || (seen ^ invert)==0 ){
94852
+ return 0;
94853
+ }
94854
+ continue;
94855
+ }
94856
+ }
94857
+ c2 = sqlite3Utf8Read(&zString);
94858
+ if( c==c2 ) continue;
94859
+ if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
94860
+ continue;
94861
+ }
94862
+ if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
94863
+ return 0;
9472694864
}
9472794865
return *zString==0;
9472894866
}
9472994867
9473094868
/*
@@ -103884,10 +104022,24 @@
103884104022
**
103885104023
*************************************************************************
103886104024
** This file contains C code routines that are called by the parser
103887104025
** to handle SELECT statements in SQLite.
103888104026
*/
104027
+
104028
+/*
104029
+** Trace output macros
104030
+*/
104031
+#if SELECTTRACE_ENABLED
104032
+/***/ int sqlite3SelectTrace = 0;
104033
+# define SELECTTRACE(K,P,S,X) \
104034
+ if(sqlite3SelectTrace&(K)) \
104035
+ sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",(S)->zSelName,(S)),\
104036
+ sqlite3DebugPrintf X
104037
+#else
104038
+# define SELECTTRACE(K,P,S,X)
104039
+#endif
104040
+
103889104041
103890104042
/*
103891104043
** An instance of the following object is used to record information about
103892104044
** how to process the DISTINCT keyword, to simplify passing that information
103893104045
** into the selectInnerLoop() routine.
@@ -103996,10 +104148,22 @@
103996104148
assert( pNew->pSrc!=0 || pParse->nErr>0 );
103997104149
}
103998104150
assert( pNew!=&standin );
103999104151
return pNew;
104000104152
}
104153
+
104154
+#if SELECTTRACE_ENABLED
104155
+/*
104156
+** Set the name of a Select object
104157
+*/
104158
+SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
104159
+ if( p && zName ){
104160
+ sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
104161
+ }
104162
+}
104163
+#endif
104164
+
104001104165
104002104166
/*
104003104167
** Delete the given Select structure and all of its substructures.
104004104168
*/
104005104169
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
@@ -105026,11 +105190,10 @@
105026105190
int regRow;
105027105191
int regRowid;
105028105192
int nKey;
105029105193
int iSortTab; /* Sorter cursor to read from */
105030105194
int nSortData; /* Trailing values to read from sorter */
105031
- u8 p5; /* p5 parameter for 1st OP_Column */
105032105195
int i;
105033105196
int bSeq; /* True if sorter record includes seq. no. */
105034105197
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
105035105198
struct ExprList_item *aOutEx = p->pEList->a;
105036105199
#endif
@@ -105060,23 +105223,20 @@
105060105223
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
105061105224
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
105062105225
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
105063105226
VdbeCoverage(v);
105064105227
codeOffset(v, p->iOffset, addrContinue);
105065
- sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
105066
- p5 = OPFLAG_CLEARCACHE;
105228
+ sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
105067105229
bSeq = 0;
105068105230
}else{
105069105231
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
105070105232
codeOffset(v, p->iOffset, addrContinue);
105071105233
iSortTab = iTab;
105072
- p5 = 0;
105073105234
bSeq = 1;
105074105235
}
105075105236
for(i=0; i<nSortData; i++){
105076105237
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
105077
- if( i==0 ) sqlite3VdbeChangeP5(v, p5);
105078105238
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
105079105239
}
105080105240
switch( eDest ){
105081105241
case SRT_Table:
105082105242
case SRT_EphemTab: {
@@ -107226,10 +107386,12 @@
107226107386
}
107227107387
}
107228107388
}
107229107389
107230107390
/***** If we reach this point, flattening is permitted. *****/
107391
+ SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
107392
+ pSub->zSelName, pSub, iFrom));
107231107393
107232107394
/* Authorize the subquery */
107233107395
pParse->zAuthContext = pSubitem->zName;
107234107396
TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
107235107397
testcase( i==SQLITE_DENY );
@@ -107278,10 +107440,11 @@
107278107440
p->pSrc = 0;
107279107441
p->pPrior = 0;
107280107442
p->pLimit = 0;
107281107443
p->pOffset = 0;
107282107444
pNew = sqlite3SelectDup(db, p, 0);
107445
+ sqlite3SelectSetName(pNew, pSub->zSelName);
107283107446
p->pOffset = pOffset;
107284107447
p->pLimit = pLimit;
107285107448
p->pOrderBy = pOrderBy;
107286107449
p->pSrc = pSrc;
107287107450
p->op = TK_ALL;
@@ -107290,10 +107453,13 @@
107290107453
}else{
107291107454
pNew->pPrior = pPrior;
107292107455
if( pPrior ) pPrior->pNext = pNew;
107293107456
pNew->pNext = p;
107294107457
p->pPrior = pNew;
107458
+ SELECTTRACE(2,pParse,p,
107459
+ ("compound-subquery flattener creates %s.%p as peer\n",
107460
+ pNew->zSelName, pNew));
107295107461
}
107296107462
if( db->mallocFailed ) return 1;
107297107463
}
107298107464
107299107465
/* Begin flattening the iFrom-th entry of the FROM clause
@@ -107419,12 +107585,27 @@
107419107585
if( isAgg ){
107420107586
substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
107421107587
pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
107422107588
}
107423107589
if( pSub->pOrderBy ){
107590
+ /* At this point, any non-zero iOrderByCol values indicate that the
107591
+ ** ORDER BY column expression is identical to the iOrderByCol'th
107592
+ ** expression returned by SELECT statement pSub. Since these values
107593
+ ** do not necessarily correspond to columns in SELECT statement pParent,
107594
+ ** zero them before transfering the ORDER BY clause.
107595
+ **
107596
+ ** Not doing this may cause an error if a subsequent call to this
107597
+ ** function attempts to flatten a compound sub-query into pParent
107598
+ ** (the only way this can happen is if the compound sub-query is
107599
+ ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */
107600
+ ExprList *pOrderBy = pSub->pOrderBy;
107601
+ for(i=0; i<pOrderBy->nExpr; i++){
107602
+ pOrderBy->a[i].u.x.iOrderByCol = 0;
107603
+ }
107424107604
assert( pParent->pOrderBy==0 );
107425
- pParent->pOrderBy = pSub->pOrderBy;
107605
+ assert( pSub->pPrior==0 );
107606
+ pParent->pOrderBy = pOrderBy;
107426107607
pSub->pOrderBy = 0;
107427107608
}else if( pParent->pOrderBy ){
107428107609
substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
107429107610
}
107430107611
if( pSub->pWhere ){
@@ -107465,10 +107646,17 @@
107465107646
107466107647
/* Finially, delete what is left of the subquery and return
107467107648
** success.
107468107649
*/
107469107650
sqlite3SelectDelete(db, pSub1);
107651
+
107652
+#if SELECTTRACE_ENABLED
107653
+ if( sqlite3SelectTrace & 0x100 ){
107654
+ sqlite3DebugPrintf("After flattening:\n");
107655
+ sqlite3TreeViewSelect(0, p, 0);
107656
+ }
107657
+#endif
107470107658
107471107659
return 1;
107472107660
}
107473107661
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
107474107662
@@ -107936,10 +108124,11 @@
107936108124
if( pTab->pSelect || IsVirtual(pTab) ){
107937108125
/* We reach here if the named table is a really a view */
107938108126
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
107939108127
assert( pFrom->pSelect==0 );
107940108128
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
108129
+ sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
107941108130
sqlite3WalkSelect(pWalker, pFrom->pSelect);
107942108131
}
107943108132
#endif
107944108133
}
107945108134
@@ -108470,10 +108659,17 @@
108470108659
if( p==0 || db->mallocFailed || pParse->nErr ){
108471108660
return 1;
108472108661
}
108473108662
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
108474108663
memset(&sAggInfo, 0, sizeof(sAggInfo));
108664
+#if SELECTTRACE_ENABLED
108665
+ pParse->nSelectIndent++;
108666
+ SELECTTRACE(1,pParse,p, ("begin processing:\n"));
108667
+ if( sqlite3SelectTrace & 0x100 ){
108668
+ sqlite3TreeViewSelect(0, p, 0);
108669
+ }
108670
+#endif
108475108671
108476108672
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
108477108673
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
108478108674
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
108479108675
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
@@ -108626,10 +108822,14 @@
108626108822
/* If there is are a sequence of queries, do the earlier ones first.
108627108823
*/
108628108824
if( p->pPrior ){
108629108825
rc = multiSelect(pParse, p, pDest);
108630108826
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
108827
+#if SELECTTRACE_ENABLED
108828
+ SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
108829
+ pParse->nSelectIndent--;
108830
+#endif
108631108831
return rc;
108632108832
}
108633108833
#endif
108634108834
108635108835
/* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
@@ -108961,16 +109161,15 @@
108961109161
** from the previous row currently stored in a0, a1, a2...
108962109162
*/
108963109163
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
108964109164
sqlite3ExprCacheClear(pParse);
108965109165
if( groupBySort ){
108966
- sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
109166
+ sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
108967109167
}
108968109168
for(j=0; j<pGroupBy->nExpr; j++){
108969109169
if( groupBySort ){
108970109170
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
108971
- if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
108972109171
}else{
108973109172
sAggInfo.directMode = 1;
108974109173
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
108975109174
}
108976109175
}
@@ -109225,107 +109424,110 @@
109225109424
generateColumnNames(pParse, pTabList, pEList);
109226109425
}
109227109426
109228109427
sqlite3DbFree(db, sAggInfo.aCol);
109229109428
sqlite3DbFree(db, sAggInfo.aFunc);
109429
+#if SELECTTRACE_ENABLED
109430
+ SELECTTRACE(1,pParse,p,("end processing\n"));
109431
+ pParse->nSelectIndent--;
109432
+#endif
109230109433
return rc;
109231109434
}
109232109435
109233
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
109436
+#ifdef SQLITE_DEBUG
109234109437
/*
109235109438
** Generate a human-readable description of a the Select object.
109236109439
*/
109237
-static void explainOneSelect(Vdbe *pVdbe, Select *p){
109238
- sqlite3ExplainPrintf(pVdbe, "SELECT ");
109239
- if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
109240
- if( p->selFlags & SF_Distinct ){
109241
- sqlite3ExplainPrintf(pVdbe, "DISTINCT ");
109242
- }
109243
- if( p->selFlags & SF_Aggregate ){
109244
- sqlite3ExplainPrintf(pVdbe, "agg_flag ");
109245
- }
109246
- sqlite3ExplainNL(pVdbe);
109247
- sqlite3ExplainPrintf(pVdbe, " ");
109248
- }
109249
- sqlite3ExplainExprList(pVdbe, p->pEList);
109250
- sqlite3ExplainNL(pVdbe);
109440
+SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
109441
+ int n = 0;
109442
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
109443
+ sqlite3TreeViewLine(pView, "SELECT%s%s",
109444
+ ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
109445
+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
109446
+ );
109447
+ if( p->pSrc && p->pSrc->nSrc ) n++;
109448
+ if( p->pWhere ) n++;
109449
+ if( p->pGroupBy ) n++;
109450
+ if( p->pHaving ) n++;
109451
+ if( p->pOrderBy ) n++;
109452
+ if( p->pLimit ) n++;
109453
+ if( p->pOffset ) n++;
109454
+ if( p->pPrior ) n++;
109455
+ sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
109251109456
if( p->pSrc && p->pSrc->nSrc ){
109252109457
int i;
109253
- sqlite3ExplainPrintf(pVdbe, "FROM ");
109254
- sqlite3ExplainPush(pVdbe);
109458
+ pView = sqlite3TreeViewPush(pView, (n--)>0);
109459
+ sqlite3TreeViewLine(pView, "FROM");
109255109460
for(i=0; i<p->pSrc->nSrc; i++){
109256109461
struct SrcList_item *pItem = &p->pSrc->a[i];
109257
- sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
109258
- if( pItem->pSelect ){
109259
- sqlite3ExplainSelect(pVdbe, pItem->pSelect);
109260
- if( pItem->pTab ){
109261
- sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
109262
- }
109462
+ StrAccum x;
109463
+ char zLine[100];
109464
+ sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
109465
+ sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
109466
+ if( pItem->zDatabase ){
109467
+ sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
109263109468
}else if( pItem->zName ){
109264
- sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName);
109469
+ sqlite3XPrintf(&x, 0, " %s", pItem->zName);
109470
+ }
109471
+ if( pItem->pTab ){
109472
+ sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
109265109473
}
109266109474
if( pItem->zAlias ){
109267
- sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
109475
+ sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
109268109476
}
109269109477
if( pItem->jointype & JT_LEFT ){
109270
- sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN");
109478
+ sqlite3XPrintf(&x, 0, " LEFT-JOIN");
109271109479
}
109272
- sqlite3ExplainNL(pVdbe);
109480
+ sqlite3StrAccumFinish(&x);
109481
+ sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
109482
+ if( pItem->pSelect ){
109483
+ sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
109484
+ }
109485
+ sqlite3TreeViewPop(pView);
109273109486
}
109274
- sqlite3ExplainPop(pVdbe);
109487
+ sqlite3TreeViewPop(pView);
109275109488
}
109276109489
if( p->pWhere ){
109277
- sqlite3ExplainPrintf(pVdbe, "WHERE ");
109278
- sqlite3ExplainExpr(pVdbe, p->pWhere);
109279
- sqlite3ExplainNL(pVdbe);
109490
+ sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
109491
+ sqlite3TreeViewExpr(pView, p->pWhere, 0);
109492
+ sqlite3TreeViewPop(pView);
109280109493
}
109281109494
if( p->pGroupBy ){
109282
- sqlite3ExplainPrintf(pVdbe, "GROUPBY ");
109283
- sqlite3ExplainExprList(pVdbe, p->pGroupBy);
109284
- sqlite3ExplainNL(pVdbe);
109495
+ sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
109285109496
}
109286109497
if( p->pHaving ){
109287
- sqlite3ExplainPrintf(pVdbe, "HAVING ");
109288
- sqlite3ExplainExpr(pVdbe, p->pHaving);
109289
- sqlite3ExplainNL(pVdbe);
109498
+ sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
109499
+ sqlite3TreeViewExpr(pView, p->pHaving, 0);
109500
+ sqlite3TreeViewPop(pView);
109290109501
}
109291109502
if( p->pOrderBy ){
109292
- sqlite3ExplainPrintf(pVdbe, "ORDERBY ");
109293
- sqlite3ExplainExprList(pVdbe, p->pOrderBy);
109294
- sqlite3ExplainNL(pVdbe);
109503
+ sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
109295109504
}
109296109505
if( p->pLimit ){
109297
- sqlite3ExplainPrintf(pVdbe, "LIMIT ");
109298
- sqlite3ExplainExpr(pVdbe, p->pLimit);
109299
- sqlite3ExplainNL(pVdbe);
109506
+ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
109507
+ sqlite3TreeViewExpr(pView, p->pLimit, 0);
109508
+ sqlite3TreeViewPop(pView);
109300109509
}
109301109510
if( p->pOffset ){
109302
- sqlite3ExplainPrintf(pVdbe, "OFFSET ");
109303
- sqlite3ExplainExpr(pVdbe, p->pOffset);
109304
- sqlite3ExplainNL(pVdbe);
109305
- }
109306
-}
109307
-SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
109308
- if( p==0 ){
109309
- sqlite3ExplainPrintf(pVdbe, "(null-select)");
109310
- return;
109311
- }
109312
- sqlite3ExplainPush(pVdbe);
109313
- while( p ){
109314
- explainOneSelect(pVdbe, p);
109315
- p = p->pNext;
109316
- if( p==0 ) break;
109317
- sqlite3ExplainNL(pVdbe);
109318
- sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
109319
- }
109320
- sqlite3ExplainPrintf(pVdbe, "END");
109321
- sqlite3ExplainPop(pVdbe);
109322
-}
109323
-
109324
-/* End of the structure debug printing code
109325
-*****************************************************************************/
109326
-#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
109511
+ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
109512
+ sqlite3TreeViewExpr(pView, p->pOffset, 0);
109513
+ sqlite3TreeViewPop(pView);
109514
+ }
109515
+ if( p->pPrior ){
109516
+ const char *zOp = "UNION";
109517
+ switch( p->op ){
109518
+ case TK_ALL: zOp = "UNION ALL"; break;
109519
+ case TK_INTERSECT: zOp = "INTERSECT"; break;
109520
+ case TK_EXCEPT: zOp = "EXCEPT"; break;
109521
+ }
109522
+ sqlite3TreeViewItem(pView, zOp, (n--)>0);
109523
+ sqlite3TreeViewSelect(pView, p->pPrior, 0);
109524
+ sqlite3TreeViewPop(pView);
109525
+ }
109526
+ sqlite3TreeViewPop(pView);
109527
+}
109528
+#endif /* SQLITE_DEBUG */
109327109529
109328109530
/************** End of select.c **********************************************/
109329109531
/************** Begin file table.c *******************************************/
109330109532
/*
109331109533
** 2001 September 15
@@ -112311,10 +112513,11 @@
112311112513
}
112312112514
sqlite3DbFree(db, pVTable);
112313112515
}else if( ALWAYS(pVTable->pVtab) ){
112314112516
/* Justification of ALWAYS(): A correct vtab constructor must allocate
112315112517
** the sqlite3_vtab object if successful. */
112518
+ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
112316112519
pVTable->pVtab->pModule = pMod->pModule;
112317112520
pVTable->nRef = 1;
112318112521
if( sCtx.pTab ){
112319112522
const char *zFormat = "vtable constructor did not declare schema: %s";
112320112523
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
@@ -113719,15 +113922,10 @@
113719113922
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
113720113923
assert( TK_GE==TK_EQ+4 );
113721113924
return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
113722113925
}
113723113926
113724
-/*
113725
-** Swap two objects of type TYPE.
113726
-*/
113727
-#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
113728
-
113729113927
/*
113730113928
** Commute a comparison operator. Expressions of the form "X op Y"
113731113929
** are converted into "Y op X".
113732113930
**
113733113931
** If left/right precedence rules come into play when determining the
@@ -115566,21 +115764,28 @@
115566115764
** have been requested when testing key $P in whereEqualScanEst(). */
115567115765
whereKeyStats(pParse, p, pRec, 0, a);
115568115766
iLower = a[0];
115569115767
iUpper = a[0] + a[1];
115570115768
}
115769
+
115770
+ assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115771
+ assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115772
+ assert( p->aSortOrder!=0 );
115773
+ if( p->aSortOrder[nEq] ){
115774
+ /* The roles of pLower and pUpper are swapped for a DESC index */
115775
+ SWAP(WhereTerm*, pLower, pUpper);
115776
+ }
115571115777
115572115778
/* If possible, improve on the iLower estimate using ($P:$L). */
115573115779
if( pLower ){
115574115780
int bOk; /* True if value is extracted from pExpr */
115575115781
Expr *pExpr = pLower->pExpr->pRight;
115576
- assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115577115782
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115578115783
if( rc==SQLITE_OK && bOk ){
115579115784
tRowcnt iNew;
115580115785
whereKeyStats(pParse, p, pRec, 0, a);
115581
- iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
115786
+ iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115582115787
if( iNew>iLower ) iLower = iNew;
115583115788
nOut--;
115584115789
pLower = 0;
115585115790
}
115586115791
}
@@ -115587,16 +115792,15 @@
115587115792
115588115793
/* If possible, improve on the iUpper estimate using ($P:$U). */
115589115794
if( pUpper ){
115590115795
int bOk; /* True if value is extracted from pExpr */
115591115796
Expr *pExpr = pUpper->pExpr->pRight;
115592
- assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115593115797
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115594115798
if( rc==SQLITE_OK && bOk ){
115595115799
tRowcnt iNew;
115596115800
whereKeyStats(pParse, p, pRec, 1, a);
115597
- iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
115801
+ iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115598115802
if( iNew<iUpper ) iUpper = iNew;
115599115803
nOut--;
115600115804
pUpper = 0;
115601115805
}
115602115806
}
@@ -116091,65 +116295,52 @@
116091116295
sqlite3StrAccumAppend(pStr, "?", 1);
116092116296
}
116093116297
116094116298
/*
116095116299
** Argument pLevel describes a strategy for scanning table pTab. This
116096
-** function returns a pointer to a string buffer containing a description
116097
-** of the subset of table rows scanned by the strategy in the form of an
116098
-** SQL expression. Or, if all rows are scanned, NULL is returned.
116300
+** function appends text to pStr that describes the subset of table
116301
+** rows scanned by the strategy in the form of an SQL expression.
116099116302
**
116100116303
** For example, if the query:
116101116304
**
116102116305
** SELECT * FROM t1 WHERE a=1 AND b>2;
116103116306
**
116104116307
** is run and there is an index on (a, b), then this function returns a
116105116308
** string similar to:
116106116309
**
116107116310
** "a=? AND b>?"
116108
-**
116109
-** The returned pointer points to memory obtained from sqlite3DbMalloc().
116110
-** It is the responsibility of the caller to free the buffer when it is
116111
-** no longer required.
116112116311
*/
116113
-static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
116312
+static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
116114116313
Index *pIndex = pLoop->u.btree.pIndex;
116115116314
u16 nEq = pLoop->u.btree.nEq;
116116116315
u16 nSkip = pLoop->u.btree.nSkip;
116117116316
int i, j;
116118116317
Column *aCol = pTab->aCol;
116119116318
i16 *aiColumn = pIndex->aiColumn;
116120
- StrAccum txt;
116121
-
116122
- if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
116123
- return 0;
116124
- }
116125
- sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
116126
- txt.db = db;
116127
- sqlite3StrAccumAppend(&txt, " (", 2);
116319
+
116320
+ if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
116321
+ sqlite3StrAccumAppend(pStr, " (", 2);
116128116322
for(i=0; i<nEq; i++){
116129116323
char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
116130116324
if( i>=nSkip ){
116131
- explainAppendTerm(&txt, i, z, "=");
116325
+ explainAppendTerm(pStr, i, z, "=");
116132116326
}else{
116133
- if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
116134
- sqlite3StrAccumAppend(&txt, "ANY(", 4);
116135
- sqlite3StrAccumAppendAll(&txt, z);
116136
- sqlite3StrAccumAppend(&txt, ")", 1);
116327
+ if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
116328
+ sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
116137116329
}
116138116330
}
116139116331
116140116332
j = i;
116141116333
if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
116142116334
char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116143
- explainAppendTerm(&txt, i++, z, ">");
116335
+ explainAppendTerm(pStr, i++, z, ">");
116144116336
}
116145116337
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
116146116338
char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116147
- explainAppendTerm(&txt, i, z, "<");
116339
+ explainAppendTerm(pStr, i, z, "<");
116148116340
}
116149
- sqlite3StrAccumAppend(&txt, ")", 1);
116150
- return sqlite3StrAccumFinish(&txt);
116341
+ sqlite3StrAccumAppend(pStr, ")", 1);
116151116342
}
116152116343
116153116344
/*
116154116345
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
116155116346
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
@@ -116169,72 +116360,90 @@
116169116360
#endif
116170116361
{
116171116362
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
116172116363
Vdbe *v = pParse->pVdbe; /* VM being constructed */
116173116364
sqlite3 *db = pParse->db; /* Database handle */
116174
- char *zMsg; /* Text to add to EQP output */
116175116365
int iId = pParse->iSelectId; /* Select id (left-most output column) */
116176116366
int isSearch; /* True for a SEARCH. False for SCAN. */
116177116367
WhereLoop *pLoop; /* The controlling WhereLoop object */
116178116368
u32 flags; /* Flags that describe this loop */
116369
+ char *zMsg; /* Text to add to EQP output */
116370
+ StrAccum str; /* EQP output string */
116371
+ char zBuf[100]; /* Initial space for EQP output string */
116179116372
116180116373
pLoop = pLevel->pWLoop;
116181116374
flags = pLoop->wsFlags;
116182116375
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
116183116376
116184116377
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
116185116378
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
116186116379
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
116187116380
116188
- zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
116381
+ sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
116382
+ str.db = db;
116383
+ sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
116189116384
if( pItem->pSelect ){
116190
- zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
116385
+ sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
116191116386
}else{
116192
- zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
116387
+ sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
116193116388
}
116194116389
116195116390
if( pItem->zAlias ){
116196
- zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
116197
- }
116198
- if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
116199
- && ALWAYS(pLoop->u.btree.pIndex!=0)
116200
- ){
116201
- const char *zFmt;
116202
- Index *pIdx = pLoop->u.btree.pIndex;
116203
- char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
116391
+ sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
116392
+ }
116393
+ if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
116394
+ const char *zFmt = 0;
116395
+ Index *pIdx;
116396
+
116397
+ assert( pLoop->u.btree.pIndex!=0 );
116398
+ pIdx = pLoop->u.btree.pIndex;
116204116399
assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
116205116400
if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
116206
- zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s";
116401
+ if( isSearch ){
116402
+ zFmt = "PRIMARY KEY";
116403
+ }
116207116404
}else if( flags & WHERE_AUTO_INDEX ){
116208
- zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s";
116405
+ zFmt = "AUTOMATIC COVERING INDEX";
116209116406
}else if( flags & WHERE_IDX_ONLY ){
116210
- zFmt = "%s USING COVERING INDEX %s%s";
116407
+ zFmt = "COVERING INDEX %s";
116211116408
}else{
116212
- zFmt = "%s USING INDEX %s%s";
116409
+ zFmt = "INDEX %s";
116213116410
}
116214
- zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere);
116215
- sqlite3DbFree(db, zWhere);
116411
+ if( zFmt ){
116412
+ sqlite3StrAccumAppend(&str, " USING ", 7);
116413
+ sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
116414
+ explainIndexRange(&str, pLoop, pItem->pTab);
116415
+ }
116216116416
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
116217
- zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
116218
-
116417
+ const char *zRange;
116219116418
if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
116220
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
116419
+ zRange = "(rowid=?)";
116221116420
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
116222
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
116421
+ zRange = "(rowid>? AND rowid<?)";
116223116422
}else if( flags&WHERE_BTM_LIMIT ){
116224
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
116225
- }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
116226
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
116423
+ zRange = "(rowid>?)";
116424
+ }else{
116425
+ assert( flags&WHERE_TOP_LIMIT);
116426
+ zRange = "(rowid<?)";
116227116427
}
116428
+ sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
116429
+ sqlite3StrAccumAppendAll(&str, zRange);
116228116430
}
116229116431
#ifndef SQLITE_OMIT_VIRTUALTABLE
116230116432
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
116231
- zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
116433
+ sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
116232116434
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
116233116435
}
116234116436
#endif
116235
- zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
116437
+#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
116438
+ if( pLoop->nOut>=10 ){
116439
+ sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
116440
+ }else{
116441
+ sqlite3StrAccumAppend(&str, " (~1 row)", 9);
116442
+ }
116443
+#endif
116444
+ zMsg = sqlite3StrAccumFinish(&str);
116236116445
sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
116237116446
}
116238116447
}
116239116448
#else
116240116449
# define explainOneScan(u,v,w,x,y,z)
@@ -116884,12 +117093,13 @@
116884117093
116885117094
/* Run a separate WHERE clause for each term of the OR clause. After
116886117095
** eliminating duplicates from other WHERE clauses, the action for each
116887117096
** sub-WHERE clause is to to invoke the main loop body as a subroutine.
116888117097
*/
116889
- wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
116890
- WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY;
117098
+ wctrlFlags = WHERE_OMIT_OPEN_CLOSE
117099
+ | WHERE_FORCE_TABLE
117100
+ | WHERE_ONETABLE_ONLY;
116891117101
for(ii=0; ii<pOrWc->nTerm; ii++){
116892117102
WhereTerm *pOrTerm = &pOrWc->a[ii];
116893117103
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
116894117104
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
116895117105
Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
@@ -116897,10 +117107,11 @@
116897117107
if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
116898117108
pAndExpr->pLeft = pOrExpr;
116899117109
pOrExpr = pAndExpr;
116900117110
}
116901117111
/* Loop through table entries that match term pOrTerm. */
117112
+ WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
116902117113
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
116903117114
wctrlFlags, iCovCur);
116904117115
assert( pSubWInfo || pParse->nErr || db->mallocFailed );
116905117116
if( pSubWInfo ){
116906117117
WhereLoop *pSubLoop;
@@ -117116,25 +117327,30 @@
117116117327
}
117117117328
117118117329
return pLevel->notReady;
117119117330
}
117120117331
117121
-#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
117332
+#ifdef WHERETRACE_ENABLED
117122117333
/*
117123
-** Generate "Explanation" text for a WhereTerm.
117334
+** Print the content of a WhereTerm object
117124117335
*/
117125
-static void whereExplainTerm(Vdbe *v, WhereTerm *pTerm){
117126
- char zType[4];
117127
- memcpy(zType, "...", 4);
117128
- if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
117129
- if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
117130
- if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
117131
- sqlite3ExplainPrintf(v, "%s ", zType);
117132
- sqlite3ExplainExpr(v, pTerm->pExpr);
117133
-}
117134
-#endif /* WHERETRACE_ENABLED && SQLITE_ENABLE_TREE_EXPLAIN */
117135
-
117336
+static void whereTermPrint(WhereTerm *pTerm, int iTerm){
117337
+ if( pTerm==0 ){
117338
+ sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
117339
+ }else{
117340
+ char zType[4];
117341
+ memcpy(zType, "...", 4);
117342
+ if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
117343
+ if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
117344
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
117345
+ sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
117346
+ iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
117347
+ pTerm->eOperator);
117348
+ sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
117349
+ }
117350
+}
117351
+#endif
117136117352
117137117353
#ifdef WHERETRACE_ENABLED
117138117354
/*
117139117355
** Print a WhereLoop object for debugging purposes
117140117356
*/
@@ -117174,31 +117390,16 @@
117174117390
sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
117175117391
}else{
117176117392
sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
117177117393
}
117178117394
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
117179
-#ifdef SQLITE_ENABLE_TREE_EXPLAIN
117180
- /* If the 0x100 bit of wheretracing is set, then show all of the constraint
117181
- ** expressions in the WhereLoop.aLTerm[] array.
117182
- */
117183
- if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ /* WHERETRACE 0x100 */
117395
+ if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
117184117396
int i;
117185
- Vdbe *v = pWInfo->pParse->pVdbe;
117186
- sqlite3ExplainBegin(v);
117187117397
for(i=0; i<p->nLTerm; i++){
117188
- WhereTerm *pTerm = p->aLTerm[i];
117189
- if( pTerm==0 ) continue;
117190
- sqlite3ExplainPrintf(v, " (%d) #%-2d ", i+1, (int)(pTerm-pWC->a));
117191
- sqlite3ExplainPush(v);
117192
- whereExplainTerm(v, pTerm);
117193
- sqlite3ExplainPop(v);
117194
- sqlite3ExplainNL(v);
117195
- }
117196
- sqlite3ExplainFinish(v);
117197
- sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
117198
- }
117199
-#endif
117398
+ whereTermPrint(p->aLTerm[i], i);
117399
+ }
117400
+ }
117200117401
}
117201117402
#endif
117202117403
117203117404
/*
117204117405
** Convert bulk memory into a valid WhereLoop that can be passed
@@ -117507,11 +117708,11 @@
117507117708
if( ppPrev==0 ){
117508117709
/* There already exists a WhereLoop on the list that is better
117509117710
** than pTemplate, so just ignore pTemplate */
117510117711
#if WHERETRACE_ENABLED /* 0x8 */
117511117712
if( sqlite3WhereTrace & 0x8 ){
117512
- sqlite3DebugPrintf("ins-noop: ");
117713
+ sqlite3DebugPrintf(" skip: ");
117513117714
whereLoopPrint(pTemplate, pBuilder->pWC);
117514117715
}
117515117716
#endif
117516117717
return SQLITE_OK;
117517117718
}else{
@@ -117523,14 +117724,14 @@
117523117724
** WhereLoop and insert it.
117524117725
*/
117525117726
#if WHERETRACE_ENABLED /* 0x8 */
117526117727
if( sqlite3WhereTrace & 0x8 ){
117527117728
if( p!=0 ){
117528
- sqlite3DebugPrintf("ins-del: ");
117729
+ sqlite3DebugPrintf("replace: ");
117529117730
whereLoopPrint(p, pBuilder->pWC);
117530117731
}
117531
- sqlite3DebugPrintf("ins-new: ");
117732
+ sqlite3DebugPrintf(" add: ");
117532117733
whereLoopPrint(pTemplate, pBuilder->pWC);
117533117734
}
117534117735
#endif
117535117736
if( p==0 ){
117536117737
/* Allocate a new WhereLoop to add to the end of the list */
@@ -117550,11 +117751,11 @@
117550117751
pToDel = *ppTail;
117551117752
if( pToDel==0 ) break;
117552117753
*ppTail = pToDel->pNextLoop;
117553117754
#if WHERETRACE_ENABLED /* 0x8 */
117554117755
if( sqlite3WhereTrace & 0x8 ){
117555
- sqlite3DebugPrintf("ins-del: ");
117756
+ sqlite3DebugPrintf(" delete: ");
117556117757
whereLoopPrint(pToDel, pBuilder->pWC);
117557117758
}
117558117759
#endif
117559117760
whereLoopDelete(db, pToDel);
117560117761
}
@@ -117714,15 +117915,18 @@
117714117915
pNew->aLTerm[pNew->nLTerm++] = 0;
117715117916
pNew->wsFlags |= WHERE_SKIPSCAN;
117716117917
nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
117717117918
if( pTerm ){
117718117919
/* TUNING: When estimating skip-scan for a term that is also indexable,
117719
- ** increase the cost of the skip-scan by 2x, to make it a little less
117920
+ ** multiply the cost of the skip-scan by 2.0, to make it a little less
117720117921
** desirable than the regular index lookup. */
117721117922
nIter += 10; assert( 10==sqlite3LogEst(2) );
117722117923
}
117723117924
pNew->nOut -= nIter;
117925
+ /* TUNING: Because uncertainties in the estimates for skip-scan queries,
117926
+ ** add a 1.375 fudge factor to make skip-scan slightly less likely. */
117927
+ nIter += 5;
117724117928
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
117725117929
pNew->nOut = saved_nOut;
117726117930
pNew->u.btree.nEq = saved_nEq;
117727117931
pNew->u.btree.nSkip = saved_nSkip;
117728117932
}
@@ -118073,13 +118277,21 @@
118073118277
pNew->u.btree.nSkip = 0;
118074118278
pNew->u.btree.pIndex = 0;
118075118279
pNew->nLTerm = 1;
118076118280
pNew->aLTerm[0] = pTerm;
118077118281
/* TUNING: One-time cost for computing the automatic index is
118078
- ** approximately 7*N*log2(N) where N is the number of rows in
118079
- ** the table being indexed. */
118080
- pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) );
118282
+ ** estimated to be X*N*log2(N) where N is the number of rows in
118283
+ ** the table being indexed and where X is 7 (LogEst=28) for normal
118284
+ ** tables or 1.375 (LogEst=4) for views and subqueries. The value
118285
+ ** of X is smaller for views and subqueries so that the query planner
118286
+ ** will be more aggressive about generating automatic indexes for
118287
+ ** those objects, since there is no opportunity to add schema
118288
+ ** indexes on subqueries and views. */
118289
+ pNew->rSetup = rLogSize + rSize + 4;
118290
+ if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
118291
+ pNew->rSetup += 24;
118292
+ }
118081118293
ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
118082118294
/* TUNING: Each index lookup yields 20 rows in the table. This
118083118295
** is more than the usual guess of 10 rows, since we have no way
118084118296
** of knowing how selective the index will ultimately be. It would
118085118297
** not be unreasonable to make this value much larger. */
@@ -118363,11 +118575,10 @@
118363118575
WhereLoopBuilder sSubBuild;
118364118576
WhereOrSet sSum, sCur;
118365118577
struct SrcList_item *pItem;
118366118578
118367118579
pWC = pBuilder->pWC;
118368
- if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
118369118580
pWCEnd = pWC->a + pWC->nTerm;
118370118581
pNew = pBuilder->pNew;
118371118582
memset(&sSum, 0, sizeof(sSum));
118372118583
pItem = pWInfo->pTabList->a + pNew->iTab;
118373118584
iCur = pItem->iCursor;
@@ -118384,10 +118595,11 @@
118384118595
118385118596
sSubBuild = *pBuilder;
118386118597
sSubBuild.pOrderBy = 0;
118387118598
sSubBuild.pOrSet = &sCur;
118388118599
118600
+ WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
118389118601
for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
118390118602
if( (pOrTerm->eOperator & WO_AND)!=0 ){
118391118603
sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
118392118604
}else if( pOrTerm->leftCursor==iCur ){
118393118605
tempWC.pWInfo = pWC->pWInfo;
@@ -118398,18 +118610,30 @@
118398118610
sSubBuild.pWC = &tempWC;
118399118611
}else{
118400118612
continue;
118401118613
}
118402118614
sCur.n = 0;
118615
+#ifdef WHERETRACE_ENABLED
118616
+ WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n",
118617
+ (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
118618
+ if( sqlite3WhereTrace & 0x400 ){
118619
+ for(i=0; i<sSubBuild.pWC->nTerm; i++){
118620
+ whereTermPrint(&sSubBuild.pWC->a[i], i);
118621
+ }
118622
+ }
118623
+#endif
118403118624
#ifndef SQLITE_OMIT_VIRTUALTABLE
118404118625
if( IsVirtual(pItem->pTab) ){
118405118626
rc = whereLoopAddVirtual(&sSubBuild, mExtra);
118406118627
}else
118407118628
#endif
118408118629
{
118409118630
rc = whereLoopAddBtree(&sSubBuild, mExtra);
118410118631
}
118632
+ if( rc==SQLITE_OK ){
118633
+ rc = whereLoopAddOr(&sSubBuild, mExtra);
118634
+ }
118411118635
assert( rc==SQLITE_OK || sCur.n==0 );
118412118636
if( sCur.n==0 ){
118413118637
sSum.n = 0;
118414118638
break;
118415118639
}else if( once ){
@@ -118450,10 +118674,11 @@
118450118674
pNew->rRun = sSum.a[i].rRun + 1;
118451118675
pNew->nOut = sSum.a[i].nOut;
118452118676
pNew->prereq = sSum.a[i].prereq;
118453118677
rc = whereLoopInsert(pBuilder, pNew);
118454118678
}
118679
+ WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm));
118455118680
}
118456118681
}
118457118682
return rc;
118458118683
}
118459118684
@@ -118693,11 +118918,11 @@
118693118918
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
118694118919
}
118695118920
isMatch = 1;
118696118921
break;
118697118922
}
118698
- if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
118923
+ if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
118699118924
/* Make sure the sort order is compatible in an ORDER BY clause.
118700118925
** Sort order is irrelevant for a GROUP BY clause. */
118701118926
if( revSet ){
118702118927
if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
118703118928
}else{
@@ -119158,16 +119383,19 @@
119158119383
pWInfo->revMask = pFrom->revLoop;
119159119384
}
119160119385
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
119161119386
&& pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
119162119387
){
119163
- Bitmask notUsed = 0;
119388
+ Bitmask revMask = 0;
119164119389
int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
119165
- pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed
119390
+ pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
119166119391
);
119167119392
assert( pWInfo->sorted==0 );
119168
- pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr);
119393
+ if( nOrder==pWInfo->pOrderBy->nExpr ){
119394
+ pWInfo->sorted = 1;
119395
+ pWInfo->revMask = revMask;
119396
+ }
119169119397
}
119170119398
}
119171119399
119172119400
119173119401
pWInfo->nRowOut = pFrom->nRow;
@@ -119516,27 +119744,20 @@
119516119744
}
119517119745
}
119518119746
119519119747
/* Construct the WhereLoop objects */
119520119748
WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
119749
+#if defined(WHERETRACE_ENABLED)
119521119750
/* Display all terms of the WHERE clause */
119522
-#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
119523119751
if( sqlite3WhereTrace & 0x100 ){
119524119752
int i;
119525
- Vdbe *v = pParse->pVdbe;
119526
- sqlite3ExplainBegin(v);
119527119753
for(i=0; i<sWLB.pWC->nTerm; i++){
119528
- sqlite3ExplainPrintf(v, "#%-2d ", i);
119529
- sqlite3ExplainPush(v);
119530
- whereExplainTerm(v, &sWLB.pWC->a[i]);
119531
- sqlite3ExplainPop(v);
119532
- sqlite3ExplainNL(v);
119533
- }
119534
- sqlite3ExplainFinish(v);
119535
- sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
119754
+ whereTermPrint(&sWLB.pWC->a[i], i);
119755
+ }
119536119756
}
119537119757
#endif
119758
+
119538119759
if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
119539119760
rc = whereLoopAddAll(&sWLB);
119540119761
if( rc ) goto whereBeginError;
119541119762
119542119763
/* Display all of the WhereLoop objects if wheretrace is enabled */
@@ -120059,11 +120280,11 @@
120059120280
120060120281
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
120061120282
** unary TK_ISNULL or TK_NOTNULL expression. */
120062120283
static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
120063120284
sqlite3 *db = pParse->db;
120064
- if( db->mallocFailed==0 && pY->op==TK_NULL ){
120285
+ if( pY && pA && pY->op==TK_NULL ){
120065120286
pA->op = (u8)op;
120066120287
sqlite3ExprDelete(db, pA->pRight);
120067120288
pA->pRight = 0;
120068120289
}
120069120290
}
@@ -122318,13 +122539,10 @@
122318122539
break;
122319122540
case 111: /* cmd ::= select */
122320122541
{
122321122542
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
122322122543
sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
122323
- sqlite3ExplainBegin(pParse->pVdbe);
122324
- sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy3);
122325
- sqlite3ExplainFinish(pParse->pVdbe);
122326122544
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
122327122545
}
122328122546
break;
122329122547
case 112: /* select ::= with selectnowith */
122330122548
{
@@ -122377,10 +122595,34 @@
122377122595
{yygotominor.yy328 = TK_ALL;}
122378122596
break;
122379122597
case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
122380122598
{
122381122599
yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
122600
+#if SELECTTRACE_ENABLED
122601
+ /* Populate the Select.zSelName[] string that is used to help with
122602
+ ** query planner debugging, to differentiate between multiple Select
122603
+ ** objects in a complex query.
122604
+ **
122605
+ ** If the SELECT keyword is immediately followed by a C-style comment
122606
+ ** then extract the first few alphanumeric characters from within that
122607
+ ** comment to be the zSelName value. Otherwise, the label is #N where
122608
+ ** is an integer that is incremented with each SELECT statement seen.
122609
+ */
122610
+ if( yygotominor.yy3!=0 ){
122611
+ const char *z = yymsp[-8].minor.yy0.z+6;
122612
+ int i;
122613
+ sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "#%d",
122614
+ ++pParse->nSelect);
122615
+ while( z[0]==' ' ) z++;
122616
+ if( z[0]=='/' && z[1]=='*' ){
122617
+ z += 2;
122618
+ while( z[0]==' ' ) z++;
122619
+ for(i=0; sqlite3Isalnum(z[i]); i++){}
122620
+ sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "%.*s", i, z);
122621
+ }
122622
+ }
122623
+#endif /* SELECTRACE_ENABLED */
122382122624
}
122383122625
break;
122384122626
case 120: /* values ::= VALUES LP nexprlist RP */
122385122627
{
122386122628
yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
@@ -123868,10 +124110,11 @@
123868124110
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */
123869124111
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */
123870124112
};
123871124113
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
123872124114
#endif
124115
+SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
123873124116
123874124117
123875124118
/*
123876124119
** Return the length of the token that begins at z[0].
123877124120
** Store the token type in *tokenType before returning.
@@ -125138,10 +125381,15 @@
125138125381
sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
125139125382
sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
125140125383
break;
125141125384
}
125142125385
125386
+ /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames
125387
+ ** can be changed at start-time using the
125388
+ ** sqlite3_config(SQLITE_CONFIG_URI,1) or
125389
+ ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls.
125390
+ */
125143125391
case SQLITE_CONFIG_URI: {
125144125392
sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
125145125393
break;
125146125394
}
125147125395
@@ -126875,11 +127123,11 @@
126875127123
int nUri = sqlite3Strlen30(zUri);
126876127124
126877127125
assert( *pzErrMsg==0 );
126878127126
126879127127
if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
126880
- && nUri>=5 && memcmp(zUri, "file:", 5)==0
127128
+ && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
126881127129
){
126882127130
char *zOpt;
126883127131
int eState; /* Parser state when parsing URI */
126884127132
int iIn; /* Input character index */
126885127133
int iOut = 0; /* Output character index */
@@ -127105,11 +127353,13 @@
127105127353
assert( SQLITE_OPEN_READWRITE == 0x02 );
127106127354
assert( SQLITE_OPEN_CREATE == 0x04 );
127107127355
testcase( (1<<(flags&7))==0x02 ); /* READONLY */
127108127356
testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
127109127357
testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
127110
- if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT;
127358
+ if( ((1<<(flags&7)) & 0x46)==0 ){
127359
+ return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */
127360
+ }
127111127361
127112127362
if( sqlite3GlobalConfig.bCoreMutex==0 ){
127113127363
isThreadsafe = 0;
127114127364
}else if( flags & SQLITE_OPEN_NOMUTEX ){
127115127365
isThreadsafe = 0;
@@ -127989,26 +128239,10 @@
127989128239
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
127990128240
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
127991128241
break;
127992128242
}
127993128243
127994
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
127995
- /* sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
127996
- ** sqlite3_stmt*,const char**);
127997
- **
127998
- ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds
127999
- ** a string that describes the optimized parse tree. This test-control
128000
- ** returns a pointer to that string.
128001
- */
128002
- case SQLITE_TESTCTRL_EXPLAIN_STMT: {
128003
- sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*);
128004
- const char **pzRet = va_arg(ap, const char**);
128005
- *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt);
128006
- break;
128007
- }
128008
-#endif
128009
-
128010128244
/* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
128011128245
**
128012128246
** Set or clear a flag that indicates that the database file is always well-
128013128247
** formed and never corrupt. This flag is clear by default, indicating that
128014128248
** database files might have arbitrary corruption. Setting the flag during
@@ -132464,10 +132698,11 @@
132464132698
assert( iIdx==nVal );
132465132699
132466132700
/* In case the cursor has been used before, clear it now. */
132467132701
sqlite3_finalize(pCsr->pStmt);
132468132702
sqlite3_free(pCsr->aDoclist);
132703
+ sqlite3_free(pCsr->aMatchinfo);
132469132704
sqlite3Fts3ExprFree(pCsr->pExpr);
132470132705
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
132471132706
132472132707
/* Set the lower and upper bounds on docids to return */
132473132708
pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -133774,11 +134009,11 @@
133774134009
if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
133775134010
iMax = a[i].iDocid;
133776134011
bMaxSet = 1;
133777134012
}
133778134013
}
133779
- assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
134014
+ assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
133780134015
assert( rc!=SQLITE_OK || bMaxSet );
133781134016
133782134017
/* Keep advancing iterators until they all point to the same document */
133783134018
for(i=0; i<p->nToken; i++){
133784134019
while( rc==SQLITE_OK && bEof==0
@@ -135891,11 +136126,11 @@
135891136126
int i = 0;
135892136127
135893136128
/* Set variable i to the maximum number of bytes of input to tokenize. */
135894136129
for(i=0; i<n; i++){
135895136130
if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
135896
- if( z[i]=='*' || z[i]=='"' ) break;
136131
+ if( z[i]=='"' ) break;
135897136132
}
135898136133
135899136134
*pnConsumed = i;
135900136135
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
135901136136
if( rc==SQLITE_OK ){
135902136137
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -231,11 +231,11 @@
231 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
232 ** [sqlite_version()] and [sqlite_source_id()].
233 */
234 #define SQLITE_VERSION "3.8.7"
235 #define SQLITE_VERSION_NUMBER 3008007
236 #define SQLITE_SOURCE_ID "2014-09-20 00:35:05 59e2c9df02d7e988c5ad44c560ead1e5288b12e7"
237
238 /*
239 ** CAPI3REF: Run-Time Library Version Numbers
240 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
241 **
@@ -2791,13 +2791,13 @@
2791 ** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
2792 ** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
2793 ** an English language description of the error following a failure of any
2794 ** of the sqlite3_open() routines.
2795 **
2796 ** ^The default encoding for the database will be UTF-8 if
2797 ** sqlite3_open() or sqlite3_open_v2() is called and
2798 ** UTF-16 in the native byte order if sqlite3_open16() is used.
2799 **
2800 ** Whether or not an error occurs when it is opened, resources
2801 ** associated with the [database connection] handle should be released by
2802 ** passing it to [sqlite3_close()] when it is no longer required.
2803 **
@@ -2881,17 +2881,18 @@
2881 ** ^SQLite uses the path component of the URI as the name of the disk file
2882 ** which contains the database. ^If the path begins with a '/' character,
2883 ** then it is interpreted as an absolute path. ^If the path does not begin
2884 ** with a '/' (meaning that the authority section is omitted from the URI)
2885 ** then the path is interpreted as a relative path.
2886 ** ^On windows, the first component of an absolute path
2887 ** is a drive specification (e.g. "C:").
2888 **
2889 ** [[core URI query parameters]]
2890 ** The query component of a URI may contain parameters that are interpreted
2891 ** either by SQLite itself, or by a [VFS | custom VFS implementation].
2892 ** SQLite interprets the following three query parameters:
 
2893 **
2894 ** <ul>
2895 ** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
2896 ** a VFS object that provides the operating system interface that should
2897 ** be used to access the database file on disk. ^If this option is set to
@@ -2922,15 +2923,13 @@
2922 ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
2923 ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
2924 ** a URI filename, its value overrides any behavior requested by setting
2925 ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
2926 **
2927 ** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
2928 ** "1") or "false" (or "off" or "no" or "0") to indicate that the
2929 ** [powersafe overwrite] property does or does not apply to the
2930 ** storage media on which the database file resides. ^The psow query
2931 ** parameter only works for the built-in unix and Windows VFSes.
2932 **
2933 ** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
2934 ** which if set disables file locking in rollback journal modes. This
2935 ** is useful for accessing a database on a filesystem that does not
2936 ** support locking. Caution: Database corruption might result if two
@@ -3521,15 +3520,14 @@
3521 ** terminated. If any NUL characters occur at byte offsets less than
3522 ** the value of the fourth parameter then the resulting string value will
3523 ** contain embedded NULs. The result of expressions involving strings
3524 ** with embedded NULs is undefined.
3525 **
3526 ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3527 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3528 ** string after SQLite has finished with it. ^The destructor is called
3529 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
3530 ** sqlite3_bind_text(), or sqlite3_bind_text16() fails.
3531 ** ^If the fifth argument is
3532 ** the special value [SQLITE_STATIC], then SQLite assumes that the
3533 ** information is in static, unmanaged space and does not need to be freed.
3534 ** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
3535 ** SQLite makes its own private copy of the data immediately, before
@@ -3536,11 +3534,11 @@
3536 ** the sqlite3_bind_*() routine returns.
3537 **
3538 ** ^The sixth argument to sqlite3_bind_text64() must be one of
3539 ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
3540 ** to specify the encoding of the text in the third parameter. If
3541 ** the sixth argument to sqlite3_bind_text64() is not how of the
3542 ** allowed values shown above, or if the text encoding is different
3543 ** from the encoding specified by the sixth parameter, then the behavior
3544 ** is undefined.
3545 **
3546 ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
@@ -4572,11 +4570,11 @@
4572 **
4573 ** ^The sqlite3_result_null() interface sets the return value
4574 ** of the application-defined function to be NULL.
4575 **
4576 ** ^The sqlite3_result_text(), sqlite3_result_text16(),
4577 ** sqlite3_result_text16le(), and sqlite3_result_text16be()
4578 ** set the return value of the application-defined function to be
4579 ** a text string which is represented as UTF-8, UTF-16 native byte order,
4580 ** UTF-16 little endian, or UTF-16 big endian, respectively.
4581 ** ^The sqlite3_result_text64() interface sets the return value of an
4582 ** application-defined function to be a text string in an encoding
@@ -6332,11 +6330,11 @@
6332 #define SQLITE_TESTCTRL_RESERVE 14
6333 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
6334 #define SQLITE_TESTCTRL_ISKEYWORD 16
6335 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17
6336 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
6337 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19
6338 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
6339 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
6340 #define SQLITE_TESTCTRL_BYTEORDER 22
6341 #define SQLITE_TESTCTRL_ISINIT 23
6342 #define SQLITE_TESTCTRL_SORTER_MMAP 24
@@ -7946,11 +7944,11 @@
7946 ** A macro to hint to the compiler that a function should not be
7947 ** inlined.
7948 */
7949 #if defined(__GNUC__)
7950 # define SQLITE_NOINLINE __attribute__((noinline))
7951 #elif defined(_MSC_VER)
7952 # define SQLITE_NOINLINE __declspec(noinline)
7953 #else
7954 # define SQLITE_NOINLINE
7955 #endif
7956
@@ -8519,10 +8517,15 @@
8519 ** Macros to compute minimum and maximum of two numbers.
8520 */
8521 #define MIN(A,B) ((A)<(B)?(A):(B))
8522 #define MAX(A,B) ((A)>(B)?(A):(B))
8523
 
 
 
 
 
8524 /*
8525 ** Check to see if this machine uses EBCDIC. (Yes, believe it or
8526 ** not, there are still machines out there that use EBCDIC.)
8527 */
8528 #if 'A' == '\301'
@@ -8756,10 +8759,20 @@
8756 # define SQLITE_ENABLE_STAT3_OR_STAT4 1
8757 #elif SQLITE_ENABLE_STAT3_OR_STAT4
8758 # undef SQLITE_ENABLE_STAT3_OR_STAT4
8759 #endif
8760
 
 
 
 
 
 
 
 
 
 
8761 /*
8762 ** An instance of the following structure is used to store the busy-handler
8763 ** callback for a given sqlite handle.
8764 **
8765 ** The sqlite.busyHandler member of the sqlite struct contains the busy
@@ -8895,10 +8908,11 @@
8895 typedef struct SrcList SrcList;
8896 typedef struct StrAccum StrAccum;
8897 typedef struct Table Table;
8898 typedef struct TableLock TableLock;
8899 typedef struct Token Token;
 
8900 typedef struct Trigger Trigger;
8901 typedef struct TriggerPrg TriggerPrg;
8902 typedef struct TriggerStep TriggerStep;
8903 typedef struct UnpackedRecord UnpackedRecord;
8904 typedef struct VTable VTable;
@@ -11308,10 +11322,11 @@
11308 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
11309 int nSample; /* Number of elements in aSample[] */
11310 int nSampleCol; /* Size of IndexSample.anEq[] and so on */
11311 tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
11312 IndexSample *aSample; /* Samples of the left-most key */
 
11313 #endif
11314 };
11315
11316 /*
11317 ** Allowed values for Index.idxType
@@ -11738,11 +11753,11 @@
11738 #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
11739 #define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
11740 #define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
11741 #define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
11742 #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
11743 #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */
11744 #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
11745 #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
11746 #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
11747 #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
11748 #define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
@@ -11823,10 +11838,13 @@
11823 struct Select {
11824 ExprList *pEList; /* The fields of the result */
11825 u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
11826 u16 selFlags; /* Various SF_* values */
11827 int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
 
 
 
11828 int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
11829 u64 nSelectRow; /* Estimated number of result rows */
11830 SrcList *pSrc; /* The FROM clause */
11831 Expr *pWhere; /* The WHERE clause */
11832 ExprList *pGroupBy; /* The GROUP BY clause */
@@ -12081,10 +12099,14 @@
12081 yDbMask cookieMask; /* Bitmask of schema verified databases */
12082 int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
12083 int regRowid; /* Register holding rowid of CREATE TABLE entry */
12084 int regRoot; /* Register holding root page number for new objects */
12085 int nMaxArg; /* Max args passed to user function by sub-program */
 
 
 
 
12086 #ifndef SQLITE_OMIT_SHARED_CACHE
12087 int nTableLock; /* Number of locks in aTableLock */
12088 TableLock *aTableLock; /* Required table locks for shared-cache mode */
12089 #endif
12090 AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
@@ -12160,15 +12182,15 @@
12160
12161 /*
12162 ** Bitfield flags for P5 value in various opcodes.
12163 */
12164 #define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */
 
12165 #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
12166 #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
12167 #define OPFLAG_APPEND 0x08 /* This is likely to be an append */
12168 #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
12169 #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
12170 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
12171 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
12172 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
12173 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
12174 #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
@@ -12428,10 +12450,21 @@
12428 Select *pSelect; /* The definition of this CTE */
12429 const char *zErr; /* Error message for circular references */
12430 } a[1];
12431 };
12432
 
 
 
 
 
 
 
 
 
 
 
12433 /*
12434 ** Assuming zIn points to the first byte of a UTF-8 character,
12435 ** advance zIn to point to the first byte of the next UTF-8 character.
12436 */
12437 #define SQLITE_SKIP_UTF8(zIn) { \
@@ -12493,10 +12526,11 @@
12493 # define sqlite3Isalpha(x) isalpha((unsigned char)(x))
12494 # define sqlite3Isdigit(x) isdigit((unsigned char)(x))
12495 # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
12496 # define sqlite3Tolower(x) tolower((unsigned char)(x))
12497 #endif
 
12498
12499 /*
12500 ** Internal function prototypes
12501 */
12502 #define sqlite3StrICmp sqlite3_stricmp
@@ -12591,29 +12625,18 @@
12591 #endif
12592 #if defined(SQLITE_TEST)
12593 SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
12594 #endif
12595
12596 /* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
12597 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
12598 SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe*);
12599 SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
12600 SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe*);
12601 SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe*);
12602 SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe*);
12603 SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe*);
12604 SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe*, Select*);
12605 SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe*, Expr*);
12606 SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe*, ExprList*);
12607 SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe*);
12608 #else
12609 # define sqlite3ExplainBegin(X)
12610 # define sqlite3ExplainSelect(A,B)
12611 # define sqlite3ExplainExpr(A,B)
12612 # define sqlite3ExplainExprList(A,B)
12613 # define sqlite3ExplainFinish(X)
12614 # define sqlite3VdbeExplanation(X) 0
12615 #endif
12616
12617
12618 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
12619 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
@@ -12791,11 +12814,11 @@
12791 SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
12792 SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
12793 SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
12794 SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
12795 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
12796 SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
12797 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
12798 SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
12799 SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
12800 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
12801 SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
@@ -12815,10 +12838,15 @@
12815 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
12816 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
12817 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
12818 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
12819 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
 
 
 
 
 
12820 SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
12821 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
12822 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
12823 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
12824 SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
@@ -13292,14 +13320,13 @@
13292 # define sqlite3MemdebugSetType(X,Y) /* no-op */
13293 # define sqlite3MemdebugHasType(X,Y) 1
13294 # define sqlite3MemdebugNoType(X,Y) 1
13295 #endif
13296 #define MEMTYPE_HEAP 0x01 /* General heap allocations */
13297 #define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
13298 #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
13299 #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
13300 #define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
13301
13302 /*
13303 ** Threading interface
13304 */
13305 #if SQLITE_MAX_WORKER_THREADS>0
@@ -13439,10 +13466,17 @@
13439 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
13440 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
13441 };
13442 #endif
13443
 
 
 
 
 
 
 
13444 #ifndef SQLITE_USE_URI
13445 # define SQLITE_USE_URI 0
13446 #endif
13447
13448 #ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
@@ -13945,11 +13979,11 @@
13945
13946 /* Since ArraySize(azCompileOpt) is normally in single digits, a
13947 ** linear search is adequate. No need for a binary search. */
13948 for(i=0; i<ArraySize(azCompileOpt); i++){
13949 if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
13950 && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0
13951 ){
13952 return 1;
13953 }
13954 }
13955 return 0;
@@ -14060,21 +14094,19 @@
14060 #ifdef SQLITE_DEBUG
14061 u8 seekOp; /* Most recent seek operation on this cursor */
14062 #endif
14063 i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
14064 u8 nullRow; /* True if pointing to a row with no data */
14065 u8 rowidIsValid; /* True if lastRowid is valid */
14066 u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
14067 Bool isEphemeral:1; /* True for an ephemeral table */
14068 Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
14069 Bool isTable:1; /* True if a table requiring integer keys */
14070 Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
14071 Pgno pgnoRoot; /* Root page of the open btree cursor */
14072 sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
14073 i64 seqCount; /* Sequence counter */
14074 i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
14075 i64 lastRowid; /* Rowid being deleted by OP_Delete */
14076 VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
14077
14078 /* Cached information about the header for the data record that the
14079 ** cursor is currently pointing to. Only valid if cacheStatus matches
14080 ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -14087,10 +14119,11 @@
14087 u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
14088 u32 payloadSize; /* Total number of bytes in the record */
14089 u32 szRow; /* Byte available in aRow */
14090 u32 iHdrOffset; /* Offset to next unparsed byte of the header */
14091 const u8 *aRow; /* Data for the current row, if all on one page */
 
14092 u32 aType[1]; /* Type values for all entries in the record */
14093 /* 2*nField extra array elements allocated for aType[], beyond the one
14094 ** static element declared in the structure. nField total array slots for
14095 ** aType[] and nField+1 array slots for aOffset[] */
14096 };
@@ -14163,11 +14196,11 @@
14163 int n; /* Number of characters in string value, excluding '\0' */
14164 char *z; /* String or BLOB value */
14165 /* ShallowCopy only needs to copy the information above */
14166 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
14167 int szMalloc; /* Size of the zMalloc allocation */
14168 int iPadding1; /* Padding for 8-byte alignment */
14169 sqlite3 *db; /* The associated database connection */
14170 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
14171 #ifdef SQLITE_DEBUG
14172 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
14173 void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
@@ -14259,11 +14292,10 @@
14259 */
14260 struct sqlite3_context {
14261 Mem *pOut; /* The return value is stored here */
14262 FuncDef *pFunc; /* Pointer to function information */
14263 Mem *pMem; /* Memory cell used to store aggregate context */
14264 CollSeq *pColl; /* Collating sequence */
14265 Vdbe *pVdbe; /* The VM that owns this context */
14266 int iOp; /* Instruction number of OP_Function */
14267 int isError; /* Error code returned by the function. */
14268 u8 skipFlag; /* Skip accumulator loading if true */
14269 u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
@@ -14348,14 +14380,10 @@
14348 i64 nFkConstraint; /* Number of imm. FK constraints this VM */
14349 i64 nStmtDefCons; /* Number of def. constraints when stmt started */
14350 i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
14351 char *zSql; /* Text of the SQL statement that generated this */
14352 void *pFree; /* Free this when deleting the vdbe */
14353 #ifdef SQLITE_ENABLE_TREE_EXPLAIN
14354 Explain *pExplain; /* The explainer */
14355 char *zExplain; /* Explanation of data structures */
14356 #endif
14357 VdbeFrame *pFrame; /* Parent frame */
14358 VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
14359 int nFrame; /* Number of frames in pFrame list */
14360 u32 expmask; /* Binding to these vars invalidates VM */
14361 SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
@@ -14376,10 +14404,11 @@
14376 ** Function prototypes
14377 */
14378 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
14379 void sqliteVdbePopStack(Vdbe*,int);
14380 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
 
14381 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
14382 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
14383 #endif
14384 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
14385 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
@@ -14675,11 +14704,11 @@
14675 sqlite3VdbeClearObject(db, pVdbe);
14676 sqlite3DbFree(db, pVdbe);
14677 }
14678 db->pnBytesFreed = 0;
14679
14680 *pHighwater = 0;
14681 *pCurrent = nByte;
14682
14683 break;
14684 }
14685
@@ -14700,21 +14729,23 @@
14700 if( db->aDb[i].pBt ){
14701 Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
14702 sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
14703 }
14704 }
14705 *pHighwater = 0;
 
 
14706 *pCurrent = nRet;
14707 break;
14708 }
14709
14710 /* Set *pCurrent to non-zero if there are unresolved deferred foreign
14711 ** key constraints. Set *pCurrent to zero if all foreign key constraints
14712 ** have been satisfied. The *pHighwater is always set to zero.
14713 */
14714 case SQLITE_DBSTATUS_DEFERRED_FKS: {
14715 *pHighwater = 0;
14716 *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
14717 break;
14718 }
14719
14720 default: {
@@ -17098,11 +17129,11 @@
17098 ** allocation p. Also return true if p==NULL.
17099 **
17100 ** This routine is designed for use within an assert() statement, to
17101 ** verify the type of an allocation. For example:
17102 **
17103 ** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
17104 */
17105 SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
17106 int rc = 1;
17107 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17108 struct MemBlockHdr *pHdr;
@@ -17120,11 +17151,11 @@
17120 ** allocation p. Also return true if p==NULL.
17121 **
17122 ** This routine is designed for use within an assert() statement, to
17123 ** verify the type of an allocation. For example:
17124 **
17125 ** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
17126 */
17127 SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
17128 int rc = 1;
17129 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17130 struct MemBlockHdr *pHdr;
@@ -20195,11 +20226,11 @@
20195 mallocWithAlarm((int)n, &p);
20196 sqlite3_mutex_leave(mem0.mutex);
20197 }else{
20198 p = sqlite3GlobalConfig.m.xMalloc((int)n);
20199 }
20200 assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */
20201 return p;
20202 }
20203
20204 /*
20205 ** This version of the memory allocation is for use by the application.
@@ -20332,39 +20363,41 @@
20332 ** Return the size of a memory allocation previously obtained from
20333 ** sqlite3Malloc() or sqlite3_malloc().
20334 */
20335 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
20336 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20337 assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
20338 return sqlite3GlobalConfig.m.xSize(p);
20339 }
20340 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
20341 if( db==0 ){
 
 
20342 return sqlite3MallocSize(p);
20343 }else{
20344 assert( sqlite3_mutex_held(db->mutex) );
20345 if( isLookaside(db, p) ){
20346 return db->lookaside.sz;
20347 }else{
20348 assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20349 assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20350 assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20351 return sqlite3GlobalConfig.m.xSize(p);
20352 }
20353 }
20354 }
20355 SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
 
 
20356 return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
20357 }
20358
20359 /*
20360 ** Free memory previously obtained from sqlite3Malloc().
20361 */
20362 SQLITE_API void sqlite3_free(void *p){
20363 if( p==0 ) return; /* IMP: R-49053-54554 */
20364 assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
20365 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
 
20366 if( sqlite3GlobalConfig.bMemstat ){
20367 sqlite3_mutex_enter(mem0.mutex);
20368 sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
20369 sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
20370 sqlite3GlobalConfig.m.xFree(p);
@@ -20404,12 +20437,12 @@
20404 db->lookaside.pFree = pBuf;
20405 db->lookaside.nOut--;
20406 return;
20407 }
20408 }
20409 assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20410 assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20411 assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20412 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20413 sqlite3_free(p);
20414 }
20415
@@ -20417,15 +20450,17 @@
20417 ** Change the size of an existing memory allocation
20418 */
20419 SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
20420 int nOld, nNew, nDiff;
20421 void *pNew;
 
 
20422 if( pOld==0 ){
20423 return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
20424 }
20425 if( nBytes==0 ){
20426 sqlite3_free(pOld); /* IMP: R-31593-10574 */
20427 return 0;
20428 }
20429 if( nBytes>=0x7fffff00 ){
20430 /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
20431 return 0;
@@ -20443,12 +20478,10 @@
20443 nDiff = nNew - nOld;
20444 if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
20445 mem0.alarmThreshold-nDiff ){
20446 sqlite3MallocAlarm(nDiff);
20447 }
20448 assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20449 assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
20450 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20451 if( pNew==0 && mem0.alarmCallback ){
20452 sqlite3MallocAlarm((int)nBytes);
20453 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20454 }
@@ -20458,11 +20491,11 @@
20458 }
20459 sqlite3_mutex_leave(mem0.mutex);
20460 }else{
20461 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20462 }
20463 assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
20464 return pNew;
20465 }
20466
20467 /*
20468 ** The public interface to sqlite3Realloc. Make sure that the memory
@@ -20470,11 +20503,11 @@
20470 */
20471 SQLITE_API void *sqlite3_realloc(void *pOld, int n){
20472 #ifndef SQLITE_OMIT_AUTOINIT
20473 if( sqlite3_initialize() ) return 0;
20474 #endif
20475 if( n<0 ) n = 0;
20476 return sqlite3Realloc(pOld, n);
20477 }
20478 SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
20479 #ifndef SQLITE_OMIT_AUTOINIT
20480 if( sqlite3_initialize() ) return 0;
@@ -20557,12 +20590,12 @@
20557 #endif
20558 p = sqlite3Malloc(n);
20559 if( !p && db ){
20560 db->mallocFailed = 1;
20561 }
20562 sqlite3MemdebugSetType(p, MEMTYPE_DB |
20563 ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20564 return p;
20565 }
20566
20567 /*
20568 ** Resize the block of memory pointed to by p to n bytes. If the
@@ -20584,19 +20617,18 @@
20584 if( pNew ){
20585 memcpy(pNew, p, db->lookaside.sz);
20586 sqlite3DbFree(db, p);
20587 }
20588 }else{
20589 assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
20590 assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
20591 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20592 pNew = sqlite3_realloc64(p, n);
20593 if( !pNew ){
20594 sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
20595 db->mallocFailed = 1;
20596 }
20597 sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
20598 (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20599 }
20600 }
20601 return pNew;
20602 }
@@ -21757,10 +21789,73 @@
21757 fprintf(stdout,"%s", zBuf);
21758 fflush(stdout);
21759 }
21760 #endif
21761
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21762 /*
21763 ** variable-argument wrapper around sqlite3VXPrintf().
21764 */
21765 SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
21766 va_list ap;
@@ -21996,18 +22091,18 @@
21996 #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
21997 /******************************** End Unix Pthreads *************************/
21998
21999
22000 /********************************* Win32 Threads ****************************/
22001 #if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
22002
22003 #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
22004 #include <process.h>
22005
22006 /* A running thread */
22007 struct SQLiteThread {
22008 uintptr_t tid; /* The thread handle */
22009 unsigned id; /* The thread identifier */
22010 void *(*xTask)(void*); /* The routine to run as a thread */
22011 void *pIn; /* Argument to xTask */
22012 void *pResult; /* Result of xTask */
22013 };
@@ -22051,11 +22146,11 @@
22051 if( sqlite3GlobalConfig.bCoreMutex==0 ){
22052 memset(p, 0, sizeof(*p));
22053 }else{
22054 p->xTask = xTask;
22055 p->pIn = pIn;
22056 p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
22057 if( p->tid==0 ){
22058 memset(p, 0, sizeof(*p));
22059 }
22060 }
22061 if( p->xTask==0 ){
@@ -22089,11 +22184,11 @@
22089 if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
22090 sqlite3_free(p);
22091 return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
22092 }
22093
22094 #endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
22095 /******************************** End Win32 Threads *************************/
22096
22097
22098 /********************************* Single-Threaded **************************/
22099 #ifndef SQLITE_THREADS_IMPLEMENTED
@@ -29659,11 +29754,11 @@
29659 ** methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
29660 **
29661 ** * An I/O method finder function called FINDER that returns a pointer
29662 ** to the METHOD object in the previous bullet.
29663 */
29664 #define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK) \
29665 static const sqlite3_io_methods METHOD = { \
29666 VERSION, /* iVersion */ \
29667 CLOSE, /* xClose */ \
29668 unixRead, /* xRead */ \
29669 unixWrite, /* xWrite */ \
@@ -29674,11 +29769,11 @@
29674 UNLOCK, /* xUnlock */ \
29675 CKLOCK, /* xCheckReservedLock */ \
29676 unixFileControl, /* xFileControl */ \
29677 unixSectorSize, /* xSectorSize */ \
29678 unixDeviceCharacteristics, /* xDeviceCapabilities */ \
29679 unixShmMap, /* xShmMap */ \
29680 unixShmLock, /* xShmLock */ \
29681 unixShmBarrier, /* xShmBarrier */ \
29682 unixShmUnmap, /* xShmUnmap */ \
29683 unixFetch, /* xFetch */ \
29684 unixUnfetch, /* xUnfetch */ \
@@ -29700,29 +29795,32 @@
29700 posixIoMethods, /* sqlite3_io_methods object name */
29701 3, /* shared memory and mmap are enabled */
29702 unixClose, /* xClose method */
29703 unixLock, /* xLock method */
29704 unixUnlock, /* xUnlock method */
29705 unixCheckReservedLock /* xCheckReservedLock method */
 
29706 )
29707 IOMETHODS(
29708 nolockIoFinder, /* Finder function name */
29709 nolockIoMethods, /* sqlite3_io_methods object name */
29710 3, /* shared memory is disabled */
29711 nolockClose, /* xClose method */
29712 nolockLock, /* xLock method */
29713 nolockUnlock, /* xUnlock method */
29714 nolockCheckReservedLock /* xCheckReservedLock method */
 
29715 )
29716 IOMETHODS(
29717 dotlockIoFinder, /* Finder function name */
29718 dotlockIoMethods, /* sqlite3_io_methods object name */
29719 1, /* shared memory is disabled */
29720 dotlockClose, /* xClose method */
29721 dotlockLock, /* xLock method */
29722 dotlockUnlock, /* xUnlock method */
29723 dotlockCheckReservedLock /* xCheckReservedLock method */
 
29724 )
29725
29726 #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
29727 IOMETHODS(
29728 flockIoFinder, /* Finder function name */
@@ -29729,11 +29827,12 @@
29729 flockIoMethods, /* sqlite3_io_methods object name */
29730 1, /* shared memory is disabled */
29731 flockClose, /* xClose method */
29732 flockLock, /* xLock method */
29733 flockUnlock, /* xUnlock method */
29734 flockCheckReservedLock /* xCheckReservedLock method */
 
29735 )
29736 #endif
29737
29738 #if OS_VXWORKS
29739 IOMETHODS(
@@ -29741,11 +29840,12 @@
29741 semIoMethods, /* sqlite3_io_methods object name */
29742 1, /* shared memory is disabled */
29743 semClose, /* xClose method */
29744 semLock, /* xLock method */
29745 semUnlock, /* xUnlock method */
29746 semCheckReservedLock /* xCheckReservedLock method */
 
29747 )
29748 #endif
29749
29750 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
29751 IOMETHODS(
@@ -29753,11 +29853,12 @@
29753 afpIoMethods, /* sqlite3_io_methods object name */
29754 1, /* shared memory is disabled */
29755 afpClose, /* xClose method */
29756 afpLock, /* xLock method */
29757 afpUnlock, /* xUnlock method */
29758 afpCheckReservedLock /* xCheckReservedLock method */
 
29759 )
29760 #endif
29761
29762 /*
29763 ** The proxy locking method is a "super-method" in the sense that it
@@ -29778,11 +29879,12 @@
29778 proxyIoMethods, /* sqlite3_io_methods object name */
29779 1, /* shared memory is disabled */
29780 proxyClose, /* xClose method */
29781 proxyLock, /* xLock method */
29782 proxyUnlock, /* xUnlock method */
29783 proxyCheckReservedLock /* xCheckReservedLock method */
 
29784 )
29785 #endif
29786
29787 /* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
29788 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
@@ -29791,11 +29893,12 @@
29791 nfsIoMethods, /* sqlite3_io_methods object name */
29792 1, /* shared memory is disabled */
29793 unixClose, /* xClose method */
29794 unixLock, /* xLock method */
29795 nfsUnlock, /* xUnlock method */
29796 unixCheckReservedLock /* xCheckReservedLock method */
 
29797 )
29798 #endif
29799
29800 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
29801 /*
@@ -33384,11 +33487,15 @@
33384 #endif
33385
33386 #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
33387 DWORD))aSyscall[63].pCurrent)
33388
 
33389 { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
 
 
 
33390
33391 #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
33392 BOOL))aSyscall[64].pCurrent)
33393
33394 #if SQLITE_OS_WINRT
@@ -33727,11 +33834,12 @@
33727 #else
33728 osSleep(milliseconds);
33729 #endif
33730 }
33731
33732 #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
 
33733 SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
33734 DWORD rc;
33735 while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
33736 TRUE))==WAIT_IO_COMPLETION ){}
33737 return rc;
@@ -39752,11 +39860,11 @@
39752 assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
39753 assert( pCache->n90pct == pCache->nMax*9/10 );
39754 if( createFlag==1 && (
39755 nPinned>=pGroup->mxPinned
39756 || nPinned>=pCache->n90pct
39757 || pcache1UnderMemoryPressure(pCache)
39758 )){
39759 return 0;
39760 }
39761
39762 if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
@@ -44373,17 +44481,19 @@
44373 if( !pNew ) rc = SQLITE_NOMEM;
44374 }
44375
44376 if( rc==SQLITE_OK ){
44377 pager_reset(pPager);
44378 sqlite3PageFree(pPager->pTmpSpace);
44379 pPager->pTmpSpace = pNew;
44380 rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
44381 }
44382 if( rc==SQLITE_OK ){
 
 
44383 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
44384 pPager->pageSize = pageSize;
 
 
44385 }
44386 }
44387
44388 *pPageSize = pPager->pageSize;
44389 if( rc==SQLITE_OK ){
@@ -51383,13 +51493,14 @@
51383 ** stored in MemPage.pBt->mutex.
51384 */
51385 struct MemPage {
51386 u8 isInit; /* True if previously initialized. MUST BE FIRST! */
51387 u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
51388 u8 intKey; /* True if intkey flag is set */
51389 u8 leaf; /* True if leaf flag is set */
51390 u8 hasData; /* True if this page stores data */
 
51391 u8 hdrOffset; /* 100 for page 1. 0 otherwise */
51392 u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
51393 u8 max1bytePayload; /* min(maxLocal,127) */
51394 u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
51395 u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
@@ -51545,11 +51656,11 @@
51545 int nRef; /* Number of references to this structure */
51546 BtShared *pNext; /* Next on a list of sharable BtShared structs */
51547 BtLock *pLock; /* List of locks held on this shared-btree struct */
51548 Btree *pWriter; /* Btree with currently open write transaction */
51549 #endif
51550 u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */
51551 };
51552
51553 /*
51554 ** Allowed values for BtShared.btsFlags
51555 */
@@ -51566,16 +51677,14 @@
51566 ** about a cell. The parseCellPtr() function fills in this structure
51567 ** based on information extract from the raw disk page.
51568 */
51569 typedef struct CellInfo CellInfo;
51570 struct CellInfo {
51571 i64 nKey; /* The key for INTKEY tables, or number of bytes in key */
51572 u8 *pCell; /* Pointer to the start of cell content */
51573 u32 nData; /* Number of bytes of data */
51574 u32 nPayload; /* Total amount of payload */
51575 u16 nHeader; /* Size of the cell content header in bytes */
51576 u16 nLocal; /* Amount of payload held locally */
51577 u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
51578 u16 nSize; /* Size of the cell content on the main b-tree page */
51579 };
51580
51581 /*
@@ -51768,10 +51877,12 @@
51768 u8 *aPgRef; /* 1 bit per page in the db (see above) */
51769 Pgno nPage; /* Number of pages in the database */
51770 int mxErr; /* Stop accumulating errors when this reaches zero */
51771 int nErr; /* Number of messages written to zErrMsg so far */
51772 int mallocFailed; /* A memory allocation error has occurred */
 
 
51773 StrAccum errMsg; /* Accumulate the error message text here */
51774 };
51775
51776 /*
51777 ** Routines to read or write a two- and four-byte big-endian integer values.
@@ -52554,11 +52665,13 @@
52554 ){
52555 BtCursor *p;
52556 BtShared *pBt = pBtree->pBt;
52557 assert( sqlite3BtreeHoldsMutex(pBtree) );
52558 for(p=pBt->pCursor; p; p=p->pNext){
52559 if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){
 
 
52560 p->eState = CURSOR_INVALID;
52561 }
52562 }
52563 }
52564
@@ -52727,13 +52840,13 @@
52727 ** the cursors if and when a cursor is found that actually requires saving.
52728 ** The common case is that no cursors need to be saved, so this routine is
52729 ** broken out from its caller to avoid unnecessary stack pointer movement.
52730 */
52731 static int SQLITE_NOINLINE saveCursorsOnList(
52732 BtCursor *p, /* The first cursor that needs saving */
52733 Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
52734 BtCursor *pExcept /* Do not save this cursor */
52735 ){
52736 do{
52737 if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
52738 if( p->eState==CURSOR_VALID ){
52739 int rc = saveCursorPosition(p);
@@ -52841,11 +52954,11 @@
52841 **
52842 ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
52843 ** back to where it ought to be if this routine returns true.
52844 */
52845 SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
52846 return pCur && pCur->eState!=CURSOR_VALID;
52847 }
52848
52849 /*
52850 ** This routine restores a cursor back to its original position after it
52851 ** has been moved by some outside activity (such as a btree rebalance or
@@ -53035,51 +53148,48 @@
53035 /*
53036 ** Parse a cell content block and fill in the CellInfo structure. There
53037 ** are two versions of this function. btreeParseCell() takes a
53038 ** cell index as the second argument and btreeParseCellPtr()
53039 ** takes a pointer to the body of the cell as its second argument.
53040 **
53041 ** Within this file, the parseCell() macro can be called instead of
53042 ** btreeParseCellPtr(). Using some compilers, this will be faster.
53043 */
53044 static void btreeParseCellPtr(
53045 MemPage *pPage, /* Page containing the cell */
53046 u8 *pCell, /* Pointer to the cell text. */
53047 CellInfo *pInfo /* Fill in this structure */
53048 ){
53049 u16 n; /* Number bytes in cell content header */
53050 u32 nPayload; /* Number of bytes of cell payload */
53051
53052 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
53053
53054 pInfo->pCell = pCell;
53055 assert( pPage->leaf==0 || pPage->leaf==1 );
53056 n = pPage->childPtrSize;
53057 assert( n==4-4*pPage->leaf );
53058 if( pPage->intKey ){
53059 if( pPage->hasData ){
53060 assert( n==0 );
53061 n = getVarint32(pCell, nPayload);
53062 }else{
53063 nPayload = 0;
53064 }
53065 n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
53066 pInfo->nData = nPayload;
53067 }else{
53068 pInfo->nData = 0;
53069 n += getVarint32(&pCell[n], nPayload);
 
53070 pInfo->nKey = nPayload;
53071 }
53072 pInfo->nPayload = nPayload;
53073 pInfo->nHeader = n;
53074 testcase( nPayload==pPage->maxLocal );
53075 testcase( nPayload==pPage->maxLocal+1 );
53076 if( likely(nPayload<=pPage->maxLocal) ){
53077 /* This is the (easy) common case where the entire payload fits
53078 ** on the local page. No overflow is required.
53079 */
53080 if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4;
 
53081 pInfo->nLocal = (u16)nPayload;
53082 pInfo->iOverflow = 0;
53083 }else{
53084 /* If the payload will not fit completely on the local page, we have
53085 ** to decide how much to store locally and how much to spill onto
@@ -53102,33 +53212,32 @@
53102 if( surplus <= maxLocal ){
53103 pInfo->nLocal = (u16)surplus;
53104 }else{
53105 pInfo->nLocal = (u16)minLocal;
53106 }
53107 pInfo->iOverflow = (u16)(pInfo->nLocal + n);
53108 pInfo->nSize = pInfo->iOverflow + 4;
53109 }
53110 }
53111 #define parseCell(pPage, iCell, pInfo) \
53112 btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
53113 static void btreeParseCell(
53114 MemPage *pPage, /* Page containing the cell */
53115 int iCell, /* The cell index. First cell is 0 */
53116 CellInfo *pInfo /* Fill in this structure */
53117 ){
53118 parseCell(pPage, iCell, pInfo);
53119 }
53120
53121 /*
53122 ** Compute the total number of bytes that a Cell needs in the cell
53123 ** data area of the btree-page. The return number includes the cell
53124 ** data header and the local payload, but not any overflow page or
53125 ** the space used by the cell pointer.
53126 */
53127 static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
53128 u8 *pIter = &pCell[pPage->childPtrSize];
53129 u32 nSize;
 
53130
53131 #ifdef SQLITE_DEBUG
53132 /* The value returned by this function should always be the same as
53133 ** the (CellInfo.nSize) value found by doing a full parse of the
53134 ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
@@ -53135,47 +53244,48 @@
53135 ** this function verifies that this invariant is not violated. */
53136 CellInfo debuginfo;
53137 btreeParseCellPtr(pPage, pCell, &debuginfo);
53138 #endif
53139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53140 if( pPage->intKey ){
53141 u8 *pEnd;
53142 if( pPage->hasData ){
53143 pIter += getVarint32(pIter, nSize);
53144 }else{
53145 nSize = 0;
53146 }
53147
53148 /* pIter now points at the 64-bit integer key value, a variable length
53149 ** integer. The following block moves pIter to point at the first byte
53150 ** past the end of the key value. */
53151 pEnd = &pIter[9];
53152 while( (*pIter++)&0x80 && pIter<pEnd );
53153 }else{
53154 pIter += getVarint32(pIter, nSize);
53155 }
53156
53157 testcase( nSize==pPage->maxLocal );
53158 testcase( nSize==pPage->maxLocal+1 );
53159 if( nSize>pPage->maxLocal ){
 
 
 
53160 int minLocal = pPage->minLocal;
53161 nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
53162 testcase( nSize==pPage->maxLocal );
53163 testcase( nSize==pPage->maxLocal+1 );
53164 if( nSize>pPage->maxLocal ){
53165 nSize = minLocal;
53166 }
53167 nSize += 4;
53168 }
53169 nSize += (u32)(pIter - pCell);
53170
53171 /* The minimum size of any cell is 4 bytes. */
53172 if( nSize<4 ){
53173 nSize = 4;
53174 }
53175
53176 assert( nSize==debuginfo.nSize );
53177 return (u16)nSize;
53178 }
53179
53180 #ifdef SQLITE_DEBUG
53181 /* This variation on cellSizePtr() is used inside of assert() statements
@@ -53194,11 +53304,10 @@
53194 static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
53195 CellInfo info;
53196 if( *pRC ) return;
53197 assert( pCell!=0 );
53198 btreeParseCellPtr(pPage, pCell, &info);
53199 assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
53200 if( info.iOverflow ){
53201 Pgno ovfl = get4byte(&pCell[info.iOverflow]);
53202 ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
53203 }
53204 }
@@ -53407,11 +53516,11 @@
53407 ** does it detect cells or freeblocks that encrouch into the reserved bytes
53408 ** at the end of the page. So do additional corruption checks inside this
53409 ** routine and return SQLITE_CORRUPT if any problems are found.
53410 */
53411 static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
53412 u16 iPtr; /* Address of pointer to next freeblock */
53413 u16 iFreeBlk; /* Address of the next freeblock */
53414 u8 hdr; /* Page header size. 0 or 100 */
53415 u8 nFrag = 0; /* Reduction in fragmentation */
53416 u16 iOrigSize = iSize; /* Original value of iSize */
53417 u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
@@ -53459,13 +53568,13 @@
53459 iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
53460 iSize = iEnd - iStart;
53461 iFreeBlk = get2byte(&data[iFreeBlk]);
53462 }
53463
53464 /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
53465 ** in the page header) then check to see if iStart should be coalesced
53466 ** onto the end of iPtr.
53467 */
53468 if( iPtr>hdr+1 ){
53469 int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
53470 if( iPtrEnd+3>=iStart ){
53471 if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
@@ -53515,16 +53624,18 @@
53515 flagByte &= ~PTF_LEAF;
53516 pPage->childPtrSize = 4-4*pPage->leaf;
53517 pBt = pPage->pBt;
53518 if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
53519 pPage->intKey = 1;
53520 pPage->hasData = pPage->leaf;
 
53521 pPage->maxLocal = pBt->maxLeaf;
53522 pPage->minLocal = pBt->minLeaf;
53523 }else if( flagByte==PTF_ZERODATA ){
53524 pPage->intKey = 0;
53525 pPage->hasData = 0;
 
53526 pPage->maxLocal = pBt->maxLocal;
53527 pPage->minLocal = pBt->minLocal;
53528 }else{
53529 return SQLITE_CORRUPT_BKPT;
53530 }
@@ -54175,11 +54286,12 @@
54175 #endif
54176 }
54177
54178 /*
54179 ** Make sure pBt->pTmpSpace points to an allocation of
54180 ** MX_CELL_SIZE(pBt) bytes.
 
54181 */
54182 static void allocateTempSpace(BtShared *pBt){
54183 if( !pBt->pTmpSpace ){
54184 pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
54185
@@ -54190,21 +54302,32 @@
54190 ** can mean that fillInCell() only initializes the first 2 or 3
54191 ** bytes of pTmpSpace, but that the first 4 bytes are copied from
54192 ** it into a database page. This is not actually a problem, but it
54193 ** does cause a valgrind error when the 1 or 2 bytes of unitialized
54194 ** data is passed to system call write(). So to avoid this error,
54195 ** zero the first 4 bytes of temp space here. */
54196 if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4);
 
 
 
 
 
 
 
 
54197 }
54198 }
54199
54200 /*
54201 ** Free the pBt->pTmpSpace allocation
54202 */
54203 static void freeTempSpace(BtShared *pBt){
54204 sqlite3PageFree( pBt->pTmpSpace);
54205 pBt->pTmpSpace = 0;
 
 
 
54206 }
54207
54208 /*
54209 ** Close an open database and invalidate all cursors.
54210 */
@@ -54694,15 +54817,15 @@
54694 */
54695 static void unlockBtreeIfUnused(BtShared *pBt){
54696 assert( sqlite3_mutex_held(pBt->mutex) );
54697 assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE );
54698 if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
54699 assert( pBt->pPage1->aData );
 
54700 assert( sqlite3PagerRefcount(pBt->pPager)==1 );
54701 assert( pBt->pPage1->aData );
54702 releasePage(pBt->pPage1);
54703 pBt->pPage1 = 0;
 
54704 }
54705 }
54706
54707 /*
54708 ** If pBt points to an empty file then convert that empty file
@@ -55739,10 +55862,14 @@
55739 assert( pBt->pPage1 && pBt->pPage1->aData );
55740
55741 if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
55742 return SQLITE_READONLY;
55743 }
 
 
 
 
55744 if( iTable==1 && btreePagecount(pBt)==0 ){
55745 assert( wrFlag==0 );
55746 iTable = 0;
55747 }
55748
@@ -55928,12 +56055,13 @@
55928 ** to return an integer result code for historical reasons.
55929 */
55930 SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
55931 assert( cursorHoldsMutex(pCur) );
55932 assert( pCur->eState==CURSOR_VALID );
 
55933 getCellInfo(pCur);
55934 *pSize = pCur->info.nData;
55935 return SQLITE_OK;
55936 }
55937
55938 /*
55939 ** Given the page number of an overflow page in the database (parameter
@@ -56080,34 +56208,32 @@
56080 unsigned char *pBuf, /* Write the bytes into this buffer */
56081 int eOp /* zero to read. non-zero to write. */
56082 ){
56083 unsigned char *aPayload;
56084 int rc = SQLITE_OK;
56085 u32 nKey;
56086 int iIdx = 0;
56087 MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
56088 BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
56089 #ifdef SQLITE_DIRECT_OVERFLOW_READ
56090 int bEnd; /* True if reading to end of data */
 
56091 #endif
56092
56093 assert( pPage );
56094 assert( pCur->eState==CURSOR_VALID );
56095 assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
56096 assert( cursorHoldsMutex(pCur) );
56097 assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */
56098
56099 getCellInfo(pCur);
56100 aPayload = pCur->info.pCell + pCur->info.nHeader;
56101 nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
56102 #ifdef SQLITE_DIRECT_OVERFLOW_READ
56103 bEnd = (offset+amt==nKey+pCur->info.nData);
56104 #endif
 
56105
56106 if( NEVER(offset+amt > nKey+pCur->info.nData)
56107 || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
56108 ){
56109 /* Trying to read or write past the end of the data is an error */
56110 return SQLITE_CORRUPT_BKPT;
56111 }
56112
56113 /* Check if data must be read/written to/from the btree page itself. */
@@ -56159,11 +56285,13 @@
56159
56160 /* If the overflow page-list cache has been allocated and the
56161 ** entry for the first required overflow page is valid, skip
56162 ** directly to it.
56163 */
56164 if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){
 
 
56165 iIdx = (offset/ovflSize);
56166 nextPage = pCur->aOverflow[iIdx];
56167 offset = (offset%ovflSize);
56168 }
56169
@@ -56212,10 +56340,11 @@
56212 ** 2) data is required from the start of this overflow page, and
56213 ** 3) the database is file-backed, and
56214 ** 4) there is no open write-transaction, and
56215 ** 5) the database is not a WAL database,
56216 ** 6) all data from the page is being read.
 
56217 **
56218 ** then data can be read directly from the database file into the
56219 ** output buffer, bypassing the page-cache altogether. This speeds
56220 ** up loading large records that span many overflow pages.
56221 */
@@ -56223,13 +56352,15 @@
56223 && offset==0 /* (2) */
56224 && (bEnd || a==ovflSize) /* (6) */
56225 && pBt->inTransaction==TRANS_READ /* (4) */
56226 && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
56227 && pBt->pPage1->aData[19]==0x01 /* (5) */
 
56228 ){
56229 u8 aSave[4];
56230 u8 *aWrite = &pBuf[-4];
 
56231 memcpy(aSave, aWrite, 4);
56232 rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
56233 nextPage = get4byte(aWrite);
56234 memcpy(aWrite, aSave, 4);
56235 }else
@@ -56337,11 +56468,11 @@
56337 assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
56338 assert( cursorHoldsMutex(pCur) );
56339 assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
56340 assert( pCur->info.nSize>0 );
56341 *pAmt = pCur->info.nLocal;
56342 return (void*)(pCur->info.pCell + pCur->info.nHeader);
56343 }
56344
56345
56346 /*
56347 ** For the entry that cursor pCur is point to, return as
@@ -56765,11 +56896,11 @@
56765 pCur->aiIdx[pCur->iPage] = (u16)idx;
56766 if( xRecordCompare==0 ){
56767 for(;;){
56768 i64 nCellKey;
56769 pCell = findCell(pPage, idx) + pPage->childPtrSize;
56770 if( pPage->hasData ){
56771 while( 0x80 <= *(pCell++) ){
56772 if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
56773 }
56774 }
56775 getVarint(pCell, (u64*)&nCellKey);
@@ -57024,13 +57155,13 @@
57024 ** was already pointing to the first entry in the database before
57025 ** this routine was called, then set *pRes=1.
57026 **
57027 ** The main entry point is sqlite3BtreePrevious(). That routine is optimized
57028 ** for the common case of merely decrementing the cell counter BtCursor.aiIdx
57029 ** to the previous cell on the current page. The (slower) btreePrevious() helper
57030 ** routine is called when it is necessary to move to a different page or
57031 ** to restore the cursor.
57032 **
57033 ** The calling function will set *pRes to 0 or 1. The initial *pRes value
57034 ** will be 1 if the cursor being stepped corresponds to an SQL index and
57035 ** if this routine could have been skipped if that SQL index had been
57036 ** a unique index. Otherwise the caller will have set *pRes to zero.
@@ -57048,12 +57179,11 @@
57048 assert( *pRes==0 );
57049 assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
57050 assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
57051 assert( pCur->info.nSize==0 );
57052 if( pCur->eState!=CURSOR_VALID ){
57053 assert( pCur->eState>=CURSOR_REQUIRESEEK );
57054 rc = btreeRestoreCursorPosition(pCur);
57055 if( rc!=SQLITE_OK ){
57056 return rc;
57057 }
57058 if( CURSOR_INVALID==pCur->eState ){
57059 *pRes = 1;
@@ -57354,11 +57484,11 @@
57354 if( rc ) goto end_allocate_page;
57355 if( closest<k-1 ){
57356 memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
57357 }
57358 put4byte(&aData[4], k-1);
57359 noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
57360 rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
57361 if( rc==SQLITE_OK ){
57362 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
57363 if( rc!=SQLITE_OK ){
57364 releasePage(*ppPage);
@@ -57387,11 +57517,11 @@
57387 ** content for any page that really does lie past the end of the database
57388 ** file on disk. So the effects of disabling the no-content optimization
57389 ** here are confined to those pages that lie between the end of the
57390 ** database image and the end of the database file.
57391 */
57392 int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;
57393
57394 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
57395 if( rc ) return rc;
57396 pBt->nPage++;
57397 if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
@@ -57586,22 +57716,29 @@
57586 *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
57587 }
57588 }
57589
57590 /*
57591 ** Free any overflow pages associated with the given Cell.
 
 
57592 */
57593 static int clearCell(MemPage *pPage, unsigned char *pCell){
 
 
 
 
57594 BtShared *pBt = pPage->pBt;
57595 CellInfo info;
57596 Pgno ovflPgno;
57597 int rc;
57598 int nOvfl;
57599 u32 ovflPageSize;
57600
57601 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
57602 btreeParseCellPtr(pPage, pCell, &info);
 
57603 if( info.iOverflow==0 ){
57604 return SQLITE_OK; /* No overflow pages. Return without doing anything */
57605 }
57606 if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
57607 return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
@@ -57681,54 +57818,87 @@
57681 unsigned char *pPrior;
57682 unsigned char *pPayload;
57683 BtShared *pBt = pPage->pBt;
57684 Pgno pgnoOvfl = 0;
57685 int nHeader;
57686 CellInfo info;
57687
57688 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
57689
57690 /* pPage is not necessarily writeable since pCell might be auxiliary
57691 ** buffer space that is separate from the pPage buffer area */
57692 assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
57693 || sqlite3PagerIswriteable(pPage->pDbPage) );
57694
57695 /* Fill in the header. */
57696 nHeader = 0;
57697 if( !pPage->leaf ){
57698 nHeader += 4;
57699 }
57700 if( pPage->hasData ){
57701 nHeader += putVarint32(&pCell[nHeader], nData+nZero);
57702 }else{
57703 nData = nZero = 0;
 
57704 }
57705 nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
57706 btreeParseCellPtr(pPage, pCell, &info);
57707 assert( info.nHeader==nHeader );
57708 assert( info.nKey==nKey );
57709 assert( info.nData==(u32)(nData+nZero) );
57710
57711 /* Fill in the payload */
57712 nPayload = nData + nZero;
57713 if( pPage->intKey ){
57714 pSrc = pData;
57715 nSrc = nData;
57716 nData = 0;
57717 }else{
57718 if( NEVER(nKey>0x7fffffff || pKey==0) ){
57719 return SQLITE_CORRUPT_BKPT;
57720 }
57721 nPayload += (int)nKey;
57722 pSrc = pKey;
57723 nSrc = (int)nKey;
57724 }
57725 *pnSize = info.nSize;
57726 spaceLeft = info.nLocal;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57727 pPayload = &pCell[nHeader];
57728 pPrior = &pCell[info.iOverflow];
57729
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57730 while( nPayload>0 ){
57731 if( spaceLeft==0 ){
57732 #ifndef SQLITE_OMIT_AUTOVACUUM
57733 Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
57734 if( pBt->autoVacuum ){
@@ -57865,15 +58035,10 @@
57865 ** pTemp is not null. Regardless of pTemp, allocate a new entry
57866 ** in pPage->apOvfl[] and make it point to the cell content (either
57867 ** in pTemp or the original pCell) and also record its index.
57868 ** Allocating a new entry in pPage->aCell[] implies that
57869 ** pPage->nOverflow is incremented.
57870 **
57871 ** If nSkip is non-zero, then do not copy the first nSkip bytes of the
57872 ** cell. The caller will overwrite them after this function returns. If
57873 ** nSkip is non-zero, then pCell may not point to an invalid memory location
57874 ** (but pCell+nSkip is always valid).
57875 */
57876 static void insertCell(
57877 MemPage *pPage, /* Page into which we are copying */
57878 int i, /* New cell becomes the i-th cell of the page */
57879 u8 *pCell, /* Content of the new cell */
@@ -57886,11 +58051,10 @@
57886 int j; /* Loop counter */
57887 int end; /* First byte past the last cell pointer in data[] */
57888 int ins; /* Index in data[] where new cell pointer is inserted */
57889 int cellOffset; /* Address of first cell pointer in data[] */
57890 u8 *data; /* The content of the whole page */
57891 int nSkip = (iChild ? 4 : 0);
57892
57893 if( *pRC ) return;
57894
57895 assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
57896 assert( MX_CELL(pPage->pBt)<=10921 );
@@ -57904,11 +58068,11 @@
57904 ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
57905 ** the term after the || in the following assert(). */
57906 assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
57907 if( pPage->nOverflow || sz+2>pPage->nFree ){
57908 if( pTemp ){
57909 memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
57910 pCell = pTemp;
57911 }
57912 if( iChild ){
57913 put4byte(pCell, iChild);
57914 }
@@ -57933,11 +58097,11 @@
57933 ** if it returns success */
57934 assert( idx >= end+2 );
57935 assert( idx+sz <= (int)pPage->pBt->usableSize );
57936 pPage->nCell++;
57937 pPage->nFree -= (u16)(2 + sz);
57938 memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
57939 if( iChild ){
57940 put4byte(&data[idx], iChild);
57941 }
57942 memmove(&data[ins+2], &data[ins], end-ins);
57943 put2byte(&data[ins], idx);
@@ -58432,11 +58596,11 @@
58432 **
58433 ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
58434 ** leafData: 1 if pPage holds key+data and pParent holds only keys.
58435 */
58436 leafCorrection = apOld[0]->leaf*4;
58437 leafData = apOld[0]->hasData;
58438 for(i=0; i<nOld; i++){
58439 int limit;
58440
58441 /* Before doing anything else, take a copy of the i'th original sibling
58442 ** The rest of this function will use data from the copies rather
@@ -59008,11 +59172,11 @@
59008 int const iIdx = pCur->aiIdx[iPage-1];
59009
59010 rc = sqlite3PagerWrite(pParent->pDbPage);
59011 if( rc==SQLITE_OK ){
59012 #ifndef SQLITE_OMIT_QUICKBALANCE
59013 if( pPage->hasData
59014 && pPage->nOverflow==1
59015 && pPage->aiOvfl[0]==pPage->nCell
59016 && pParent->pgno!=1
59017 && pParent->nCell==iIdx
59018 ){
@@ -59127,11 +59291,12 @@
59127 assert( pCur->skipNext!=SQLITE_OK );
59128 return pCur->skipNext;
59129 }
59130
59131 assert( cursorHoldsMutex(pCur) );
59132 assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE
 
59133 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
59134 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
59135
59136 /* Assert that the caller has been consistent. If this cursor was opened
59137 ** expecting an index b-tree, then the caller should be inserting blob
@@ -59160,11 +59325,12 @@
59160 invalidateIncrblobCursors(p, nKey, 0);
59161
59162 /* If the cursor is currently on the last row and we are appending a
59163 ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
59164 ** call */
59165 if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){
 
59166 loc = -1;
59167 }
59168 }
59169
59170 if( !loc ){
@@ -59179,13 +59345,12 @@
59179
59180 TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
59181 pCur->pgnoRoot, nKey, nData, pPage->pgno,
59182 loc==0 ? "overwrite" : "new entry"));
59183 assert( pPage->isInit );
59184 allocateTempSpace(pBt);
59185 newCell = pBt->pTmpSpace;
59186 if( newCell==0 ) return SQLITE_NOMEM;
59187 rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
59188 if( rc ) goto end_insert;
59189 assert( szNew==cellSizePtr(pPage, newCell) );
59190 assert( szNew <= MX_CELL_SIZE(pBt) );
59191 idx = pCur->aiIdx[pCur->iPage];
@@ -59198,12 +59363,11 @@
59198 }
59199 oldCell = findCell(pPage, idx);
59200 if( !pPage->leaf ){
59201 memcpy(newCell, oldCell, 4);
59202 }
59203 szOld = cellSizePtr(pPage, oldCell);
59204 rc = clearCell(pPage, oldCell);
59205 dropCell(pPage, idx, szOld, &rc);
59206 if( rc ) goto end_insert;
59207 }else if( loc<0 && pPage->nCell>0 ){
59208 assert( pPage->leaf );
59209 idx = ++pCur->aiIdx[pCur->iPage];
@@ -59261,10 +59425,11 @@
59261 int rc; /* Return code */
59262 MemPage *pPage; /* Page to delete cell from */
59263 unsigned char *pCell; /* Pointer to cell to delete */
59264 int iCellIdx; /* Index of cell to delete */
59265 int iCellDepth; /* Depth of node containing pCell */
 
59266
59267 assert( cursorHoldsMutex(pCur) );
59268 assert( pBt->inTransaction==TRANS_WRITE );
59269 assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
59270 assert( pCur->curFlags & BTCF_WriteFlag );
@@ -59309,12 +59474,12 @@
59309 invalidateIncrblobCursors(p, pCur->info.nKey, 0);
59310 }
59311
59312 rc = sqlite3PagerWrite(pPage->pDbPage);
59313 if( rc ) return rc;
59314 rc = clearCell(pPage, pCell);
59315 dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
59316 if( rc ) return rc;
59317
59318 /* If the cell deleted was not located on a leaf page, then the cursor
59319 ** is currently pointing to the largest entry in the sub-tree headed
59320 ** by the child-page of the cell that was just deleted from an internal
@@ -59327,14 +59492,12 @@
59327 unsigned char *pTmp;
59328
59329 pCell = findCell(pLeaf, pLeaf->nCell-1);
59330 nCell = cellSizePtr(pLeaf, pCell);
59331 assert( MX_CELL_SIZE(pBt) >= nCell );
59332
59333 allocateTempSpace(pBt);
59334 pTmp = pBt->pTmpSpace;
59335
59336 rc = sqlite3PagerWrite(pLeaf->pDbPage);
59337 insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
59338 dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
59339 if( rc ) return rc;
59340 }
@@ -59542,10 +59705,11 @@
59542 MemPage *pPage;
59543 int rc;
59544 unsigned char *pCell;
59545 int i;
59546 int hdr;
 
59547
59548 assert( sqlite3_mutex_held(pBt->mutex) );
59549 if( pgno>btreePagecount(pBt) ){
59550 return SQLITE_CORRUPT_BKPT;
59551 }
@@ -59557,11 +59721,11 @@
59557 pCell = findCell(pPage, i);
59558 if( !pPage->leaf ){
59559 rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
59560 if( rc ) goto cleardatabasepage_out;
59561 }
59562 rc = clearCell(pPage, pCell);
59563 if( rc ) goto cleardatabasepage_out;
59564 }
59565 if( !pPage->leaf ){
59566 rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
59567 if( rc ) goto cleardatabasepage_out;
@@ -59903,24 +60067,25 @@
59903 /*
59904 ** Append a message to the error message string.
59905 */
59906 static void checkAppendMsg(
59907 IntegrityCk *pCheck,
59908 char *zMsg1,
59909 const char *zFormat,
59910 ...
59911 ){
59912 va_list ap;
 
59913 if( !pCheck->mxErr ) return;
59914 pCheck->mxErr--;
59915 pCheck->nErr++;
59916 va_start(ap, zFormat);
59917 if( pCheck->errMsg.nChar ){
59918 sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
59919 }
59920 if( zMsg1 ){
59921 sqlite3StrAccumAppendAll(&pCheck->errMsg, zMsg1);
 
59922 }
59923 sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
59924 va_end(ap);
59925 if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
59926 pCheck->mallocFailed = 1;
@@ -59954,18 +60119,18 @@
59954 ** Return 1 if there are 2 or more references to the page and 0 if
59955 ** if this is the first reference to the page.
59956 **
59957 ** Also check that the page number is in bounds.
59958 */
59959 static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
59960 if( iPage==0 ) return 1;
59961 if( iPage>pCheck->nPage ){
59962 checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
59963 return 1;
59964 }
59965 if( getPageReferenced(pCheck, iPage) ){
59966 checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
59967 return 1;
59968 }
59969 setPageReferenced(pCheck, iPage);
59970 return 0;
59971 }
@@ -59978,26 +60143,25 @@
59978 */
59979 static void checkPtrmap(
59980 IntegrityCk *pCheck, /* Integrity check context */
59981 Pgno iChild, /* Child page number */
59982 u8 eType, /* Expected pointer map type */
59983 Pgno iParent, /* Expected pointer map parent page number */
59984 char *zContext /* Context description (used for error msg) */
59985 ){
59986 int rc;
59987 u8 ePtrmapType;
59988 Pgno iPtrmapParent;
59989
59990 rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
59991 if( rc!=SQLITE_OK ){
59992 if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
59993 checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
59994 return;
59995 }
59996
59997 if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
59998 checkAppendMsg(pCheck, zContext,
59999 "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
60000 iChild, eType, iParent, ePtrmapType, iPtrmapParent);
60001 }
60002 }
60003 #endif
@@ -60008,51 +60172,50 @@
60008 */
60009 static void checkList(
60010 IntegrityCk *pCheck, /* Integrity checking context */
60011 int isFreeList, /* True for a freelist. False for overflow page list */
60012 int iPage, /* Page number for first page in the list */
60013 int N, /* Expected number of pages in the list */
60014 char *zContext /* Context for error messages */
60015 ){
60016 int i;
60017 int expected = N;
60018 int iFirst = iPage;
60019 while( N-- > 0 && pCheck->mxErr ){
60020 DbPage *pOvflPage;
60021 unsigned char *pOvflData;
60022 if( iPage<1 ){
60023 checkAppendMsg(pCheck, zContext,
60024 "%d of %d pages missing from overflow list starting at %d",
60025 N+1, expected, iFirst);
60026 break;
60027 }
60028 if( checkRef(pCheck, iPage, zContext) ) break;
60029 if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
60030 checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
60031 break;
60032 }
60033 pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
60034 if( isFreeList ){
60035 int n = get4byte(&pOvflData[4]);
60036 #ifndef SQLITE_OMIT_AUTOVACUUM
60037 if( pCheck->pBt->autoVacuum ){
60038 checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
60039 }
60040 #endif
60041 if( n>(int)pCheck->pBt->usableSize/4-2 ){
60042 checkAppendMsg(pCheck, zContext,
60043 "freelist leaf count too big on page %d", iPage);
60044 N--;
60045 }else{
60046 for(i=0; i<n; i++){
60047 Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
60048 #ifndef SQLITE_OMIT_AUTOVACUUM
60049 if( pCheck->pBt->autoVacuum ){
60050 checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
60051 }
60052 #endif
60053 checkRef(pCheck, iFreePage, zContext);
60054 }
60055 N -= n;
60056 }
60057 }
60058 #ifndef SQLITE_OMIT_AUTOVACUUM
@@ -60061,11 +60224,11 @@
60061 ** page in this overflow list, check that the pointer-map entry for
60062 ** the following page matches iPage.
60063 */
60064 if( pCheck->pBt->autoVacuum && N>0 ){
60065 i = get4byte(pOvflData);
60066 checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
60067 }
60068 }
60069 #endif
60070 iPage = get4byte(pOvflData);
60071 sqlite3PagerUnref(pOvflPage);
@@ -60093,11 +60256,10 @@
60093 ** the root of the tree.
60094 */
60095 static int checkTreePage(
60096 IntegrityCk *pCheck, /* Context for the sanity check */
60097 int iPage, /* Page number of the page to check */
60098 char *zParentContext, /* Parent context */
60099 i64 *pnParentMinKey,
60100 i64 *pnParentMaxKey
60101 ){
60102 MemPage *pPage;
60103 int i, rc, depth, d2, pgno, cnt;
@@ -60104,38 +60266,42 @@
60104 int hdr, cellStart;
60105 int nCell;
60106 u8 *data;
60107 BtShared *pBt;
60108 int usableSize;
60109 char zContext[100];
60110 char *hit = 0;
60111 i64 nMinKey = 0;
60112 i64 nMaxKey = 0;
60113
60114 sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
 
60115
60116 /* Check that the page exists
60117 */
60118 pBt = pCheck->pBt;
60119 usableSize = pBt->usableSize;
60120 if( iPage==0 ) return 0;
60121 if( checkRef(pCheck, iPage, zParentContext) ) return 0;
 
 
60122 if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
60123 checkAppendMsg(pCheck, zContext,
60124 "unable to get the page. error code=%d", rc);
60125 return 0;
 
60126 }
60127
60128 /* Clear MemPage.isInit to make sure the corruption detection code in
60129 ** btreeInitPage() is executed. */
60130 pPage->isInit = 0;
60131 if( (rc = btreeInitPage(pPage))!=0 ){
60132 assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */
60133 checkAppendMsg(pCheck, zContext,
60134 "btreeInitPage() returns error code %d", rc);
60135 releasePage(pPage);
60136 return 0;
 
60137 }
60138
60139 /* Check out all the cells.
60140 */
60141 depth = 0;
@@ -60144,99 +60310,101 @@
60144 u32 sz;
60145 CellInfo info;
60146
60147 /* Check payload overflow pages
60148 */
60149 sqlite3_snprintf(sizeof(zContext), zContext,
60150 "On tree page %d cell %d: ", iPage, i);
 
60151 pCell = findCell(pPage,i);
60152 btreeParseCellPtr(pPage, pCell, &info);
60153 sz = info.nData;
60154 if( !pPage->intKey ) sz += (int)info.nKey;
60155 /* For intKey pages, check that the keys are in order.
60156 */
60157 else if( i==0 ) nMinKey = nMaxKey = info.nKey;
60158 else{
60159 if( info.nKey <= nMaxKey ){
60160 checkAppendMsg(pCheck, zContext,
60161 "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
 
60162 }
60163 nMaxKey = info.nKey;
60164 }
60165 assert( sz==info.nPayload );
60166 if( (sz>info.nLocal)
60167 && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
60168 ){
60169 int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
60170 Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
60171 #ifndef SQLITE_OMIT_AUTOVACUUM
60172 if( pBt->autoVacuum ){
60173 checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
60174 }
60175 #endif
60176 checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
60177 }
60178
60179 /* Check sanity of left child page.
60180 */
60181 if( !pPage->leaf ){
60182 pgno = get4byte(pCell);
60183 #ifndef SQLITE_OMIT_AUTOVACUUM
60184 if( pBt->autoVacuum ){
60185 checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
60186 }
60187 #endif
60188 d2 = checkTreePage(pCheck, pgno, zContext, &nMinKey, i==0 ? NULL : &nMaxKey);
60189 if( i>0 && d2!=depth ){
60190 checkAppendMsg(pCheck, zContext, "Child page depth differs");
60191 }
60192 depth = d2;
60193 }
60194 }
60195
60196 if( !pPage->leaf ){
60197 pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
60198 sqlite3_snprintf(sizeof(zContext), zContext,
60199 "On page %d at right child: ", iPage);
60200 #ifndef SQLITE_OMIT_AUTOVACUUM
60201 if( pBt->autoVacuum ){
60202 checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
60203 }
60204 #endif
60205 checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
60206 }
60207
60208 /* For intKey leaf pages, check that the min/max keys are in order
60209 ** with any left/parent/right pages.
60210 */
 
 
60211 if( pPage->leaf && pPage->intKey ){
60212 /* if we are a left child page */
60213 if( pnParentMinKey ){
60214 /* if we are the left most child page */
60215 if( !pnParentMaxKey ){
60216 if( nMaxKey > *pnParentMinKey ){
60217 checkAppendMsg(pCheck, zContext,
60218 "Rowid %lld out of order (max larger than parent min of %lld)",
60219 nMaxKey, *pnParentMinKey);
60220 }
60221 }else{
60222 if( nMinKey <= *pnParentMinKey ){
60223 checkAppendMsg(pCheck, zContext,
60224 "Rowid %lld out of order (min less than parent min of %lld)",
60225 nMinKey, *pnParentMinKey);
60226 }
60227 if( nMaxKey > *pnParentMaxKey ){
60228 checkAppendMsg(pCheck, zContext,
60229 "Rowid %lld out of order (max larger than parent max of %lld)",
60230 nMaxKey, *pnParentMaxKey);
60231 }
60232 *pnParentMinKey = nMaxKey;
60233 }
60234 /* else if we're a right child page */
60235 } else if( pnParentMaxKey ){
60236 if( nMinKey <= *pnParentMaxKey ){
60237 checkAppendMsg(pCheck, zContext,
60238 "Rowid %lld out of order (min less than parent max of %lld)",
60239 nMinKey, *pnParentMaxKey);
60240 }
60241 }
60242 }
@@ -60244,10 +60412,11 @@
60244 /* Check for complete coverage of the page
60245 */
60246 data = pPage->aData;
60247 hdr = pPage->hdrOffset;
60248 hit = sqlite3PageMalloc( pBt->pageSize );
 
60249 if( hit==0 ){
60250 pCheck->mallocFailed = 1;
60251 }else{
60252 int contentOffset = get2byteNotZero(&data[hdr+5]);
60253 assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
@@ -60261,11 +60430,12 @@
60261 int j;
60262 if( pc<=usableSize-4 ){
60263 size = cellSizePtr(pPage, &data[pc]);
60264 }
60265 if( (int)(pc+size-1)>=usableSize ){
60266 checkAppendMsg(pCheck, 0,
 
60267 "Corruption detected in cell %d on page %d",i,iPage);
60268 }else{
60269 for(j=pc+size-1; j>=pc; j--) hit[j]++;
60270 }
60271 }
@@ -60283,23 +60453,28 @@
60283 }
60284 for(i=cnt=0; i<usableSize; i++){
60285 if( hit[i]==0 ){
60286 cnt++;
60287 }else if( hit[i]>1 ){
60288 checkAppendMsg(pCheck, 0,
60289 "Multiple uses for byte %d of page %d", i, iPage);
60290 break;
60291 }
60292 }
60293 if( cnt!=data[hdr+7] ){
60294 checkAppendMsg(pCheck, 0,
60295 "Fragmentation of %d bytes reported as %d on page %d",
60296 cnt, data[hdr+7], iPage);
60297 }
60298 }
60299 sqlite3PageFree(hit);
60300 releasePage(pPage);
 
 
 
 
 
60301 return depth+1;
60302 }
60303 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
60304
60305 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
@@ -60336,10 +60511,13 @@
60336 sCheck.pPager = pBt->pPager;
60337 sCheck.nPage = btreePagecount(sCheck.pBt);
60338 sCheck.mxErr = mxErr;
60339 sCheck.nErr = 0;
60340 sCheck.mallocFailed = 0;
 
 
 
60341 *pnErr = 0;
60342 if( sCheck.nPage==0 ){
60343 sqlite3BtreeLeave(p);
60344 return 0;
60345 }
@@ -60355,53 +60533,57 @@
60355 sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
60356 sCheck.errMsg.useMalloc = 2;
60357
60358 /* Check the integrity of the freelist
60359 */
 
60360 checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
60361 get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
 
60362
60363 /* Check all the tables.
60364 */
60365 for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
60366 if( aRoot[i]==0 ) continue;
60367 #ifndef SQLITE_OMIT_AUTOVACUUM
60368 if( pBt->autoVacuum && aRoot[i]>1 ){
60369 checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
60370 }
60371 #endif
60372 checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
 
 
60373 }
60374
60375 /* Make sure every page in the file is referenced
60376 */
60377 for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
60378 #ifdef SQLITE_OMIT_AUTOVACUUM
60379 if( getPageReferenced(&sCheck, i)==0 ){
60380 checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
60381 }
60382 #else
60383 /* If the database supports auto-vacuum, make sure no tables contain
60384 ** references to pointer-map pages.
60385 */
60386 if( getPageReferenced(&sCheck, i)==0 &&
60387 (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
60388 checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
60389 }
60390 if( getPageReferenced(&sCheck, i)!=0 &&
60391 (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
60392 checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
60393 }
60394 #endif
60395 }
60396
60397 /* Make sure this analysis did not leave any unref() pages.
60398 ** This is an internal consistency check; an integrity check
60399 ** of the integrity check.
60400 */
60401 if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
60402 checkAppendMsg(&sCheck, 0,
60403 "Outstanding page count goes from %d to %d during this analysis",
60404 nRef, sqlite3PagerRefcount(pBt->pPager)
60405 );
60406 }
60407
@@ -60593,11 +60775,11 @@
60593
60594 /* Save the positions of all other cursors open on this table. This is
60595 ** required in case any of them are holding references to an xFetch
60596 ** version of the b-tree page modified by the accessPayload call below.
60597 **
60598 ** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition()
60599 ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
60600 ** saveAllCursors can only return SQLITE_OK.
60601 */
60602 VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
60603 assert( rc==SQLITE_OK );
@@ -61461,11 +61643,14 @@
61461 /* If MEM_Dyn is set then Mem.xDel!=0.
61462 ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
61463 */
61464 assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
61465
61466 /* MEM_Dyn may only be set if Mem.szMalloc==0 */
 
 
 
61467 assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
61468
61469 /* Cannot be both MEM_Int and MEM_Real at the same time */
61470 assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
61471
@@ -61570,11 +61755,11 @@
61570 }else{
61571 pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
61572 }
61573 }
61574
61575 if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
61576 memcpy(pMem->zMalloc, pMem->z, pMem->n);
61577 }
61578 if( (pMem->flags&MEM_Dyn)!=0 ){
61579 assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
61580 pMem->xDel((void *)(pMem->z));
@@ -61597,11 +61782,12 @@
61597 **
61598 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
61599 ** if unable to complete the resizing.
61600 */
61601 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
61602 assert( szNew>=0 );
 
61603 if( pMem->szMalloc<szNew ){
61604 return sqlite3VdbeMemGrow(pMem, szNew, 0);
61605 }
61606 assert( (pMem->flags & MEM_Dyn)==0 );
61607 pMem->z = pMem->zMalloc;
@@ -62321,11 +62507,14 @@
62321 nAlloc += (enc==SQLITE_UTF8?1:2);
62322 }
62323 if( nByte>iLimit ){
62324 return SQLITE_TOOBIG;
62325 }
62326 if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){
 
 
 
62327 return SQLITE_NOMEM;
62328 }
62329 memcpy(pMem->z, z, nAlloc);
62330 }else if( xDel==SQLITE_DYNAMIC ){
62331 sqlite3VdbeMemRelease(pMem);
@@ -62424,11 +62613,11 @@
62424 /*
62425 ** The pVal argument is known to be a value other than NULL.
62426 ** Convert it into a string with encoding enc and return a pointer
62427 ** to a zero-terminated version of that string.
62428 */
62429 SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
62430 assert( pVal!=0 );
62431 assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
62432 assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
62433 assert( (pVal->flags & MEM_RowSet)==0 );
62434 assert( (pVal->flags & (MEM_Null))==0 );
@@ -63751,11 +63940,12 @@
63751 if( addr==p->nOp-1 ) p->nOp--;
63752 }
63753 }
63754
63755 /*
63756 ** Remove the last opcode inserted
 
63757 */
63758 SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
63759 if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
63760 sqlite3VdbeChangeToNoop(p, p->nOp-1);
63761 return 1;
@@ -64743,11 +64933,11 @@
64743 ** the call above. */
64744 }else if( pCx->pCursor ){
64745 sqlite3BtreeCloseCursor(pCx->pCursor);
64746 }
64747 #ifndef SQLITE_OMIT_VIRTUALTABLE
64748 if( pCx->pVtabCursor ){
64749 sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
64750 const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
64751 p->inVtabMethod = 1;
64752 pModule->xClose(pVtabCursor);
64753 p->inVtabMethod = 0;
@@ -64786,13 +64976,14 @@
64786 static void closeAllCursors(Vdbe *p){
64787 if( p->pFrame ){
64788 VdbeFrame *pFrame;
64789 for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
64790 sqlite3VdbeFrameRestore(pFrame);
 
 
64791 }
64792 p->pFrame = 0;
64793 p->nFrame = 0;
64794
64795 if( p->apCsr ){
64796 int i;
64797 for(i=0; i<p->nCursor; i++){
64798 VdbeCursor *pC = p->apCsr[i];
@@ -64810,11 +65001,11 @@
64810 p->pDelFrame = pDel->pParent;
64811 sqlite3VdbeFrameDelete(pDel);
64812 }
64813
64814 /* Delete any auxdata allocations made by the VM */
64815 sqlite3VdbeDeleteAuxData(p, -1, 0);
64816 assert( p->pAuxData==0 );
64817 }
64818
64819 /*
64820 ** Clean up the VM after a single run.
@@ -65676,14 +65867,10 @@
65676 for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
65677 vdbeFreeOpArray(db, p->aOp, p->nOp);
65678 sqlite3DbFree(db, p->aColName);
65679 sqlite3DbFree(db, p->zSql);
65680 sqlite3DbFree(db, p->pFree);
65681 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
65682 sqlite3DbFree(db, p->zExplain);
65683 sqlite3DbFree(db, p->pExplain);
65684 #endif
65685 }
65686
65687 /*
65688 ** Delete an entire VDBE.
65689 */
@@ -65720,13 +65907,11 @@
65720 #endif
65721 assert( p->deferredMoveto );
65722 assert( p->isTable );
65723 rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
65724 if( rc ) return rc;
65725 p->lastRowid = p->movetoTarget;
65726 if( res!=0 ) return SQLITE_CORRUPT_BKPT;
65727 p->rowidIsValid = 1;
65728 #ifdef SQLITE_TEST
65729 sqlite3_search_count++;
65730 #endif
65731 p->deferredMoveto = 0;
65732 p->cacheStatus = CACHE_STALE;
@@ -65747,10 +65932,21 @@
65747 rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
65748 p->cacheStatus = CACHE_STALE;
65749 if( isDifferentRow ) p->nullRow = 1;
65750 return rc;
65751 }
 
 
 
 
 
 
 
 
 
 
 
65752
65753 /*
65754 ** Make sure the cursor p is ready to read or write the row to which it
65755 ** was last positioned. Return an error code if an OOM fault or I/O error
65756 ** prevents us from positioning the cursor to its correct position.
@@ -65765,11 +65961,11 @@
65765 */
65766 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
65767 if( p->deferredMoveto ){
65768 return handleDeferredMoveto(p);
65769 }
65770 if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65771 return handleMovedCursor(p);
65772 }
65773 return SQLITE_OK;
65774 }
65775
@@ -67390,10 +67586,11 @@
67390 void (*xDel)(void *),
67391 unsigned char enc
67392 ){
67393 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
67394 assert( xDel!=SQLITE_DYNAMIC );
 
67395 if( n>0x7fffffff ){
67396 (void)invokeValueDestructor(z, xDel, pCtx);
67397 }else{
67398 setResultStrOrError(pCtx, z, (int)n, enc, xDel);
67399 }
@@ -68712,125 +68909,10 @@
68712 return sqlite3StrAccumFinish(&out);
68713 }
68714
68715 #endif /* #ifndef SQLITE_OMIT_TRACE */
68716
68717 /*****************************************************************************
68718 ** The following code implements the data-structure explaining logic
68719 ** for the Vdbe.
68720 */
68721
68722 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
68723
68724 /*
68725 ** Allocate a new Explain object
68726 */
68727 SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
68728 if( pVdbe ){
68729 Explain *p;
68730 sqlite3BeginBenignMalloc();
68731 p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
68732 if( p ){
68733 p->pVdbe = pVdbe;
68734 sqlite3_free(pVdbe->pExplain);
68735 pVdbe->pExplain = p;
68736 sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
68737 SQLITE_MAX_LENGTH);
68738 p->str.useMalloc = 2;
68739 }else{
68740 sqlite3EndBenignMalloc();
68741 }
68742 }
68743 }
68744
68745 /*
68746 ** Return true if the Explain ends with a new-line.
68747 */
68748 static int endsWithNL(Explain *p){
68749 return p && p->str.zText && p->str.nChar
68750 && p->str.zText[p->str.nChar-1]=='\n';
68751 }
68752
68753 /*
68754 ** Append text to the indentation
68755 */
68756 SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
68757 Explain *p;
68758 if( pVdbe && (p = pVdbe->pExplain)!=0 ){
68759 va_list ap;
68760 if( p->nIndent && endsWithNL(p) ){
68761 int n = p->nIndent;
68762 if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
68763 sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
68764 }
68765 va_start(ap, zFormat);
68766 sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap);
68767 va_end(ap);
68768 }
68769 }
68770
68771 /*
68772 ** Append a '\n' if there is not already one.
68773 */
68774 SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe *pVdbe){
68775 Explain *p;
68776 if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
68777 sqlite3StrAccumAppend(&p->str, "\n", 1);
68778 }
68779 }
68780
68781 /*
68782 ** Push a new indentation level. Subsequent lines will be indented
68783 ** so that they begin at the current cursor position.
68784 */
68785 SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe *pVdbe){
68786 Explain *p;
68787 if( pVdbe && (p = pVdbe->pExplain)!=0 ){
68788 if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
68789 const char *z = p->str.zText;
68790 int i = p->str.nChar-1;
68791 int x;
68792 while( i>=0 && z[i]!='\n' ){ i--; }
68793 x = (p->str.nChar - 1) - i;
68794 if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
68795 x = p->aIndent[p->nIndent-1];
68796 }
68797 p->aIndent[p->nIndent] = x;
68798 }
68799 p->nIndent++;
68800 }
68801 }
68802
68803 /*
68804 ** Pop the indentation stack by one level.
68805 */
68806 SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe *p){
68807 if( p && p->pExplain ) p->pExplain->nIndent--;
68808 }
68809
68810 /*
68811 ** Free the indentation structure
68812 */
68813 SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe *pVdbe){
68814 if( pVdbe && pVdbe->pExplain ){
68815 sqlite3_free(pVdbe->zExplain);
68816 sqlite3ExplainNL(pVdbe);
68817 pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str);
68818 sqlite3_free(pVdbe->pExplain);
68819 pVdbe->pExplain = 0;
68820 sqlite3EndBenignMalloc();
68821 }
68822 }
68823
68824 /*
68825 ** Return the explanation of a virtual machine.
68826 */
68827 SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
68828 return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
68829 }
68830 #endif /* defined(SQLITE_DEBUG) */
68831
68832 /************** End of vdbetrace.c *******************************************/
68833 /************** Begin file vdbe.c ********************************************/
68834 /*
68835 ** 2001 September 15
68836 **
@@ -69043,10 +69125,11 @@
69043 if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
69044 p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
69045 memset(pCx, 0, sizeof(VdbeCursor));
69046 pCx->iDb = iDb;
69047 pCx->nField = nField;
 
69048 if( isBtreeCursor ){
69049 pCx->pCursor = (BtCursor*)
69050 &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
69051 sqlite3BtreeCursorZero(pCx->pCursor);
69052 }
@@ -70475,21 +70558,14 @@
70475 assert( pOp->p4type==P4_FUNCDEF );
70476 ctx.pFunc = pOp->p4.pFunc;
70477 ctx.iOp = pc;
70478 ctx.pVdbe = p;
70479 MemSetTypeFlag(ctx.pOut, MEM_Null);
70480
70481 ctx.fErrorOrAux = 0;
70482 if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
70483 assert( pOp>aOp );
70484 assert( pOp[-1].p4type==P4_COLLSEQ );
70485 assert( pOp[-1].opcode==OP_CollSeq );
70486 ctx.pColl = pOp[-1].p4.pColl;
70487 }
70488 db->lastRowid = lastRowid;
70489 (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
70490 lastRowid = db->lastRowid;
70491
70492 /* If the function returned an error, throw an exception */
70493 if( ctx.fErrorOrAux ){
70494 if( ctx.isError ){
70495 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
@@ -71201,11 +71277,11 @@
71201 memAboutToChange(p, pDest);
71202 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
71203 pC = p->apCsr[pOp->p1];
71204 assert( pC!=0 );
71205 assert( p2<pC->nField );
71206 aOffset = pC->aType + pC->nField;
71207 #ifndef SQLITE_OMIT_VIRTUALTABLE
71208 assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
71209 #endif
71210 pCrsr = pC->pCursor;
71211 assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
@@ -71212,11 +71288,11 @@
71212 assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
71213
71214 /* If the cursor cache is stale, bring it up-to-date */
71215 rc = sqlite3VdbeCursorMoveto(pC);
71216 if( rc ) goto abort_due_to_error;
71217 if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
71218 if( pC->nullRow ){
71219 if( pCrsr==0 ){
71220 assert( pC->pseudoTableReg>0 );
71221 pReg = &aMem[pC->pseudoTableReg];
71222 assert( pReg->flags & MEM_Blob );
@@ -71257,18 +71333,10 @@
71257 }
71258 pC->cacheStatus = p->cacheCtr;
71259 pC->iHdrOffset = getVarint32(pC->aRow, offset);
71260 pC->nHdrParsed = 0;
71261 aOffset[0] = offset;
71262 if( avail<offset ){
71263 /* pC->aRow does not have to hold the entire row, but it does at least
71264 ** need to cover the header of the record. If pC->aRow does not contain
71265 ** the complete header, then set it to zero, forcing the header to be
71266 ** dynamically allocated. */
71267 pC->aRow = 0;
71268 pC->szRow = 0;
71269 }
71270
71271 /* Make sure a corrupt database has not given us an oversize header.
71272 ** Do this now to avoid an oversize memory allocation.
71273 **
71274 ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
@@ -71279,19 +71347,36 @@
71279 */
71280 if( offset > 98307 || offset > pC->payloadSize ){
71281 rc = SQLITE_CORRUPT_BKPT;
71282 goto op_column_error;
71283 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71284 }
71285
71286 /* Make sure at least the first p2+1 entries of the header have been
71287 ** parsed and valid information is in aOffset[] and pC->aType[].
71288 */
71289 if( pC->nHdrParsed<=p2 ){
71290 /* If there is more header available for parsing in the record, try
71291 ** to extract additional fields up through the p2+1-th field
71292 */
 
71293 if( pC->iHdrOffset<aOffset[0] ){
71294 /* Make sure zData points to enough of the record to cover the header. */
71295 if( pC->aRow==0 ){
71296 memset(&sMem, 0, sizeof(sMem));
71297 rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
@@ -71332,19 +71417,20 @@
71332 if( pC->aRow==0 ){
71333 sqlite3VdbeMemRelease(&sMem);
71334 sMem.flags = MEM_Null;
71335 }
71336
71337 /* If we have read more header data than was contained in the header,
71338 ** or if the end of the last field appears to be past the end of the
71339 ** record, or if the end of the last field appears to be before the end
71340 ** of the record (when all fields present), then we must be dealing
71341 ** with a corrupt database.
 
 
71342 */
71343 if( (zHdr > zEndHdr)
71344 || (offset > pC->payloadSize)
71345 || (zHdr==zEndHdr && offset!=pC->payloadSize)
71346 ){
71347 rc = SQLITE_CORRUPT_BKPT;
71348 goto op_column_error;
71349 }
71350 }
@@ -71531,11 +71617,11 @@
71531 ** out how much space is required for the new record.
71532 */
71533 pRec = pLast;
71534 do{
71535 assert( memIsValid(pRec) );
71536 serial_type = sqlite3VdbeSerialType(pRec, file_format);
71537 len = sqlite3VdbeSerialTypeLen(serial_type);
71538 if( pRec->flags & MEM_Zero ){
71539 if( nData ){
71540 sqlite3VdbeMemExpandBlob(pRec);
71541 }else{
@@ -71580,11 +71666,11 @@
71580 i = putVarint32(zNewRecord, nHdr);
71581 j = nHdr;
71582 assert( pData0<=pLast );
71583 pRec = pData0;
71584 do{
71585 serial_type = sqlite3VdbeSerialType(pRec, file_format);
71586 i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
71587 j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
71588 }while( (++pRec)<=pLast );
71589 assert( i==nHdr );
71590 assert( j==nByte );
@@ -72205,14 +72291,10 @@
72205 rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
72206 pCur->pKeyInfo = pKeyInfo;
72207 assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
72208 sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
72209
72210 /* Since it performs no memory allocation or IO, the only value that
72211 ** sqlite3BtreeCursor() may return is SQLITE_OK. */
72212 assert( rc==SQLITE_OK );
72213
72214 /* Set the VdbeCursor.isTable variable. Previous versions of
72215 ** SQLite used to check if the root-page flags were sane at this point
72216 ** and report database corruption if they were not, but this check has
72217 ** since moved into the btree layer. */
72218 pCur->isTable = pOp->p4type!=P4_KEYINFO;
@@ -72483,11 +72565,10 @@
72483 pIn3 = &aMem[pOp->p3];
72484 if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
72485 applyNumericAffinity(pIn3, 0);
72486 }
72487 iKey = sqlite3VdbeIntValue(pIn3);
72488 pC->rowidIsValid = 0;
72489
72490 /* If the P3 value could not be converted into an integer without
72491 ** loss of information, then special processing is required... */
72492 if( (pIn3->flags & MEM_Int)==0 ){
72493 if( (pIn3->flags & MEM_Real)==0 ){
@@ -72519,17 +72600,14 @@
72519 assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
72520 if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
72521 }
72522 }
72523 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
 
72524 if( rc!=SQLITE_OK ){
72525 goto abort_due_to_error;
72526 }
72527 if( res==0 ){
72528 pC->rowidIsValid = 1;
72529 pC->lastRowid = iKey;
72530 }
72531 }else{
72532 nField = pOp->p4.i;
72533 assert( pOp->p4type==P4_INT32 );
72534 assert( nField>0 );
72535 r.pKeyInfo = pC->pKeyInfo;
@@ -72555,11 +72633,10 @@
72555 ExpandBlob(r.aMem);
72556 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
72557 if( rc!=SQLITE_OK ){
72558 goto abort_due_to_error;
72559 }
72560 pC->rowidIsValid = 0;
72561 }
72562 pC->deferredMoveto = 0;
72563 pC->cacheStatus = CACHE_STALE;
72564 #ifdef SQLITE_TEST
72565 sqlite3_search_count++;
@@ -72567,21 +72644,19 @@
72567 if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
72568 if( res<0 || (res==0 && oc==OP_SeekGT) ){
72569 res = 0;
72570 rc = sqlite3BtreeNext(pC->pCursor, &res);
72571 if( rc!=SQLITE_OK ) goto abort_due_to_error;
72572 pC->rowidIsValid = 0;
72573 }else{
72574 res = 0;
72575 }
72576 }else{
72577 assert( oc==OP_SeekLT || oc==OP_SeekLE );
72578 if( res>0 || (res==0 && oc==OP_SeekLT) ){
72579 res = 0;
72580 rc = sqlite3BtreePrevious(pC->pCursor, &res);
72581 if( rc!=SQLITE_OK ) goto abort_due_to_error;
72582 pC->rowidIsValid = 0;
72583 }else{
72584 /* res might be negative because the table is empty. Check to
72585 ** see if this is the case.
72586 */
72587 res = sqlite3BtreeEof(pC->pCursor);
@@ -72614,11 +72689,10 @@
72614 assert( pC->pCursor!=0 );
72615 assert( pC->isTable );
72616 pC->nullRow = 0;
72617 pIn2 = &aMem[pOp->p2];
72618 pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
72619 pC->rowidIsValid = 0;
72620 pC->deferredMoveto = 1;
72621 break;
72622 }
72623
72624
@@ -72800,19 +72874,17 @@
72800 pCrsr = pC->pCursor;
72801 assert( pCrsr!=0 );
72802 res = 0;
72803 iKey = pIn3->u.i;
72804 rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
72805 pC->lastRowid = pIn3->u.i;
72806 pC->rowidIsValid = res==0 ?1:0;
72807 pC->nullRow = 0;
72808 pC->cacheStatus = CACHE_STALE;
72809 pC->deferredMoveto = 0;
72810 VdbeBranchTaken(res!=0,2);
72811 if( res!=0 ){
72812 pc = pOp->p2 - 1;
72813 assert( pC->rowidIsValid==0 );
72814 }
72815 pC->seekResult = res;
72816 break;
72817 }
72818
@@ -72942,36 +73014,24 @@
72942 ** largest possible integer (9223372036854775807) then the database
72943 ** engine starts picking positive candidate ROWIDs at random until
72944 ** it finds one that is not previously used. */
72945 assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is
72946 ** an AUTOINCREMENT table. */
72947 /* on the first attempt, simply do one more than previous */
72948 v = lastRowid;
72949 v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
72950 v++; /* ensure non-zero */
72951 cnt = 0;
72952 while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
 
 
 
72953 0, &res))==SQLITE_OK)
72954 && (res==0)
72955 && (++cnt<100)){
72956 /* collision - try another random rowid */
72957 sqlite3_randomness(sizeof(v), &v);
72958 if( cnt<5 ){
72959 /* try "small" random rowids for the initial attempts */
72960 v &= 0xffffff;
72961 }else{
72962 v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
72963 }
72964 v++; /* ensure non-zero */
72965 }
72966 if( rc==SQLITE_OK && res==0 ){
72967 rc = SQLITE_FULL; /* IMP: R-38219-53002 */
72968 goto abort_due_to_error;
72969 }
72970 assert( v>0 ); /* EV: R-40812-03570 */
72971 }
72972 pC->rowidIsValid = 0;
72973 pC->deferredMoveto = 0;
72974 pC->cacheStatus = CACHE_STALE;
72975 }
72976 pOut->u.i = v;
72977 break;
@@ -73072,11 +73132,10 @@
73072 }
73073 rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
73074 pData->z, pData->n, nZero,
73075 (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
73076 );
73077 pC->rowidIsValid = 0;
73078 pC->deferredMoveto = 0;
73079 pC->cacheStatus = CACHE_STALE;
73080
73081 /* Invoke the update-hook if required. */
73082 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
@@ -73109,37 +73168,36 @@
73109 ** pointing to. The update hook will be invoked, if it exists.
73110 ** If P4 is not NULL then the P1 cursor must have been positioned
73111 ** using OP_NotFound prior to invoking this opcode.
73112 */
73113 case OP_Delete: {
73114 i64 iKey;
73115 VdbeCursor *pC;
73116
73117 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73118 pC = p->apCsr[pOp->p1];
73119 assert( pC!=0 );
73120 assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
73121 iKey = pC->lastRowid; /* Only used for the update hook */
73122
73123 /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
73124 ** OP_Column on the same table without any intervening operations that
73125 ** might move or invalidate the cursor. Hence cursor pC is always pointing
73126 ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
73127 ** below is always a no-op and cannot fail. We will run it anyhow, though,
73128 ** to guard against future changes to the code generator.
73129 **/
73130 assert( pC->deferredMoveto==0 );
73131 rc = sqlite3VdbeCursorMoveto(pC);
73132 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73133
 
 
 
 
 
 
 
 
 
 
 
73134 rc = sqlite3BtreeDelete(pC->pCursor);
73135 pC->cacheStatus = CACHE_STALE;
73136
73137 /* Invoke the update-hook if required. */
73138 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
73139 db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
73140 db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
73141 assert( pC->iDb>=0 );
73142 }
73143 if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
73144 break;
73145 }
@@ -73188,23 +73246,32 @@
73188 pc = pOp->p2-1;
73189 }
73190 break;
73191 };
73192
73193 /* Opcode: SorterData P1 P2 * * *
73194 ** Synopsis: r[P2]=data
73195 **
73196 ** Write into register P2 the current sorter data for sorter cursor P1.
 
 
 
 
 
 
 
73197 */
73198 case OP_SorterData: {
73199 VdbeCursor *pC;
73200
73201 pOut = &aMem[pOp->p2];
73202 pC = p->apCsr[pOp->p1];
73203 assert( isSorter(pC) );
73204 rc = sqlite3VdbeSorterRowkey(pC, pOut);
73205 assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
 
 
73206 break;
73207 }
73208
73209 /* Opcode: RowData P1 P2 * * *
73210 ** Synopsis: r[P2]=data
@@ -73247,20 +73314,24 @@
73247 assert( pC!=0 );
73248 assert( pC->nullRow==0 );
73249 assert( pC->pseudoTableReg==0 );
73250 assert( pC->pCursor!=0 );
73251 pCrsr = pC->pCursor;
73252 assert( sqlite3BtreeCursorIsValid(pCrsr) );
73253
73254 /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
73255 ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
73256 ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
73257 ** a no-op and can never fail. But we leave it in place as a safety.
 
 
73258 */
73259 assert( pC->deferredMoveto==0 );
 
 
73260 rc = sqlite3VdbeCursorMoveto(pC);
73261 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
 
73262
73263 if( pC->isTable==0 ){
73264 assert( !pC->isTable );
73265 VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
73266 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -73273,11 +73344,12 @@
73273 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
73274 if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
73275 goto too_big;
73276 }
73277 }
73278 if( sqlite3VdbeMemClearAndResize(pOut, n) ){
 
73279 goto no_mem;
73280 }
73281 pOut->n = n;
73282 MemSetTypeFlag(pOut, MEM_Blob);
73283 if( pC->isTable==0 ){
@@ -73324,18 +73396,14 @@
73324 rc = pModule->xRowid(pC->pVtabCursor, &v);
73325 sqlite3VtabImportErrmsg(p, pVtab);
73326 #endif /* SQLITE_OMIT_VIRTUALTABLE */
73327 }else{
73328 assert( pC->pCursor!=0 );
73329 rc = sqlite3VdbeCursorMoveto(pC);
73330 if( rc ) goto abort_due_to_error;
73331 if( pC->rowidIsValid ){
73332 v = pC->lastRowid;
73333 }else{
73334 rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73335 assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
73336 }
73337 }
73338 pOut->u.i = v;
73339 break;
73340 }
73341
@@ -73350,11 +73418,10 @@
73350
73351 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73352 pC = p->apCsr[pOp->p1];
73353 assert( pC!=0 );
73354 pC->nullRow = 1;
73355 pC->rowidIsValid = 0;
73356 pC->cacheStatus = CACHE_STALE;
73357 if( pC->pCursor ){
73358 sqlite3BtreeClearCursor(pC->pCursor);
73359 }
73360 break;
@@ -73384,11 +73451,10 @@
73384 res = 0;
73385 assert( pCrsr!=0 );
73386 rc = sqlite3BtreeLast(pCrsr, &res);
73387 pC->nullRow = (u8)res;
73388 pC->deferredMoveto = 0;
73389 pC->rowidIsValid = 0;
73390 pC->cacheStatus = CACHE_STALE;
73391 #ifdef SQLITE_DEBUG
73392 pC->seekOp = OP_Last;
73393 #endif
73394 if( pOp->p2>0 ){
@@ -73451,11 +73517,10 @@
73451 pCrsr = pC->pCursor;
73452 assert( pCrsr );
73453 rc = sqlite3BtreeFirst(pCrsr, &res);
73454 pC->deferredMoveto = 0;
73455 pC->cacheStatus = CACHE_STALE;
73456 pC->rowidIsValid = 0;
73457 }
73458 pC->nullRow = (u8)res;
73459 assert( pOp->p2>0 && pOp->p2<p->nOp );
73460 VdbeBranchTaken(res!=0,2);
73461 if( res ){
@@ -73577,11 +73642,10 @@
73577 sqlite3_search_count++;
73578 #endif
73579 }else{
73580 pC->nullRow = 1;
73581 }
73582 pC->rowidIsValid = 0;
73583 goto check_for_interrupt;
73584 }
73585
73586 /* Opcode: IdxInsert P1 P2 P3 * P5
73587 ** Synopsis: key=r[P2]
@@ -73693,14 +73757,20 @@
73693 pC = p->apCsr[pOp->p1];
73694 assert( pC!=0 );
73695 pCrsr = pC->pCursor;
73696 assert( pCrsr!=0 );
73697 pOut->flags = MEM_Null;
73698 rc = sqlite3VdbeCursorMoveto(pC);
73699 if( NEVER(rc) ) goto abort_due_to_error;
73700 assert( pC->deferredMoveto==0 );
73701 assert( pC->isTable==0 );
 
 
 
 
 
 
 
73702 if( !pC->nullRow ){
73703 rowid = 0; /* Not needed. Only used to silence a warning. */
73704 rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
73705 if( rc!=SQLITE_OK ){
73706 goto abort_due_to_error;
@@ -74556,18 +74626,13 @@
74556 ctx.pMem = pMem = &aMem[pOp->p3];
74557 pMem->n++;
74558 sqlite3VdbeMemInit(&t, db, MEM_Null);
74559 ctx.pOut = &t;
74560 ctx.isError = 0;
74561 ctx.pColl = 0;
 
74562 ctx.skipFlag = 0;
74563 if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
74564 assert( pOp>p->aOp );
74565 assert( pOp[-1].p4type==P4_COLLSEQ );
74566 assert( pOp[-1].opcode==OP_CollSeq );
74567 ctx.pColl = pOp[-1].p4.pColl;
74568 }
74569 (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
74570 if( ctx.isError ){
74571 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
74572 rc = ctx.isError;
74573 }
@@ -78162,11 +78227,11 @@
78162 if( rc==SQLITE_OK ){
78163 #if SQLITE_MAX_WORKER_THREADS
78164 assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
78165 if( pSorter->bUseThreads ){
78166 int iTask;
78167 PmaReader *pReadr;
78168 SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
78169 rc = vdbeSortAllocUnpacked(pLast);
78170 if( rc==SQLITE_OK ){
78171 pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
78172 pSorter->pReader = pReadr;
@@ -81597,10 +81662,11 @@
81597 pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
81598 pNew->addrOpenEphm[0] = -1;
81599 pNew->addrOpenEphm[1] = -1;
81600 pNew->nSelectRow = p->nSelectRow;
81601 pNew->pWith = withDup(db, p->pWith);
 
81602 return pNew;
81603 }
81604 #else
81605 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
81606 assert( p==0 );
@@ -81739,36 +81805,44 @@
81739 }
81740
81741 /*
81742 ** These routines are Walker callbacks. Walker.u.pi is a pointer
81743 ** to an integer. These routines are checking an expression to see
81744 ** if it is a constant. Set *Walker.u.pi to 0 if the expression is
81745 ** not constant.
81746 **
81747 ** These callback routines are used to implement the following:
81748 **
81749 ** sqlite3ExprIsConstant()
81750 ** sqlite3ExprIsConstantNotJoin()
81751 ** sqlite3ExprIsConstantOrFunction()
81752 **
 
 
 
 
 
 
 
 
81753 */
81754 static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
81755
81756 /* If pWalker->u.i is 3 then any term of the expression that comes from
81757 ** the ON or USING clauses of a join disqualifies the expression
81758 ** from being considered constant. */
81759 if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){
81760 pWalker->u.i = 0;
81761 return WRC_Abort;
81762 }
81763
81764 switch( pExpr->op ){
81765 /* Consider functions to be constant if all their arguments are constant
81766 ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST
81767 ** flag. */
81768 case TK_FUNCTION:
81769 if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){
81770 return WRC_Continue;
81771 }
81772 /* Fall through */
81773 case TK_ID:
81774 case TK_COLUMN:
@@ -81778,10 +81852,23 @@
81778 testcase( pExpr->op==TK_COLUMN );
81779 testcase( pExpr->op==TK_AGG_FUNCTION );
81780 testcase( pExpr->op==TK_AGG_COLUMN );
81781 pWalker->u.i = 0;
81782 return WRC_Abort;
 
 
 
 
 
 
 
 
 
 
 
 
 
81783 default:
81784 testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
81785 testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
81786 return WRC_Continue;
81787 }
@@ -81818,11 +81905,11 @@
81818 ** that does no originate from the ON or USING clauses of a join.
81819 ** Return 0 if it involves variables or function calls or terms from
81820 ** an ON or USING clause.
81821 */
81822 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
81823 return exprIsConst(p, 3);
81824 }
81825
81826 /*
81827 ** Walk an expression tree. Return 1 if the expression is constant
81828 ** or a function call with constant arguments. Return and 0 if there
@@ -81830,12 +81917,13 @@
81830 **
81831 ** For the purposes of this function, a double-quoted string (ex: "abc")
81832 ** is considered a variable but a single-quoted string (ex: 'abc') is
81833 ** a constant.
81834 */
81835 SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){
81836 return exprIsConst(p, 2);
 
81837 }
81838
81839 /*
81840 ** If the expression p codes a constant integer that is small enough
81841 ** to fit in a 32-bit integer, return 1 and put the value of the integer
@@ -83741,94 +83829,90 @@
83741 iMem = ++pParse->nMem;
83742 sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
83743 exprToRegister(pExpr, iMem);
83744 }
83745
83746 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
83747 /*
83748 ** Generate a human-readable explanation of an expression tree.
83749 */
83750 SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
83751 int op; /* The opcode being coded */
83752 const char *zBinOp = 0; /* Binary operator */
83753 const char *zUniOp = 0; /* Unary operator */
 
83754 if( pExpr==0 ){
83755 op = TK_NULL;
83756 }else{
83757 op = pExpr->op;
83758 }
83759 switch( op ){
83760 case TK_AGG_COLUMN: {
83761 sqlite3ExplainPrintf(pOut, "AGG{%d:%d}",
83762 pExpr->iTable, pExpr->iColumn);
83763 break;
83764 }
83765 case TK_COLUMN: {
83766 if( pExpr->iTable<0 ){
83767 /* This only happens when coding check constraints */
83768 sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
83769 }else{
83770 sqlite3ExplainPrintf(pOut, "{%d:%d}",
83771 pExpr->iTable, pExpr->iColumn);
83772 }
83773 break;
83774 }
83775 case TK_INTEGER: {
83776 if( pExpr->flags & EP_IntValue ){
83777 sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue);
83778 }else{
83779 sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken);
83780 }
83781 break;
83782 }
83783 #ifndef SQLITE_OMIT_FLOATING_POINT
83784 case TK_FLOAT: {
83785 sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
83786 break;
83787 }
83788 #endif
83789 case TK_STRING: {
83790 sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
83791 break;
83792 }
83793 case TK_NULL: {
83794 sqlite3ExplainPrintf(pOut,"NULL");
83795 break;
83796 }
83797 #ifndef SQLITE_OMIT_BLOB_LITERAL
83798 case TK_BLOB: {
83799 sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
83800 break;
83801 }
83802 #endif
83803 case TK_VARIABLE: {
83804 sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)",
83805 pExpr->u.zToken, pExpr->iColumn);
83806 break;
83807 }
83808 case TK_REGISTER: {
83809 sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
83810 break;
83811 }
83812 case TK_AS: {
83813 sqlite3ExplainExpr(pOut, pExpr->pLeft);
 
 
 
 
 
83814 break;
83815 }
83816 #ifndef SQLITE_OMIT_CAST
83817 case TK_CAST: {
83818 /* Expressions of the form: CAST(pLeft AS token) */
83819 const char *zAff = "unk";
83820 switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){
83821 case SQLITE_AFF_TEXT: zAff = "TEXT"; break;
83822 case SQLITE_AFF_NONE: zAff = "NONE"; break;
83823 case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break;
83824 case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break;
83825 case SQLITE_AFF_REAL: zAff = "REAL"; break;
83826 }
83827 sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff);
83828 sqlite3ExplainExpr(pOut, pExpr->pLeft);
83829 sqlite3ExplainPrintf(pOut, ")");
83830 break;
83831 }
83832 #endif /* SQLITE_OMIT_CAST */
83833 case TK_LT: zBinOp = "LT"; break;
83834 case TK_LE: zBinOp = "LE"; break;
@@ -83848,21 +83932,22 @@
83848 case TK_BITOR: zBinOp = "BITOR"; break;
83849 case TK_SLASH: zBinOp = "DIV"; break;
83850 case TK_LSHIFT: zBinOp = "LSHIFT"; break;
83851 case TK_RSHIFT: zBinOp = "RSHIFT"; break;
83852 case TK_CONCAT: zBinOp = "CONCAT"; break;
 
83853
83854 case TK_UMINUS: zUniOp = "UMINUS"; break;
83855 case TK_UPLUS: zUniOp = "UPLUS"; break;
83856 case TK_BITNOT: zUniOp = "BITNOT"; break;
83857 case TK_NOT: zUniOp = "NOT"; break;
83858 case TK_ISNULL: zUniOp = "ISNULL"; break;
83859 case TK_NOTNULL: zUniOp = "NOTNULL"; break;
83860
83861 case TK_COLLATE: {
83862 sqlite3ExplainExpr(pOut, pExpr->pLeft);
83863 sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
83864 break;
83865 }
83866
83867 case TK_AGG_FUNCTION:
83868 case TK_FUNCTION: {
@@ -83870,45 +83955,40 @@
83870 if( ExprHasProperty(pExpr, EP_TokenOnly) ){
83871 pFarg = 0;
83872 }else{
83873 pFarg = pExpr->x.pList;
83874 }
83875 if( op==TK_AGG_FUNCTION ){
83876 sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
83877 pExpr->op2, pExpr->u.zToken);
83878 }else{
83879 sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
83880 }
83881 if( pFarg ){
83882 sqlite3ExplainExprList(pOut, pFarg);
83883 }
83884 sqlite3ExplainPrintf(pOut, ")");
83885 break;
83886 }
83887 #ifndef SQLITE_OMIT_SUBQUERY
83888 case TK_EXISTS: {
83889 sqlite3ExplainPrintf(pOut, "EXISTS(");
83890 sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
83891 sqlite3ExplainPrintf(pOut,")");
83892 break;
83893 }
83894 case TK_SELECT: {
83895 sqlite3ExplainPrintf(pOut, "(");
83896 sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
83897 sqlite3ExplainPrintf(pOut, ")");
83898 break;
83899 }
83900 case TK_IN: {
83901 sqlite3ExplainPrintf(pOut, "IN(");
83902 sqlite3ExplainExpr(pOut, pExpr->pLeft);
83903 sqlite3ExplainPrintf(pOut, ",");
83904 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
83905 sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
83906 }else{
83907 sqlite3ExplainExprList(pOut, pExpr->x.pList);
83908 }
83909 sqlite3ExplainPrintf(pOut, ")");
83910 break;
83911 }
83912 #endif /* SQLITE_OMIT_SUBQUERY */
83913
83914 /*
@@ -83924,17 +84004,14 @@
83924 */
83925 case TK_BETWEEN: {
83926 Expr *pX = pExpr->pLeft;
83927 Expr *pY = pExpr->x.pList->a[0].pExpr;
83928 Expr *pZ = pExpr->x.pList->a[1].pExpr;
83929 sqlite3ExplainPrintf(pOut, "BETWEEN(");
83930 sqlite3ExplainExpr(pOut, pX);
83931 sqlite3ExplainPrintf(pOut, ",");
83932 sqlite3ExplainExpr(pOut, pY);
83933 sqlite3ExplainPrintf(pOut, ",");
83934 sqlite3ExplainExpr(pOut, pZ);
83935 sqlite3ExplainPrintf(pOut, ")");
83936 break;
83937 }
83938 case TK_TRIGGER: {
83939 /* If the opcode is TK_TRIGGER, then the expression is a reference
83940 ** to a column in the new.* or old.* pseudo-tables available to
@@ -83941,19 +84018,18 @@
83941 ** trigger programs. In this case Expr.iTable is set to 1 for the
83942 ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
83943 ** is set to the column of the pseudo-table to read, or to -1 to
83944 ** read the rowid field.
83945 */
83946 sqlite3ExplainPrintf(pOut, "%s(%d)",
83947 pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
83948 break;
83949 }
83950 case TK_CASE: {
83951 sqlite3ExplainPrintf(pOut, "CASE(");
83952 sqlite3ExplainExpr(pOut, pExpr->pLeft);
83953 sqlite3ExplainPrintf(pOut, ",");
83954 sqlite3ExplainExprList(pOut, pExpr->x.pList);
83955 break;
83956 }
83957 #ifndef SQLITE_OMIT_TRIGGER
83958 case TK_RAISE: {
83959 const char *zType = "unk";
@@ -83961,59 +84037,61 @@
83961 case OE_Rollback: zType = "rollback"; break;
83962 case OE_Abort: zType = "abort"; break;
83963 case OE_Fail: zType = "fail"; break;
83964 case OE_Ignore: zType = "ignore"; break;
83965 }
83966 sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
83967 break;
83968 }
83969 #endif
 
 
 
 
83970 }
83971 if( zBinOp ){
83972 sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
83973 sqlite3ExplainExpr(pOut, pExpr->pLeft);
83974 sqlite3ExplainPrintf(pOut,",");
83975 sqlite3ExplainExpr(pOut, pExpr->pRight);
83976 sqlite3ExplainPrintf(pOut,")");
83977 }else if( zUniOp ){
83978 sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
83979 sqlite3ExplainExpr(pOut, pExpr->pLeft);
83980 sqlite3ExplainPrintf(pOut,")");
83981 }
83982 }
83983 #endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
83984
83985 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
83986 /*
83987 ** Generate a human-readable explanation of an expression list.
83988 */
83989 SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){
 
 
 
 
 
83990 int i;
83991 if( pList==0 || pList->nExpr==0 ){
83992 sqlite3ExplainPrintf(pOut, "(empty-list)");
83993 return;
83994 }else if( pList->nExpr==1 ){
83995 sqlite3ExplainExpr(pOut, pList->a[0].pExpr);
83996 }else{
83997 sqlite3ExplainPush(pOut);
83998 for(i=0; i<pList->nExpr; i++){
83999 sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
84000 sqlite3ExplainPush(pOut);
84001 sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
84002 sqlite3ExplainPop(pOut);
84003 if( pList->a[i].zName ){
84004 sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
84005 }
84006 if( pList->a[i].bSpanIsTab ){
84007 sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
84008 }
84009 if( i<pList->nExpr-1 ){
84010 sqlite3ExplainNL(pOut);
84011 }
84012 }
84013 sqlite3ExplainPop(pOut);
84014 }
 
84015 }
84016 #endif /* SQLITE_DEBUG */
84017
84018 /*
84019 ** Generate code that pushes the value of every element of the given
@@ -87130,29 +87208,27 @@
87130 tRowcnt v;
87131
87132 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87133 if( z==0 ) z = "";
87134 #else
87135 if( NEVER(z==0) ) z = "";
87136 #endif
87137 for(i=0; *z && i<nOut; i++){
87138 v = 0;
87139 while( (c=z[0])>='0' && c<='9' ){
87140 v = v*10 + c - '0';
87141 z++;
87142 }
87143 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87144 if( aOut ){
87145 aOut[i] = v;
87146 }else
87147 #else
87148 assert( aOut==0 );
87149 UNUSED_PARAMETER(aOut);
 
 
87150 #endif
87151 {
87152 aLog[i] = sqlite3LogEst(v);
87153 }
87154 if( *z==' ' ) z++;
87155 }
87156 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4
87157 assert( pIndex!=0 );
87158 #else
@@ -87209,12 +87285,21 @@
87209 pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
87210 }
87211 z = argv[2];
87212
87213 if( pIndex ){
 
 
 
 
 
 
 
 
 
87214 pIndex->bUnordered = 0;
87215 decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
87216 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
87217 }else{
87218 Index fakeIdx;
87219 fakeIdx.szIdxRow = pTable->szTabRow;
87220 #ifdef SQLITE_ENABLE_COSTMULT
@@ -87269,29 +87354,42 @@
87269 ** unique. */
87270 nCol = pIdx->nSampleCol-1;
87271 pIdx->aAvgEq[nCol] = 1;
87272 }
87273 for(iCol=0; iCol<nCol; iCol++){
 
87274 int i; /* Used to iterate through samples */
87275 tRowcnt sumEq = 0; /* Sum of the nEq values */
87276 tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
87277 tRowcnt avgEq = 0;
87278 tRowcnt nDLt = pFinal->anDLt[iCol];
 
 
 
 
 
 
 
 
 
 
 
87279
87280 /* Set nSum to the number of distinct (iCol+1) field prefixes that
87281 ** occur in the stat4 table for this index before pFinal. Set
87282 ** sumEq to the sum of the nEq values for column iCol for the same
87283 ** set (adding the value only once where there exist duplicate
87284 ** prefixes). */
87285 for(i=0; i<(pIdx->nSample-1); i++){
87286 if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
 
87287 sumEq += aSample[i].anEq[iCol];
87288 nSum++;
87289 }
87290 }
87291 if( nDLt>nSum ){
87292 avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
 
87293 }
87294 if( avgEq==0 ) avgEq = 1;
87295 pIdx->aAvgEq[iCol] = avgEq;
87296 }
87297 }
@@ -87538,10 +87636,15 @@
87538 if( rc==SQLITE_OK ){
87539 int lookasideEnabled = db->lookaside.bEnabled;
87540 db->lookaside.bEnabled = 0;
87541 rc = loadStat4(db, sInfo.zDatabase);
87542 db->lookaside.bEnabled = lookasideEnabled;
 
 
 
 
 
87543 }
87544 #endif
87545
87546 if( rc==SQLITE_NOMEM ){
87547 db->mallocFailed = 1;
@@ -88832,10 +88935,13 @@
88832 #endif
88833 if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
88834 sqlite3ExprDelete(db, p->pPartIdxWhere);
88835 sqlite3DbFree(db, p->zColAff);
88836 if( p->isResized ) sqlite3DbFree(db, p->azColl);
 
 
 
88837 sqlite3DbFree(db, p);
88838 }
88839
88840 /*
88841 ** For the index called zIdxName which is found in the database iDb,
@@ -89633,11 +89739,11 @@
89633 Column *pCol;
89634 sqlite3 *db = pParse->db;
89635 p = pParse->pNewTable;
89636 if( p!=0 ){
89637 pCol = &(p->aCol[p->nCol-1]);
89638 if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
89639 sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
89640 pCol->zName);
89641 }else{
89642 /* A copy of pExpr is used instead of the original, as pExpr contains
89643 ** tokens that point to volatile memory. The 'span' of the expression
@@ -91141,11 +91247,11 @@
91141 pIndex->nKeyCol); VdbeCoverage(v);
91142 sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
91143 }else{
91144 addr2 = sqlite3VdbeCurrentAddr(v);
91145 }
91146 sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
91147 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
91148 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
91149 sqlite3ReleaseTempReg(pParse, regRecord);
91150 sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
91151 sqlite3VdbeJumpHere(v, addr1);
@@ -94030,11 +94136,14 @@
94030
94031 /*
94032 ** Return the collating function associated with a function.
94033 */
94034 static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
94035 return context->pColl;
 
 
 
94036 }
94037
94038 /*
94039 ** Indicate that the accumulator load should be skipped on this
94040 ** iteration of the aggregate loop.
@@ -94575,14 +94684,16 @@
94575 ** character is exactly one byte in size. Also, all characters are
94576 ** able to participate in upper-case-to-lower-case mappings in EBCDIC
94577 ** whereas only characters less than 0x80 do in ASCII.
94578 */
94579 #if defined(SQLITE_EBCDIC)
94580 # define sqlite3Utf8Read(A) (*((*A)++))
94581 # define GlobUpperToLower(A) A = sqlite3UpperToLower[A]
 
94582 #else
94583 # define GlobUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
 
94584 #endif
94585
94586 static const struct compareInfo globInfo = { '*', '?', '[', 0 };
94587 /* The correct SQL-92 behavior is for the LIKE operator to ignore
94588 ** case. Thus 'a' LIKE 'A' would be true. */
@@ -94591,11 +94702,11 @@
94591 ** is case sensitive causing 'a' LIKE 'A' to be false */
94592 static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
94593
94594 /*
94595 ** Compare two UTF-8 strings for equality where the first string can
94596 ** potentially be a "glob" expression. Return true (1) if they
94597 ** are the same and false (0) if they are different.
94598 **
94599 ** Globbing rules:
94600 **
94601 ** '*' Matches any sequence of zero or more characters.
@@ -94611,120 +94722,147 @@
94611 ** in the list by making it the first character after '[' or '^'. A
94612 ** range of characters can be specified using '-'. Example:
94613 ** "[a-z]" matches any single lower-case letter. To match a '-', make
94614 ** it the last character in the list.
94615 **
 
 
 
 
 
 
 
 
 
 
 
94616 ** This routine is usually quick, but can be N**2 in the worst case.
94617 **
94618 ** Hints: to match '*' or '?', put them in "[]". Like this:
94619 **
94620 ** abc[*]xyz Matches "abc*xyz" only
94621 */
94622 static int patternCompare(
94623 const u8 *zPattern, /* The glob pattern */
94624 const u8 *zString, /* The string to compare against the glob */
94625 const struct compareInfo *pInfo, /* Information about how to do the compare */
94626 u32 esc /* The escape character */
94627 ){
94628 u32 c, c2;
94629 int invert;
94630 int seen;
94631 u8 matchOne = pInfo->matchOne;
94632 u8 matchAll = pInfo->matchAll;
94633 u8 matchSet = pInfo->matchSet;
94634 u8 noCase = pInfo->noCase;
94635 int prevEscape = 0; /* True if the previous character was 'escape' */
 
 
 
 
 
94636
94637 while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
94638 if( c==matchAll && !prevEscape ){
 
 
 
94639 while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
94640 || c == matchOne ){
94641 if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
94642 return 0;
94643 }
94644 }
94645 if( c==0 ){
94646 return 1;
94647 }else if( c==esc ){
94648 c = sqlite3Utf8Read(&zPattern);
94649 if( c==0 ){
94650 return 0;
94651 }
94652 }else if( c==matchSet ){
94653 assert( esc==0 ); /* This is GLOB, not LIKE */
94654 assert( matchSet<0x80 ); /* '[' is a single-byte character */
94655 while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
94656 SQLITE_SKIP_UTF8(zString);
94657 }
94658 return *zString!=0;
94659 }
94660 while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
94661 if( noCase ){
94662 GlobUpperToLower(c2);
94663 GlobUpperToLower(c);
94664 while( c2 != 0 && c2 != c ){
94665 c2 = sqlite3Utf8Read(&zString);
94666 GlobUpperToLower(c2);
94667 }
94668 }else{
94669 while( c2 != 0 && c2 != c ){
94670 c2 = sqlite3Utf8Read(&zString);
94671 }
94672 }
94673 if( c2==0 ) return 0;
94674 if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
94675 }
94676 return 0;
94677 }else if( c==matchOne && !prevEscape ){
94678 if( sqlite3Utf8Read(&zString)==0 ){
94679 return 0;
94680 }
94681 }else if( c==matchSet ){
94682 u32 prior_c = 0;
94683 assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
94684 seen = 0;
94685 invert = 0;
94686 c = sqlite3Utf8Read(&zString);
94687 if( c==0 ) return 0;
94688 c2 = sqlite3Utf8Read(&zPattern);
94689 if( c2=='^' ){
94690 invert = 1;
94691 c2 = sqlite3Utf8Read(&zPattern);
94692 }
94693 if( c2==']' ){
94694 if( c==']' ) seen = 1;
94695 c2 = sqlite3Utf8Read(&zPattern);
94696 }
94697 while( c2 && c2!=']' ){
94698 if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
94699 c2 = sqlite3Utf8Read(&zPattern);
94700 if( c>=prior_c && c<=c2 ) seen = 1;
94701 prior_c = 0;
94702 }else{
94703 if( c==c2 ){
94704 seen = 1;
94705 }
94706 prior_c = c2;
94707 }
94708 c2 = sqlite3Utf8Read(&zPattern);
94709 }
94710 if( c2==0 || (seen ^ invert)==0 ){
94711 return 0;
94712 }
94713 }else if( esc==c && !prevEscape ){
94714 prevEscape = 1;
94715 }else{
94716 c2 = sqlite3Utf8Read(&zString);
94717 if( noCase ){
94718 GlobUpperToLower(c);
94719 GlobUpperToLower(c2);
94720 }
94721 if( c!=c2 ){
94722 return 0;
94723 }
94724 prevEscape = 0;
94725 }
 
 
 
 
 
 
 
 
 
 
 
 
94726 }
94727 return *zString==0;
94728 }
94729
94730 /*
@@ -103884,10 +104022,24 @@
103884 **
103885 *************************************************************************
103886 ** This file contains C code routines that are called by the parser
103887 ** to handle SELECT statements in SQLite.
103888 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103889
103890 /*
103891 ** An instance of the following object is used to record information about
103892 ** how to process the DISTINCT keyword, to simplify passing that information
103893 ** into the selectInnerLoop() routine.
@@ -103996,10 +104148,22 @@
103996 assert( pNew->pSrc!=0 || pParse->nErr>0 );
103997 }
103998 assert( pNew!=&standin );
103999 return pNew;
104000 }
 
 
 
 
 
 
 
 
 
 
 
 
104001
104002 /*
104003 ** Delete the given Select structure and all of its substructures.
104004 */
104005 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
@@ -105026,11 +105190,10 @@
105026 int regRow;
105027 int regRowid;
105028 int nKey;
105029 int iSortTab; /* Sorter cursor to read from */
105030 int nSortData; /* Trailing values to read from sorter */
105031 u8 p5; /* p5 parameter for 1st OP_Column */
105032 int i;
105033 int bSeq; /* True if sorter record includes seq. no. */
105034 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
105035 struct ExprList_item *aOutEx = p->pEList->a;
105036 #endif
@@ -105060,23 +105223,20 @@
105060 sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
105061 if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
105062 addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
105063 VdbeCoverage(v);
105064 codeOffset(v, p->iOffset, addrContinue);
105065 sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
105066 p5 = OPFLAG_CLEARCACHE;
105067 bSeq = 0;
105068 }else{
105069 addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
105070 codeOffset(v, p->iOffset, addrContinue);
105071 iSortTab = iTab;
105072 p5 = 0;
105073 bSeq = 1;
105074 }
105075 for(i=0; i<nSortData; i++){
105076 sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
105077 if( i==0 ) sqlite3VdbeChangeP5(v, p5);
105078 VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
105079 }
105080 switch( eDest ){
105081 case SRT_Table:
105082 case SRT_EphemTab: {
@@ -107226,10 +107386,12 @@
107226 }
107227 }
107228 }
107229
107230 /***** If we reach this point, flattening is permitted. *****/
 
 
107231
107232 /* Authorize the subquery */
107233 pParse->zAuthContext = pSubitem->zName;
107234 TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
107235 testcase( i==SQLITE_DENY );
@@ -107278,10 +107440,11 @@
107278 p->pSrc = 0;
107279 p->pPrior = 0;
107280 p->pLimit = 0;
107281 p->pOffset = 0;
107282 pNew = sqlite3SelectDup(db, p, 0);
 
107283 p->pOffset = pOffset;
107284 p->pLimit = pLimit;
107285 p->pOrderBy = pOrderBy;
107286 p->pSrc = pSrc;
107287 p->op = TK_ALL;
@@ -107290,10 +107453,13 @@
107290 }else{
107291 pNew->pPrior = pPrior;
107292 if( pPrior ) pPrior->pNext = pNew;
107293 pNew->pNext = p;
107294 p->pPrior = pNew;
 
 
 
107295 }
107296 if( db->mallocFailed ) return 1;
107297 }
107298
107299 /* Begin flattening the iFrom-th entry of the FROM clause
@@ -107419,12 +107585,27 @@
107419 if( isAgg ){
107420 substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
107421 pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
107422 }
107423 if( pSub->pOrderBy ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107424 assert( pParent->pOrderBy==0 );
107425 pParent->pOrderBy = pSub->pOrderBy;
 
107426 pSub->pOrderBy = 0;
107427 }else if( pParent->pOrderBy ){
107428 substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
107429 }
107430 if( pSub->pWhere ){
@@ -107465,10 +107646,17 @@
107465
107466 /* Finially, delete what is left of the subquery and return
107467 ** success.
107468 */
107469 sqlite3SelectDelete(db, pSub1);
 
 
 
 
 
 
 
107470
107471 return 1;
107472 }
107473 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
107474
@@ -107936,10 +108124,11 @@
107936 if( pTab->pSelect || IsVirtual(pTab) ){
107937 /* We reach here if the named table is a really a view */
107938 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
107939 assert( pFrom->pSelect==0 );
107940 pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
 
107941 sqlite3WalkSelect(pWalker, pFrom->pSelect);
107942 }
107943 #endif
107944 }
107945
@@ -108470,10 +108659,17 @@
108470 if( p==0 || db->mallocFailed || pParse->nErr ){
108471 return 1;
108472 }
108473 if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
108474 memset(&sAggInfo, 0, sizeof(sAggInfo));
 
 
 
 
 
 
 
108475
108476 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
108477 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
108478 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
108479 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
@@ -108626,10 +108822,14 @@
108626 /* If there is are a sequence of queries, do the earlier ones first.
108627 */
108628 if( p->pPrior ){
108629 rc = multiSelect(pParse, p, pDest);
108630 explainSetInteger(pParse->iSelectId, iRestoreSelectId);
 
 
 
 
108631 return rc;
108632 }
108633 #endif
108634
108635 /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
@@ -108961,16 +109161,15 @@
108961 ** from the previous row currently stored in a0, a1, a2...
108962 */
108963 addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
108964 sqlite3ExprCacheClear(pParse);
108965 if( groupBySort ){
108966 sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
108967 }
108968 for(j=0; j<pGroupBy->nExpr; j++){
108969 if( groupBySort ){
108970 sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
108971 if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
108972 }else{
108973 sAggInfo.directMode = 1;
108974 sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
108975 }
108976 }
@@ -109225,107 +109424,110 @@
109225 generateColumnNames(pParse, pTabList, pEList);
109226 }
109227
109228 sqlite3DbFree(db, sAggInfo.aCol);
109229 sqlite3DbFree(db, sAggInfo.aFunc);
 
 
 
 
109230 return rc;
109231 }
109232
109233 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
109234 /*
109235 ** Generate a human-readable description of a the Select object.
109236 */
109237 static void explainOneSelect(Vdbe *pVdbe, Select *p){
109238 sqlite3ExplainPrintf(pVdbe, "SELECT ");
109239 if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
109240 if( p->selFlags & SF_Distinct ){
109241 sqlite3ExplainPrintf(pVdbe, "DISTINCT ");
109242 }
109243 if( p->selFlags & SF_Aggregate ){
109244 sqlite3ExplainPrintf(pVdbe, "agg_flag ");
109245 }
109246 sqlite3ExplainNL(pVdbe);
109247 sqlite3ExplainPrintf(pVdbe, " ");
109248 }
109249 sqlite3ExplainExprList(pVdbe, p->pEList);
109250 sqlite3ExplainNL(pVdbe);
 
 
109251 if( p->pSrc && p->pSrc->nSrc ){
109252 int i;
109253 sqlite3ExplainPrintf(pVdbe, "FROM ");
109254 sqlite3ExplainPush(pVdbe);
109255 for(i=0; i<p->pSrc->nSrc; i++){
109256 struct SrcList_item *pItem = &p->pSrc->a[i];
109257 sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
109258 if( pItem->pSelect ){
109259 sqlite3ExplainSelect(pVdbe, pItem->pSelect);
109260 if( pItem->pTab ){
109261 sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
109262 }
109263 }else if( pItem->zName ){
109264 sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName);
 
 
 
109265 }
109266 if( pItem->zAlias ){
109267 sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
109268 }
109269 if( pItem->jointype & JT_LEFT ){
109270 sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN");
109271 }
109272 sqlite3ExplainNL(pVdbe);
 
 
 
 
 
109273 }
109274 sqlite3ExplainPop(pVdbe);
109275 }
109276 if( p->pWhere ){
109277 sqlite3ExplainPrintf(pVdbe, "WHERE ");
109278 sqlite3ExplainExpr(pVdbe, p->pWhere);
109279 sqlite3ExplainNL(pVdbe);
109280 }
109281 if( p->pGroupBy ){
109282 sqlite3ExplainPrintf(pVdbe, "GROUPBY ");
109283 sqlite3ExplainExprList(pVdbe, p->pGroupBy);
109284 sqlite3ExplainNL(pVdbe);
109285 }
109286 if( p->pHaving ){
109287 sqlite3ExplainPrintf(pVdbe, "HAVING ");
109288 sqlite3ExplainExpr(pVdbe, p->pHaving);
109289 sqlite3ExplainNL(pVdbe);
109290 }
109291 if( p->pOrderBy ){
109292 sqlite3ExplainPrintf(pVdbe, "ORDERBY ");
109293 sqlite3ExplainExprList(pVdbe, p->pOrderBy);
109294 sqlite3ExplainNL(pVdbe);
109295 }
109296 if( p->pLimit ){
109297 sqlite3ExplainPrintf(pVdbe, "LIMIT ");
109298 sqlite3ExplainExpr(pVdbe, p->pLimit);
109299 sqlite3ExplainNL(pVdbe);
109300 }
109301 if( p->pOffset ){
109302 sqlite3ExplainPrintf(pVdbe, "OFFSET ");
109303 sqlite3ExplainExpr(pVdbe, p->pOffset);
109304 sqlite3ExplainNL(pVdbe);
109305 }
109306 }
109307 SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
109308 if( p==0 ){
109309 sqlite3ExplainPrintf(pVdbe, "(null-select)");
109310 return;
109311 }
109312 sqlite3ExplainPush(pVdbe);
109313 while( p ){
109314 explainOneSelect(pVdbe, p);
109315 p = p->pNext;
109316 if( p==0 ) break;
109317 sqlite3ExplainNL(pVdbe);
109318 sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
109319 }
109320 sqlite3ExplainPrintf(pVdbe, "END");
109321 sqlite3ExplainPop(pVdbe);
109322 }
109323
109324 /* End of the structure debug printing code
109325 *****************************************************************************/
109326 #endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
109327
109328 /************** End of select.c **********************************************/
109329 /************** Begin file table.c *******************************************/
109330 /*
109331 ** 2001 September 15
@@ -112311,10 +112513,11 @@
112311 }
112312 sqlite3DbFree(db, pVTable);
112313 }else if( ALWAYS(pVTable->pVtab) ){
112314 /* Justification of ALWAYS(): A correct vtab constructor must allocate
112315 ** the sqlite3_vtab object if successful. */
 
112316 pVTable->pVtab->pModule = pMod->pModule;
112317 pVTable->nRef = 1;
112318 if( sCtx.pTab ){
112319 const char *zFormat = "vtable constructor did not declare schema: %s";
112320 *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
@@ -113719,15 +113922,10 @@
113719 assert( TK_LE>TK_EQ && TK_LE<TK_GE );
113720 assert( TK_GE==TK_EQ+4 );
113721 return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
113722 }
113723
113724 /*
113725 ** Swap two objects of type TYPE.
113726 */
113727 #define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
113728
113729 /*
113730 ** Commute a comparison operator. Expressions of the form "X op Y"
113731 ** are converted into "Y op X".
113732 **
113733 ** If left/right precedence rules come into play when determining the
@@ -115566,21 +115764,28 @@
115566 ** have been requested when testing key $P in whereEqualScanEst(). */
115567 whereKeyStats(pParse, p, pRec, 0, a);
115568 iLower = a[0];
115569 iUpper = a[0] + a[1];
115570 }
 
 
 
 
 
 
 
 
115571
115572 /* If possible, improve on the iLower estimate using ($P:$L). */
115573 if( pLower ){
115574 int bOk; /* True if value is extracted from pExpr */
115575 Expr *pExpr = pLower->pExpr->pRight;
115576 assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115577 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115578 if( rc==SQLITE_OK && bOk ){
115579 tRowcnt iNew;
115580 whereKeyStats(pParse, p, pRec, 0, a);
115581 iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
115582 if( iNew>iLower ) iLower = iNew;
115583 nOut--;
115584 pLower = 0;
115585 }
115586 }
@@ -115587,16 +115792,15 @@
115587
115588 /* If possible, improve on the iUpper estimate using ($P:$U). */
115589 if( pUpper ){
115590 int bOk; /* True if value is extracted from pExpr */
115591 Expr *pExpr = pUpper->pExpr->pRight;
115592 assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115593 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115594 if( rc==SQLITE_OK && bOk ){
115595 tRowcnt iNew;
115596 whereKeyStats(pParse, p, pRec, 1, a);
115597 iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
115598 if( iNew<iUpper ) iUpper = iNew;
115599 nOut--;
115600 pUpper = 0;
115601 }
115602 }
@@ -116091,65 +116295,52 @@
116091 sqlite3StrAccumAppend(pStr, "?", 1);
116092 }
116093
116094 /*
116095 ** Argument pLevel describes a strategy for scanning table pTab. This
116096 ** function returns a pointer to a string buffer containing a description
116097 ** of the subset of table rows scanned by the strategy in the form of an
116098 ** SQL expression. Or, if all rows are scanned, NULL is returned.
116099 **
116100 ** For example, if the query:
116101 **
116102 ** SELECT * FROM t1 WHERE a=1 AND b>2;
116103 **
116104 ** is run and there is an index on (a, b), then this function returns a
116105 ** string similar to:
116106 **
116107 ** "a=? AND b>?"
116108 **
116109 ** The returned pointer points to memory obtained from sqlite3DbMalloc().
116110 ** It is the responsibility of the caller to free the buffer when it is
116111 ** no longer required.
116112 */
116113 static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
116114 Index *pIndex = pLoop->u.btree.pIndex;
116115 u16 nEq = pLoop->u.btree.nEq;
116116 u16 nSkip = pLoop->u.btree.nSkip;
116117 int i, j;
116118 Column *aCol = pTab->aCol;
116119 i16 *aiColumn = pIndex->aiColumn;
116120 StrAccum txt;
116121
116122 if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
116123 return 0;
116124 }
116125 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
116126 txt.db = db;
116127 sqlite3StrAccumAppend(&txt, " (", 2);
116128 for(i=0; i<nEq; i++){
116129 char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
116130 if( i>=nSkip ){
116131 explainAppendTerm(&txt, i, z, "=");
116132 }else{
116133 if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
116134 sqlite3StrAccumAppend(&txt, "ANY(", 4);
116135 sqlite3StrAccumAppendAll(&txt, z);
116136 sqlite3StrAccumAppend(&txt, ")", 1);
116137 }
116138 }
116139
116140 j = i;
116141 if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
116142 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116143 explainAppendTerm(&txt, i++, z, ">");
116144 }
116145 if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
116146 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116147 explainAppendTerm(&txt, i, z, "<");
116148 }
116149 sqlite3StrAccumAppend(&txt, ")", 1);
116150 return sqlite3StrAccumFinish(&txt);
116151 }
116152
116153 /*
116154 ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
116155 ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
@@ -116169,72 +116360,90 @@
116169 #endif
116170 {
116171 struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
116172 Vdbe *v = pParse->pVdbe; /* VM being constructed */
116173 sqlite3 *db = pParse->db; /* Database handle */
116174 char *zMsg; /* Text to add to EQP output */
116175 int iId = pParse->iSelectId; /* Select id (left-most output column) */
116176 int isSearch; /* True for a SEARCH. False for SCAN. */
116177 WhereLoop *pLoop; /* The controlling WhereLoop object */
116178 u32 flags; /* Flags that describe this loop */
 
 
 
116179
116180 pLoop = pLevel->pWLoop;
116181 flags = pLoop->wsFlags;
116182 if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
116183
116184 isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
116185 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
116186 || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
116187
116188 zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
 
 
116189 if( pItem->pSelect ){
116190 zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
116191 }else{
116192 zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
116193 }
116194
116195 if( pItem->zAlias ){
116196 zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
116197 }
116198 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
116199 && ALWAYS(pLoop->u.btree.pIndex!=0)
116200 ){
116201 const char *zFmt;
116202 Index *pIdx = pLoop->u.btree.pIndex;
116203 char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
116204 assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
116205 if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
116206 zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s";
 
 
116207 }else if( flags & WHERE_AUTO_INDEX ){
116208 zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s";
116209 }else if( flags & WHERE_IDX_ONLY ){
116210 zFmt = "%s USING COVERING INDEX %s%s";
116211 }else{
116212 zFmt = "%s USING INDEX %s%s";
116213 }
116214 zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere);
116215 sqlite3DbFree(db, zWhere);
 
 
 
116216 }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
116217 zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
116218
116219 if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
116220 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
116221 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
116222 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
116223 }else if( flags&WHERE_BTM_LIMIT ){
116224 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
116225 }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
116226 zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
 
116227 }
 
 
116228 }
116229 #ifndef SQLITE_OMIT_VIRTUALTABLE
116230 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
116231 zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
116232 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
116233 }
116234 #endif
116235 zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
 
 
 
 
 
 
 
116236 sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
116237 }
116238 }
116239 #else
116240 # define explainOneScan(u,v,w,x,y,z)
@@ -116884,12 +117093,13 @@
116884
116885 /* Run a separate WHERE clause for each term of the OR clause. After
116886 ** eliminating duplicates from other WHERE clauses, the action for each
116887 ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
116888 */
116889 wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
116890 WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY;
 
116891 for(ii=0; ii<pOrWc->nTerm; ii++){
116892 WhereTerm *pOrTerm = &pOrWc->a[ii];
116893 if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
116894 WhereInfo *pSubWInfo; /* Info for single OR-term scan */
116895 Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
@@ -116897,10 +117107,11 @@
116897 if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
116898 pAndExpr->pLeft = pOrExpr;
116899 pOrExpr = pAndExpr;
116900 }
116901 /* Loop through table entries that match term pOrTerm. */
 
116902 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
116903 wctrlFlags, iCovCur);
116904 assert( pSubWInfo || pParse->nErr || db->mallocFailed );
116905 if( pSubWInfo ){
116906 WhereLoop *pSubLoop;
@@ -117116,25 +117327,30 @@
117116 }
117117
117118 return pLevel->notReady;
117119 }
117120
117121 #if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
117122 /*
117123 ** Generate "Explanation" text for a WhereTerm.
117124 */
117125 static void whereExplainTerm(Vdbe *v, WhereTerm *pTerm){
117126 char zType[4];
117127 memcpy(zType, "...", 4);
117128 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
117129 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
117130 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
117131 sqlite3ExplainPrintf(v, "%s ", zType);
117132 sqlite3ExplainExpr(v, pTerm->pExpr);
117133 }
117134 #endif /* WHERETRACE_ENABLED && SQLITE_ENABLE_TREE_EXPLAIN */
117135
 
 
 
 
 
117136
117137 #ifdef WHERETRACE_ENABLED
117138 /*
117139 ** Print a WhereLoop object for debugging purposes
117140 */
@@ -117174,31 +117390,16 @@
117174 sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
117175 }else{
117176 sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
117177 }
117178 sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
117179 #ifdef SQLITE_ENABLE_TREE_EXPLAIN
117180 /* If the 0x100 bit of wheretracing is set, then show all of the constraint
117181 ** expressions in the WhereLoop.aLTerm[] array.
117182 */
117183 if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ /* WHERETRACE 0x100 */
117184 int i;
117185 Vdbe *v = pWInfo->pParse->pVdbe;
117186 sqlite3ExplainBegin(v);
117187 for(i=0; i<p->nLTerm; i++){
117188 WhereTerm *pTerm = p->aLTerm[i];
117189 if( pTerm==0 ) continue;
117190 sqlite3ExplainPrintf(v, " (%d) #%-2d ", i+1, (int)(pTerm-pWC->a));
117191 sqlite3ExplainPush(v);
117192 whereExplainTerm(v, pTerm);
117193 sqlite3ExplainPop(v);
117194 sqlite3ExplainNL(v);
117195 }
117196 sqlite3ExplainFinish(v);
117197 sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
117198 }
117199 #endif
117200 }
117201 #endif
117202
117203 /*
117204 ** Convert bulk memory into a valid WhereLoop that can be passed
@@ -117507,11 +117708,11 @@
117507 if( ppPrev==0 ){
117508 /* There already exists a WhereLoop on the list that is better
117509 ** than pTemplate, so just ignore pTemplate */
117510 #if WHERETRACE_ENABLED /* 0x8 */
117511 if( sqlite3WhereTrace & 0x8 ){
117512 sqlite3DebugPrintf("ins-noop: ");
117513 whereLoopPrint(pTemplate, pBuilder->pWC);
117514 }
117515 #endif
117516 return SQLITE_OK;
117517 }else{
@@ -117523,14 +117724,14 @@
117523 ** WhereLoop and insert it.
117524 */
117525 #if WHERETRACE_ENABLED /* 0x8 */
117526 if( sqlite3WhereTrace & 0x8 ){
117527 if( p!=0 ){
117528 sqlite3DebugPrintf("ins-del: ");
117529 whereLoopPrint(p, pBuilder->pWC);
117530 }
117531 sqlite3DebugPrintf("ins-new: ");
117532 whereLoopPrint(pTemplate, pBuilder->pWC);
117533 }
117534 #endif
117535 if( p==0 ){
117536 /* Allocate a new WhereLoop to add to the end of the list */
@@ -117550,11 +117751,11 @@
117550 pToDel = *ppTail;
117551 if( pToDel==0 ) break;
117552 *ppTail = pToDel->pNextLoop;
117553 #if WHERETRACE_ENABLED /* 0x8 */
117554 if( sqlite3WhereTrace & 0x8 ){
117555 sqlite3DebugPrintf("ins-del: ");
117556 whereLoopPrint(pToDel, pBuilder->pWC);
117557 }
117558 #endif
117559 whereLoopDelete(db, pToDel);
117560 }
@@ -117714,15 +117915,18 @@
117714 pNew->aLTerm[pNew->nLTerm++] = 0;
117715 pNew->wsFlags |= WHERE_SKIPSCAN;
117716 nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
117717 if( pTerm ){
117718 /* TUNING: When estimating skip-scan for a term that is also indexable,
117719 ** increase the cost of the skip-scan by 2x, to make it a little less
117720 ** desirable than the regular index lookup. */
117721 nIter += 10; assert( 10==sqlite3LogEst(2) );
117722 }
117723 pNew->nOut -= nIter;
 
 
 
117724 whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
117725 pNew->nOut = saved_nOut;
117726 pNew->u.btree.nEq = saved_nEq;
117727 pNew->u.btree.nSkip = saved_nSkip;
117728 }
@@ -118073,13 +118277,21 @@
118073 pNew->u.btree.nSkip = 0;
118074 pNew->u.btree.pIndex = 0;
118075 pNew->nLTerm = 1;
118076 pNew->aLTerm[0] = pTerm;
118077 /* TUNING: One-time cost for computing the automatic index is
118078 ** approximately 7*N*log2(N) where N is the number of rows in
118079 ** the table being indexed. */
118080 pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) );
 
 
 
 
 
 
 
 
118081 ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
118082 /* TUNING: Each index lookup yields 20 rows in the table. This
118083 ** is more than the usual guess of 10 rows, since we have no way
118084 ** of knowing how selective the index will ultimately be. It would
118085 ** not be unreasonable to make this value much larger. */
@@ -118363,11 +118575,10 @@
118363 WhereLoopBuilder sSubBuild;
118364 WhereOrSet sSum, sCur;
118365 struct SrcList_item *pItem;
118366
118367 pWC = pBuilder->pWC;
118368 if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
118369 pWCEnd = pWC->a + pWC->nTerm;
118370 pNew = pBuilder->pNew;
118371 memset(&sSum, 0, sizeof(sSum));
118372 pItem = pWInfo->pTabList->a + pNew->iTab;
118373 iCur = pItem->iCursor;
@@ -118384,10 +118595,11 @@
118384
118385 sSubBuild = *pBuilder;
118386 sSubBuild.pOrderBy = 0;
118387 sSubBuild.pOrSet = &sCur;
118388
 
118389 for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
118390 if( (pOrTerm->eOperator & WO_AND)!=0 ){
118391 sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
118392 }else if( pOrTerm->leftCursor==iCur ){
118393 tempWC.pWInfo = pWC->pWInfo;
@@ -118398,18 +118610,30 @@
118398 sSubBuild.pWC = &tempWC;
118399 }else{
118400 continue;
118401 }
118402 sCur.n = 0;
 
 
 
 
 
 
 
 
 
118403 #ifndef SQLITE_OMIT_VIRTUALTABLE
118404 if( IsVirtual(pItem->pTab) ){
118405 rc = whereLoopAddVirtual(&sSubBuild, mExtra);
118406 }else
118407 #endif
118408 {
118409 rc = whereLoopAddBtree(&sSubBuild, mExtra);
118410 }
 
 
 
118411 assert( rc==SQLITE_OK || sCur.n==0 );
118412 if( sCur.n==0 ){
118413 sSum.n = 0;
118414 break;
118415 }else if( once ){
@@ -118450,10 +118674,11 @@
118450 pNew->rRun = sSum.a[i].rRun + 1;
118451 pNew->nOut = sSum.a[i].nOut;
118452 pNew->prereq = sSum.a[i].prereq;
118453 rc = whereLoopInsert(pBuilder, pNew);
118454 }
 
118455 }
118456 }
118457 return rc;
118458 }
118459
@@ -118693,11 +118918,11 @@
118693 if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
118694 }
118695 isMatch = 1;
118696 break;
118697 }
118698 if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
118699 /* Make sure the sort order is compatible in an ORDER BY clause.
118700 ** Sort order is irrelevant for a GROUP BY clause. */
118701 if( revSet ){
118702 if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
118703 }else{
@@ -119158,16 +119383,19 @@
119158 pWInfo->revMask = pFrom->revLoop;
119159 }
119160 if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
119161 && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
119162 ){
119163 Bitmask notUsed = 0;
119164 int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
119165 pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed
119166 );
119167 assert( pWInfo->sorted==0 );
119168 pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr);
 
 
 
119169 }
119170 }
119171
119172
119173 pWInfo->nRowOut = pFrom->nRow;
@@ -119516,27 +119744,20 @@
119516 }
119517 }
119518
119519 /* Construct the WhereLoop objects */
119520 WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
 
119521 /* Display all terms of the WHERE clause */
119522 #if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
119523 if( sqlite3WhereTrace & 0x100 ){
119524 int i;
119525 Vdbe *v = pParse->pVdbe;
119526 sqlite3ExplainBegin(v);
119527 for(i=0; i<sWLB.pWC->nTerm; i++){
119528 sqlite3ExplainPrintf(v, "#%-2d ", i);
119529 sqlite3ExplainPush(v);
119530 whereExplainTerm(v, &sWLB.pWC->a[i]);
119531 sqlite3ExplainPop(v);
119532 sqlite3ExplainNL(v);
119533 }
119534 sqlite3ExplainFinish(v);
119535 sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
119536 }
119537 #endif
 
119538 if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
119539 rc = whereLoopAddAll(&sWLB);
119540 if( rc ) goto whereBeginError;
119541
119542 /* Display all of the WhereLoop objects if wheretrace is enabled */
@@ -120059,11 +120280,11 @@
120059
120060 /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
120061 ** unary TK_ISNULL or TK_NOTNULL expression. */
120062 static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
120063 sqlite3 *db = pParse->db;
120064 if( db->mallocFailed==0 && pY->op==TK_NULL ){
120065 pA->op = (u8)op;
120066 sqlite3ExprDelete(db, pA->pRight);
120067 pA->pRight = 0;
120068 }
120069 }
@@ -122318,13 +122539,10 @@
122318 break;
122319 case 111: /* cmd ::= select */
122320 {
122321 SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
122322 sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
122323 sqlite3ExplainBegin(pParse->pVdbe);
122324 sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy3);
122325 sqlite3ExplainFinish(pParse->pVdbe);
122326 sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
122327 }
122328 break;
122329 case 112: /* select ::= with selectnowith */
122330 {
@@ -122377,10 +122595,34 @@
122377 {yygotominor.yy328 = TK_ALL;}
122378 break;
122379 case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
122380 {
122381 yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122382 }
122383 break;
122384 case 120: /* values ::= VALUES LP nexprlist RP */
122385 {
122386 yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
@@ -123868,10 +124110,11 @@
123868 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */
123869 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */
123870 };
123871 #define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
123872 #endif
 
123873
123874
123875 /*
123876 ** Return the length of the token that begins at z[0].
123877 ** Store the token type in *tokenType before returning.
@@ -125138,10 +125381,15 @@
125138 sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
125139 sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
125140 break;
125141 }
125142
 
 
 
 
 
125143 case SQLITE_CONFIG_URI: {
125144 sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
125145 break;
125146 }
125147
@@ -126875,11 +127123,11 @@
126875 int nUri = sqlite3Strlen30(zUri);
126876
126877 assert( *pzErrMsg==0 );
126878
126879 if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
126880 && nUri>=5 && memcmp(zUri, "file:", 5)==0
126881 ){
126882 char *zOpt;
126883 int eState; /* Parser state when parsing URI */
126884 int iIn; /* Input character index */
126885 int iOut = 0; /* Output character index */
@@ -127105,11 +127353,13 @@
127105 assert( SQLITE_OPEN_READWRITE == 0x02 );
127106 assert( SQLITE_OPEN_CREATE == 0x04 );
127107 testcase( (1<<(flags&7))==0x02 ); /* READONLY */
127108 testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
127109 testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
127110 if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT;
 
 
127111
127112 if( sqlite3GlobalConfig.bCoreMutex==0 ){
127113 isThreadsafe = 0;
127114 }else if( flags & SQLITE_OPEN_NOMUTEX ){
127115 isThreadsafe = 0;
@@ -127989,26 +128239,10 @@
127989 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
127990 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
127991 break;
127992 }
127993
127994 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
127995 /* sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
127996 ** sqlite3_stmt*,const char**);
127997 **
127998 ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds
127999 ** a string that describes the optimized parse tree. This test-control
128000 ** returns a pointer to that string.
128001 */
128002 case SQLITE_TESTCTRL_EXPLAIN_STMT: {
128003 sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*);
128004 const char **pzRet = va_arg(ap, const char**);
128005 *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt);
128006 break;
128007 }
128008 #endif
128009
128010 /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
128011 **
128012 ** Set or clear a flag that indicates that the database file is always well-
128013 ** formed and never corrupt. This flag is clear by default, indicating that
128014 ** database files might have arbitrary corruption. Setting the flag during
@@ -132464,10 +132698,11 @@
132464 assert( iIdx==nVal );
132465
132466 /* In case the cursor has been used before, clear it now. */
132467 sqlite3_finalize(pCsr->pStmt);
132468 sqlite3_free(pCsr->aDoclist);
 
132469 sqlite3Fts3ExprFree(pCsr->pExpr);
132470 memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
132471
132472 /* Set the lower and upper bounds on docids to return */
132473 pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -133774,11 +134009,11 @@
133774 if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
133775 iMax = a[i].iDocid;
133776 bMaxSet = 1;
133777 }
133778 }
133779 assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
133780 assert( rc!=SQLITE_OK || bMaxSet );
133781
133782 /* Keep advancing iterators until they all point to the same document */
133783 for(i=0; i<p->nToken; i++){
133784 while( rc==SQLITE_OK && bEof==0
@@ -135891,11 +136126,11 @@
135891 int i = 0;
135892
135893 /* Set variable i to the maximum number of bytes of input to tokenize. */
135894 for(i=0; i<n; i++){
135895 if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
135896 if( z[i]=='*' || z[i]=='"' ) break;
135897 }
135898
135899 *pnConsumed = i;
135900 rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
135901 if( rc==SQLITE_OK ){
135902
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -231,11 +231,11 @@
231 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
232 ** [sqlite_version()] and [sqlite_source_id()].
233 */
234 #define SQLITE_VERSION "3.8.7"
235 #define SQLITE_VERSION_NUMBER 3008007
236 #define SQLITE_SOURCE_ID "2014-10-17 11:24:17 e4ab094f8afce0817f4074e823fabe59fc29ebb4"
237
238 /*
239 ** CAPI3REF: Run-Time Library Version Numbers
240 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
241 **
@@ -2791,13 +2791,13 @@
2791 ** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
2792 ** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
2793 ** an English language description of the error following a failure of any
2794 ** of the sqlite3_open() routines.
2795 **
2796 ** ^The default encoding will be UTF-8 for databases created using
2797 ** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases
2798 ** created using sqlite3_open16() will be UTF-16 in the native byte order.
2799 **
2800 ** Whether or not an error occurs when it is opened, resources
2801 ** associated with the [database connection] handle should be released by
2802 ** passing it to [sqlite3_close()] when it is no longer required.
2803 **
@@ -2881,17 +2881,18 @@
2881 ** ^SQLite uses the path component of the URI as the name of the disk file
2882 ** which contains the database. ^If the path begins with a '/' character,
2883 ** then it is interpreted as an absolute path. ^If the path does not begin
2884 ** with a '/' (meaning that the authority section is omitted from the URI)
2885 ** then the path is interpreted as a relative path.
2886 ** ^(On windows, the first component of an absolute path
2887 ** is a drive specification (e.g. "C:").)^
2888 **
2889 ** [[core URI query parameters]]
2890 ** The query component of a URI may contain parameters that are interpreted
2891 ** either by SQLite itself, or by a [VFS | custom VFS implementation].
2892 ** SQLite and its built-in [VFSes] interpret the
2893 ** following query parameters:
2894 **
2895 ** <ul>
2896 ** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
2897 ** a VFS object that provides the operating system interface that should
2898 ** be used to access the database file on disk. ^If this option is set to
@@ -2922,15 +2923,13 @@
2923 ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
2924 ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
2925 ** a URI filename, its value overrides any behavior requested by setting
2926 ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
2927 **
2928 ** <li> <b>psow</b>: ^The psow parameter indicates whether or not the
 
2929 ** [powersafe overwrite] property does or does not apply to the
2930 ** storage media on which the database file resides.
 
2931 **
2932 ** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
2933 ** which if set disables file locking in rollback journal modes. This
2934 ** is useful for accessing a database on a filesystem that does not
2935 ** support locking. Caution: Database corruption might result if two
@@ -3521,15 +3520,14 @@
3520 ** terminated. If any NUL characters occur at byte offsets less than
3521 ** the value of the fourth parameter then the resulting string value will
3522 ** contain embedded NULs. The result of expressions involving strings
3523 ** with embedded NULs is undefined.
3524 **
3525 ** ^The fifth argument to the BLOB and string binding interfaces
3526 ** is a destructor used to dispose of the BLOB or
3527 ** string after SQLite has finished with it. ^The destructor is called
3528 ** to dispose of the BLOB or string even if the call to bind API fails.
 
3529 ** ^If the fifth argument is
3530 ** the special value [SQLITE_STATIC], then SQLite assumes that the
3531 ** information is in static, unmanaged space and does not need to be freed.
3532 ** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
3533 ** SQLite makes its own private copy of the data immediately, before
@@ -3536,11 +3534,11 @@
3534 ** the sqlite3_bind_*() routine returns.
3535 **
3536 ** ^The sixth argument to sqlite3_bind_text64() must be one of
3537 ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
3538 ** to specify the encoding of the text in the third parameter. If
3539 ** the sixth argument to sqlite3_bind_text64() is not one of the
3540 ** allowed values shown above, or if the text encoding is different
3541 ** from the encoding specified by the sixth parameter, then the behavior
3542 ** is undefined.
3543 **
3544 ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
@@ -4572,11 +4570,11 @@
4570 **
4571 ** ^The sqlite3_result_null() interface sets the return value
4572 ** of the application-defined function to be NULL.
4573 **
4574 ** ^The sqlite3_result_text(), sqlite3_result_text16(),
4575 ** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
4576 ** set the return value of the application-defined function to be
4577 ** a text string which is represented as UTF-8, UTF-16 native byte order,
4578 ** UTF-16 little endian, or UTF-16 big endian, respectively.
4579 ** ^The sqlite3_result_text64() interface sets the return value of an
4580 ** application-defined function to be a text string in an encoding
@@ -6332,11 +6330,11 @@
6330 #define SQLITE_TESTCTRL_RESERVE 14
6331 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
6332 #define SQLITE_TESTCTRL_ISKEYWORD 16
6333 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17
6334 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
6335 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
6336 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
6337 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
6338 #define SQLITE_TESTCTRL_BYTEORDER 22
6339 #define SQLITE_TESTCTRL_ISINIT 23
6340 #define SQLITE_TESTCTRL_SORTER_MMAP 24
@@ -7946,11 +7944,11 @@
7944 ** A macro to hint to the compiler that a function should not be
7945 ** inlined.
7946 */
7947 #if defined(__GNUC__)
7948 # define SQLITE_NOINLINE __attribute__((noinline))
7949 #elif defined(_MSC_VER) && _MSC_VER>=1310
7950 # define SQLITE_NOINLINE __declspec(noinline)
7951 #else
7952 # define SQLITE_NOINLINE
7953 #endif
7954
@@ -8519,10 +8517,15 @@
8517 ** Macros to compute minimum and maximum of two numbers.
8518 */
8519 #define MIN(A,B) ((A)<(B)?(A):(B))
8520 #define MAX(A,B) ((A)>(B)?(A):(B))
8521
8522 /*
8523 ** Swap two objects of type TYPE.
8524 */
8525 #define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
8526
8527 /*
8528 ** Check to see if this machine uses EBCDIC. (Yes, believe it or
8529 ** not, there are still machines out there that use EBCDIC.)
8530 */
8531 #if 'A' == '\301'
@@ -8756,10 +8759,20 @@
8759 # define SQLITE_ENABLE_STAT3_OR_STAT4 1
8760 #elif SQLITE_ENABLE_STAT3_OR_STAT4
8761 # undef SQLITE_ENABLE_STAT3_OR_STAT4
8762 #endif
8763
8764 /*
8765 ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
8766 ** the Select query generator tracing logic is turned on.
8767 */
8768 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE)
8769 # define SELECTTRACE_ENABLED 1
8770 #else
8771 # define SELECTTRACE_ENABLED 0
8772 #endif
8773
8774 /*
8775 ** An instance of the following structure is used to store the busy-handler
8776 ** callback for a given sqlite handle.
8777 **
8778 ** The sqlite.busyHandler member of the sqlite struct contains the busy
@@ -8895,10 +8908,11 @@
8908 typedef struct SrcList SrcList;
8909 typedef struct StrAccum StrAccum;
8910 typedef struct Table Table;
8911 typedef struct TableLock TableLock;
8912 typedef struct Token Token;
8913 typedef struct TreeView TreeView;
8914 typedef struct Trigger Trigger;
8915 typedef struct TriggerPrg TriggerPrg;
8916 typedef struct TriggerStep TriggerStep;
8917 typedef struct UnpackedRecord UnpackedRecord;
8918 typedef struct VTable VTable;
@@ -11308,10 +11322,11 @@
11322 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
11323 int nSample; /* Number of elements in aSample[] */
11324 int nSampleCol; /* Size of IndexSample.anEq[] and so on */
11325 tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
11326 IndexSample *aSample; /* Samples of the left-most key */
11327 tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this table */
11328 #endif
11329 };
11330
11331 /*
11332 ** Allowed values for Index.idxType
@@ -11738,11 +11753,11 @@
11753 #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
11754 #define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
11755 #define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
11756 #define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
11757 #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
11758 /* 0x0080 // not currently used */
11759 #define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
11760 #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
11761 #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
11762 #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
11763 #define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
@@ -11823,10 +11838,13 @@
11838 struct Select {
11839 ExprList *pEList; /* The fields of the result */
11840 u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
11841 u16 selFlags; /* Various SF_* values */
11842 int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
11843 #if SELECTTRACE_ENABLED
11844 char zSelName[12]; /* Symbolic name of this SELECT use for debugging */
11845 #endif
11846 int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
11847 u64 nSelectRow; /* Estimated number of result rows */
11848 SrcList *pSrc; /* The FROM clause */
11849 Expr *pWhere; /* The WHERE clause */
11850 ExprList *pGroupBy; /* The GROUP BY clause */
@@ -12081,10 +12099,14 @@
12099 yDbMask cookieMask; /* Bitmask of schema verified databases */
12100 int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
12101 int regRowid; /* Register holding rowid of CREATE TABLE entry */
12102 int regRoot; /* Register holding root page number for new objects */
12103 int nMaxArg; /* Max args passed to user function by sub-program */
12104 #if SELECTTRACE_ENABLED
12105 int nSelect; /* Number of SELECT statements seen */
12106 int nSelectIndent; /* How far to indent SELECTTRACE() output */
12107 #endif
12108 #ifndef SQLITE_OMIT_SHARED_CACHE
12109 int nTableLock; /* Number of locks in aTableLock */
12110 TableLock *aTableLock; /* Required table locks for shared-cache mode */
12111 #endif
12112 AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
@@ -12160,15 +12182,15 @@
12182
12183 /*
12184 ** Bitfield flags for P5 value in various opcodes.
12185 */
12186 #define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */
12187 #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
12188 #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
12189 #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
12190 #define OPFLAG_APPEND 0x08 /* This is likely to be an append */
12191 #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
 
12192 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
12193 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
12194 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
12195 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
12196 #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
@@ -12428,10 +12450,21 @@
12450 Select *pSelect; /* The definition of this CTE */
12451 const char *zErr; /* Error message for circular references */
12452 } a[1];
12453 };
12454
12455 #ifdef SQLITE_DEBUG
12456 /*
12457 ** An instance of the TreeView object is used for printing the content of
12458 ** data structures on sqlite3DebugPrintf() using a tree-like view.
12459 */
12460 struct TreeView {
12461 int iLevel; /* Which level of the tree we are on */
12462 u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */
12463 };
12464 #endif /* SQLITE_DEBUG */
12465
12466 /*
12467 ** Assuming zIn points to the first byte of a UTF-8 character,
12468 ** advance zIn to point to the first byte of the next UTF-8 character.
12469 */
12470 #define SQLITE_SKIP_UTF8(zIn) { \
@@ -12493,10 +12526,11 @@
12526 # define sqlite3Isalpha(x) isalpha((unsigned char)(x))
12527 # define sqlite3Isdigit(x) isdigit((unsigned char)(x))
12528 # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
12529 # define sqlite3Tolower(x) tolower((unsigned char)(x))
12530 #endif
12531 SQLITE_PRIVATE int sqlite3IsIdChar(u8);
12532
12533 /*
12534 ** Internal function prototypes
12535 */
12536 #define sqlite3StrICmp sqlite3_stricmp
@@ -12591,29 +12625,18 @@
12625 #endif
12626 #if defined(SQLITE_TEST)
12627 SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
12628 #endif
12629
12630 #if defined(SQLITE_DEBUG)
12631 SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView*,u8);
12632 SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView*);
12633 SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView*, const char*, ...);
12634 SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView*, const char*, u8);
12635 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
12636 SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
12637 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
 
 
 
 
 
 
 
 
 
 
 
12638 #endif
12639
12640
12641 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
12642 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
@@ -12791,11 +12814,11 @@
12814 SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
12815 SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
12816 SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
12817 SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
12818 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
12819 SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
12820 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
12821 SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
12822 SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
12823 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
12824 SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
@@ -12815,10 +12838,15 @@
12838 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
12839 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
12840 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
12841 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
12842 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
12843 #if SELECTTRACE_ENABLED
12844 SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
12845 #else
12846 # define sqlite3SelectSetName(A,B)
12847 #endif
12848 SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
12849 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
12850 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
12851 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
12852 SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
@@ -13292,14 +13320,13 @@
13320 # define sqlite3MemdebugSetType(X,Y) /* no-op */
13321 # define sqlite3MemdebugHasType(X,Y) 1
13322 # define sqlite3MemdebugNoType(X,Y) 1
13323 #endif
13324 #define MEMTYPE_HEAP 0x01 /* General heap allocations */
13325 #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
13326 #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
13327 #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
 
13328
13329 /*
13330 ** Threading interface
13331 */
13332 #if SQLITE_MAX_WORKER_THREADS>0
@@ -13439,10 +13466,17 @@
13466 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
13467 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
13468 };
13469 #endif
13470
13471 /* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
13472 ** compatibility for legacy applications, the URI filename capability is
13473 ** disabled by default.
13474 **
13475 ** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
13476 ** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
13477 */
13478 #ifndef SQLITE_USE_URI
13479 # define SQLITE_USE_URI 0
13480 #endif
13481
13482 #ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
@@ -13945,11 +13979,11 @@
13979
13980 /* Since ArraySize(azCompileOpt) is normally in single digits, a
13981 ** linear search is adequate. No need for a binary search. */
13982 for(i=0; i<ArraySize(azCompileOpt); i++){
13983 if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
13984 && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
13985 ){
13986 return 1;
13987 }
13988 }
13989 return 0;
@@ -14060,21 +14094,19 @@
14094 #ifdef SQLITE_DEBUG
14095 u8 seekOp; /* Most recent seek operation on this cursor */
14096 #endif
14097 i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
14098 u8 nullRow; /* True if pointing to a row with no data */
 
14099 u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
14100 Bool isEphemeral:1; /* True for an ephemeral table */
14101 Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
14102 Bool isTable:1; /* True if a table requiring integer keys */
14103 Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
14104 Pgno pgnoRoot; /* Root page of the open btree cursor */
14105 sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
14106 i64 seqCount; /* Sequence counter */
14107 i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
 
14108 VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
14109
14110 /* Cached information about the header for the data record that the
14111 ** cursor is currently pointing to. Only valid if cacheStatus matches
14112 ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -14087,10 +14119,11 @@
14119 u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
14120 u32 payloadSize; /* Total number of bytes in the record */
14121 u32 szRow; /* Byte available in aRow */
14122 u32 iHdrOffset; /* Offset to next unparsed byte of the header */
14123 const u8 *aRow; /* Data for the current row, if all on one page */
14124 u32 *aOffset; /* Pointer to aType[nField] */
14125 u32 aType[1]; /* Type values for all entries in the record */
14126 /* 2*nField extra array elements allocated for aType[], beyond the one
14127 ** static element declared in the structure. nField total array slots for
14128 ** aType[] and nField+1 array slots for aOffset[] */
14129 };
@@ -14163,11 +14196,11 @@
14196 int n; /* Number of characters in string value, excluding '\0' */
14197 char *z; /* String or BLOB value */
14198 /* ShallowCopy only needs to copy the information above */
14199 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
14200 int szMalloc; /* Size of the zMalloc allocation */
14201 u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
14202 sqlite3 *db; /* The associated database connection */
14203 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
14204 #ifdef SQLITE_DEBUG
14205 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
14206 void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
@@ -14259,11 +14292,10 @@
14292 */
14293 struct sqlite3_context {
14294 Mem *pOut; /* The return value is stored here */
14295 FuncDef *pFunc; /* Pointer to function information */
14296 Mem *pMem; /* Memory cell used to store aggregate context */
 
14297 Vdbe *pVdbe; /* The VM that owns this context */
14298 int iOp; /* Instruction number of OP_Function */
14299 int isError; /* Error code returned by the function. */
14300 u8 skipFlag; /* Skip accumulator loading if true */
14301 u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
@@ -14348,14 +14380,10 @@
14380 i64 nFkConstraint; /* Number of imm. FK constraints this VM */
14381 i64 nStmtDefCons; /* Number of def. constraints when stmt started */
14382 i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
14383 char *zSql; /* Text of the SQL statement that generated this */
14384 void *pFree; /* Free this when deleting the vdbe */
 
 
 
 
14385 VdbeFrame *pFrame; /* Parent frame */
14386 VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
14387 int nFrame; /* Number of frames in pFrame list */
14388 u32 expmask; /* Binding to these vars invalidates VM */
14389 SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
@@ -14376,10 +14404,11 @@
14404 ** Function prototypes
14405 */
14406 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
14407 void sqliteVdbePopStack(Vdbe*,int);
14408 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
14409 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
14410 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
14411 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
14412 #endif
14413 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
14414 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
@@ -14675,11 +14704,11 @@
14704 sqlite3VdbeClearObject(db, pVdbe);
14705 sqlite3DbFree(db, pVdbe);
14706 }
14707 db->pnBytesFreed = 0;
14708
14709 *pHighwater = 0; /* IMP: R-64479-57858 */
14710 *pCurrent = nByte;
14711
14712 break;
14713 }
14714
@@ -14700,21 +14729,23 @@
14729 if( db->aDb[i].pBt ){
14730 Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
14731 sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
14732 }
14733 }
14734 *pHighwater = 0; /* IMP: R-42420-56072 */
14735 /* IMP: R-54100-20147 */
14736 /* IMP: R-29431-39229 */
14737 *pCurrent = nRet;
14738 break;
14739 }
14740
14741 /* Set *pCurrent to non-zero if there are unresolved deferred foreign
14742 ** key constraints. Set *pCurrent to zero if all foreign key constraints
14743 ** have been satisfied. The *pHighwater is always set to zero.
14744 */
14745 case SQLITE_DBSTATUS_DEFERRED_FKS: {
14746 *pHighwater = 0; /* IMP: R-11967-56545 */
14747 *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
14748 break;
14749 }
14750
14751 default: {
@@ -17098,11 +17129,11 @@
17129 ** allocation p. Also return true if p==NULL.
17130 **
17131 ** This routine is designed for use within an assert() statement, to
17132 ** verify the type of an allocation. For example:
17133 **
17134 ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
17135 */
17136 SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
17137 int rc = 1;
17138 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17139 struct MemBlockHdr *pHdr;
@@ -17120,11 +17151,11 @@
17151 ** allocation p. Also return true if p==NULL.
17152 **
17153 ** This routine is designed for use within an assert() statement, to
17154 ** verify the type of an allocation. For example:
17155 **
17156 ** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
17157 */
17158 SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
17159 int rc = 1;
17160 if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
17161 struct MemBlockHdr *pHdr;
@@ -20195,11 +20226,11 @@
20226 mallocWithAlarm((int)n, &p);
20227 sqlite3_mutex_leave(mem0.mutex);
20228 }else{
20229 p = sqlite3GlobalConfig.m.xMalloc((int)n);
20230 }
20231 assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */
20232 return p;
20233 }
20234
20235 /*
20236 ** This version of the memory allocation is for use by the application.
@@ -20332,39 +20363,41 @@
20363 ** Return the size of a memory allocation previously obtained from
20364 ** sqlite3Malloc() or sqlite3_malloc().
20365 */
20366 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
20367 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
 
20368 return sqlite3GlobalConfig.m.xSize(p);
20369 }
20370 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
20371 if( db==0 ){
20372 assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20373 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20374 return sqlite3MallocSize(p);
20375 }else{
20376 assert( sqlite3_mutex_held(db->mutex) );
20377 if( isLookaside(db, p) ){
20378 return db->lookaside.sz;
20379 }else{
20380 assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20381 assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
 
20382 return sqlite3GlobalConfig.m.xSize(p);
20383 }
20384 }
20385 }
20386 SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
20387 assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20388 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20389 return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
20390 }
20391
20392 /*
20393 ** Free memory previously obtained from sqlite3Malloc().
20394 */
20395 SQLITE_API void sqlite3_free(void *p){
20396 if( p==0 ) return; /* IMP: R-49053-54554 */
 
20397 assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
20398 assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
20399 if( sqlite3GlobalConfig.bMemstat ){
20400 sqlite3_mutex_enter(mem0.mutex);
20401 sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
20402 sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
20403 sqlite3GlobalConfig.m.xFree(p);
@@ -20404,12 +20437,12 @@
20437 db->lookaside.pFree = pBuf;
20438 db->lookaside.nOut--;
20439 return;
20440 }
20441 }
20442 assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20443 assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20444 assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
20445 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20446 sqlite3_free(p);
20447 }
20448
@@ -20417,15 +20450,17 @@
20450 ** Change the size of an existing memory allocation
20451 */
20452 SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
20453 int nOld, nNew, nDiff;
20454 void *pNew;
20455 assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
20456 assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
20457 if( pOld==0 ){
20458 return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
20459 }
20460 if( nBytes==0 ){
20461 sqlite3_free(pOld); /* IMP: R-26507-47431 */
20462 return 0;
20463 }
20464 if( nBytes>=0x7fffff00 ){
20465 /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
20466 return 0;
@@ -20443,12 +20478,10 @@
20478 nDiff = nNew - nOld;
20479 if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
20480 mem0.alarmThreshold-nDiff ){
20481 sqlite3MallocAlarm(nDiff);
20482 }
 
 
20483 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20484 if( pNew==0 && mem0.alarmCallback ){
20485 sqlite3MallocAlarm((int)nBytes);
20486 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20487 }
@@ -20458,11 +20491,11 @@
20491 }
20492 sqlite3_mutex_leave(mem0.mutex);
20493 }else{
20494 pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
20495 }
20496 assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */
20497 return pNew;
20498 }
20499
20500 /*
20501 ** The public interface to sqlite3Realloc. Make sure that the memory
@@ -20470,11 +20503,11 @@
20503 */
20504 SQLITE_API void *sqlite3_realloc(void *pOld, int n){
20505 #ifndef SQLITE_OMIT_AUTOINIT
20506 if( sqlite3_initialize() ) return 0;
20507 #endif
20508 if( n<0 ) n = 0; /* IMP: R-26507-47431 */
20509 return sqlite3Realloc(pOld, n);
20510 }
20511 SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
20512 #ifndef SQLITE_OMIT_AUTOINIT
20513 if( sqlite3_initialize() ) return 0;
@@ -20557,12 +20590,12 @@
20590 #endif
20591 p = sqlite3Malloc(n);
20592 if( !p && db ){
20593 db->mallocFailed = 1;
20594 }
20595 sqlite3MemdebugSetType(p,
20596 (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
20597 return p;
20598 }
20599
20600 /*
20601 ** Resize the block of memory pointed to by p to n bytes. If the
@@ -20584,19 +20617,18 @@
20617 if( pNew ){
20618 memcpy(pNew, p, db->lookaside.sz);
20619 sqlite3DbFree(db, p);
20620 }
20621 }else{
20622 assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20623 assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
20624 sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
20625 pNew = sqlite3_realloc64(p, n);
20626 if( !pNew ){
 
20627 db->mallocFailed = 1;
20628 }
20629 sqlite3MemdebugSetType(pNew,
20630 (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
20631 }
20632 }
20633 return pNew;
20634 }
@@ -21757,10 +21789,73 @@
21789 fprintf(stdout,"%s", zBuf);
21790 fflush(stdout);
21791 }
21792 #endif
21793
21794 #ifdef SQLITE_DEBUG
21795 /*************************************************************************
21796 ** Routines for implementing the "TreeView" display of hierarchical
21797 ** data structures for debugging.
21798 **
21799 ** The main entry points (coded elsewhere) are:
21800 ** sqlite3TreeViewExpr(0, pExpr, 0);
21801 ** sqlite3TreeViewExprList(0, pList, 0, 0);
21802 ** sqlite3TreeViewSelect(0, pSelect, 0);
21803 ** Insert calls to those routines while debugging in order to display
21804 ** a diagram of Expr, ExprList, and Select objects.
21805 **
21806 */
21807 /* Add a new subitem to the tree. The moreToFollow flag indicates that this
21808 ** is not the last item in the tree. */
21809 SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
21810 if( p==0 ){
21811 p = sqlite3_malloc( sizeof(*p) );
21812 if( p==0 ) return 0;
21813 memset(p, 0, sizeof(*p));
21814 }else{
21815 p->iLevel++;
21816 }
21817 assert( moreToFollow==0 || moreToFollow==1 );
21818 if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
21819 return p;
21820 }
21821 /* Finished with one layer of the tree */
21822 SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView *p){
21823 if( p==0 ) return;
21824 p->iLevel--;
21825 if( p->iLevel<0 ) sqlite3_free(p);
21826 }
21827 /* Generate a single line of output for the tree, with a prefix that contains
21828 ** all the appropriate tree lines */
21829 SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
21830 va_list ap;
21831 int i;
21832 StrAccum acc;
21833 char zBuf[500];
21834 sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
21835 acc.useMalloc = 0;
21836 if( p ){
21837 for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
21838 sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
21839 }
21840 sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
21841 }
21842 va_start(ap, zFormat);
21843 sqlite3VXPrintf(&acc, 0, zFormat, ap);
21844 va_end(ap);
21845 if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
21846 sqlite3StrAccumFinish(&acc);
21847 fprintf(stdout,"%s", zBuf);
21848 fflush(stdout);
21849 }
21850 /* Shorthand for starting a new tree item that consists of a single label */
21851 SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
21852 p = sqlite3TreeViewPush(p, moreToFollow);
21853 sqlite3TreeViewLine(p, "%s", zLabel);
21854 }
21855 #endif /* SQLITE_DEBUG */
21856
21857 /*
21858 ** variable-argument wrapper around sqlite3VXPrintf().
21859 */
21860 SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
21861 va_list ap;
@@ -21996,18 +22091,18 @@
22091 #endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
22092 /******************************** End Unix Pthreads *************************/
22093
22094
22095 /********************************* Win32 Threads ****************************/
22096 #if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
22097
22098 #define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
22099 #include <process.h>
22100
22101 /* A running thread */
22102 struct SQLiteThread {
22103 void *tid; /* The thread handle */
22104 unsigned id; /* The thread identifier */
22105 void *(*xTask)(void*); /* The routine to run as a thread */
22106 void *pIn; /* Argument to xTask */
22107 void *pResult; /* Result of xTask */
22108 };
@@ -22051,11 +22146,11 @@
22146 if( sqlite3GlobalConfig.bCoreMutex==0 ){
22147 memset(p, 0, sizeof(*p));
22148 }else{
22149 p->xTask = xTask;
22150 p->pIn = pIn;
22151 p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
22152 if( p->tid==0 ){
22153 memset(p, 0, sizeof(*p));
22154 }
22155 }
22156 if( p->xTask==0 ){
@@ -22089,11 +22184,11 @@
22184 if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
22185 sqlite3_free(p);
22186 return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
22187 }
22188
22189 #endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */
22190 /******************************** End Win32 Threads *************************/
22191
22192
22193 /********************************* Single-Threaded **************************/
22194 #ifndef SQLITE_THREADS_IMPLEMENTED
@@ -29659,11 +29754,11 @@
29754 ** methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
29755 **
29756 ** * An I/O method finder function called FINDER that returns a pointer
29757 ** to the METHOD object in the previous bullet.
29758 */
29759 #define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK, SHMMAP) \
29760 static const sqlite3_io_methods METHOD = { \
29761 VERSION, /* iVersion */ \
29762 CLOSE, /* xClose */ \
29763 unixRead, /* xRead */ \
29764 unixWrite, /* xWrite */ \
@@ -29674,11 +29769,11 @@
29769 UNLOCK, /* xUnlock */ \
29770 CKLOCK, /* xCheckReservedLock */ \
29771 unixFileControl, /* xFileControl */ \
29772 unixSectorSize, /* xSectorSize */ \
29773 unixDeviceCharacteristics, /* xDeviceCapabilities */ \
29774 SHMMAP, /* xShmMap */ \
29775 unixShmLock, /* xShmLock */ \
29776 unixShmBarrier, /* xShmBarrier */ \
29777 unixShmUnmap, /* xShmUnmap */ \
29778 unixFetch, /* xFetch */ \
29779 unixUnfetch, /* xUnfetch */ \
@@ -29700,29 +29795,32 @@
29795 posixIoMethods, /* sqlite3_io_methods object name */
29796 3, /* shared memory and mmap are enabled */
29797 unixClose, /* xClose method */
29798 unixLock, /* xLock method */
29799 unixUnlock, /* xUnlock method */
29800 unixCheckReservedLock, /* xCheckReservedLock method */
29801 unixShmMap /* xShmMap method */
29802 )
29803 IOMETHODS(
29804 nolockIoFinder, /* Finder function name */
29805 nolockIoMethods, /* sqlite3_io_methods object name */
29806 3, /* shared memory is disabled */
29807 nolockClose, /* xClose method */
29808 nolockLock, /* xLock method */
29809 nolockUnlock, /* xUnlock method */
29810 nolockCheckReservedLock, /* xCheckReservedLock method */
29811 0 /* xShmMap method */
29812 )
29813 IOMETHODS(
29814 dotlockIoFinder, /* Finder function name */
29815 dotlockIoMethods, /* sqlite3_io_methods object name */
29816 1, /* shared memory is disabled */
29817 dotlockClose, /* xClose method */
29818 dotlockLock, /* xLock method */
29819 dotlockUnlock, /* xUnlock method */
29820 dotlockCheckReservedLock, /* xCheckReservedLock method */
29821 0 /* xShmMap method */
29822 )
29823
29824 #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
29825 IOMETHODS(
29826 flockIoFinder, /* Finder function name */
@@ -29729,11 +29827,12 @@
29827 flockIoMethods, /* sqlite3_io_methods object name */
29828 1, /* shared memory is disabled */
29829 flockClose, /* xClose method */
29830 flockLock, /* xLock method */
29831 flockUnlock, /* xUnlock method */
29832 flockCheckReservedLock, /* xCheckReservedLock method */
29833 0 /* xShmMap method */
29834 )
29835 #endif
29836
29837 #if OS_VXWORKS
29838 IOMETHODS(
@@ -29741,11 +29840,12 @@
29840 semIoMethods, /* sqlite3_io_methods object name */
29841 1, /* shared memory is disabled */
29842 semClose, /* xClose method */
29843 semLock, /* xLock method */
29844 semUnlock, /* xUnlock method */
29845 semCheckReservedLock, /* xCheckReservedLock method */
29846 0 /* xShmMap method */
29847 )
29848 #endif
29849
29850 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
29851 IOMETHODS(
@@ -29753,11 +29853,12 @@
29853 afpIoMethods, /* sqlite3_io_methods object name */
29854 1, /* shared memory is disabled */
29855 afpClose, /* xClose method */
29856 afpLock, /* xLock method */
29857 afpUnlock, /* xUnlock method */
29858 afpCheckReservedLock, /* xCheckReservedLock method */
29859 0 /* xShmMap method */
29860 )
29861 #endif
29862
29863 /*
29864 ** The proxy locking method is a "super-method" in the sense that it
@@ -29778,11 +29879,12 @@
29879 proxyIoMethods, /* sqlite3_io_methods object name */
29880 1, /* shared memory is disabled */
29881 proxyClose, /* xClose method */
29882 proxyLock, /* xLock method */
29883 proxyUnlock, /* xUnlock method */
29884 proxyCheckReservedLock, /* xCheckReservedLock method */
29885 0 /* xShmMap method */
29886 )
29887 #endif
29888
29889 /* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
29890 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
@@ -29791,11 +29893,12 @@
29893 nfsIoMethods, /* sqlite3_io_methods object name */
29894 1, /* shared memory is disabled */
29895 unixClose, /* xClose method */
29896 unixLock, /* xLock method */
29897 nfsUnlock, /* xUnlock method */
29898 unixCheckReservedLock, /* xCheckReservedLock method */
29899 0 /* xShmMap method */
29900 )
29901 #endif
29902
29903 #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
29904 /*
@@ -33384,11 +33487,15 @@
33487 #endif
33488
33489 #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
33490 DWORD))aSyscall[63].pCurrent)
33491
33492 #if !SQLITE_OS_WINCE
33493 { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
33494 #else
33495 { "WaitForSingleObjectEx", (SYSCALL)0, 0 },
33496 #endif
33497
33498 #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
33499 BOOL))aSyscall[64].pCurrent)
33500
33501 #if SQLITE_OS_WINRT
@@ -33727,11 +33834,12 @@
33834 #else
33835 osSleep(milliseconds);
33836 #endif
33837 }
33838
33839 #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
33840 SQLITE_THREADSAFE>0
33841 SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
33842 DWORD rc;
33843 while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
33844 TRUE))==WAIT_IO_COMPLETION ){}
33845 return rc;
@@ -39752,11 +39860,11 @@
39860 assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
39861 assert( pCache->n90pct == pCache->nMax*9/10 );
39862 if( createFlag==1 && (
39863 nPinned>=pGroup->mxPinned
39864 || nPinned>=pCache->n90pct
39865 || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
39866 )){
39867 return 0;
39868 }
39869
39870 if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
@@ -44373,17 +44481,19 @@
44481 if( !pNew ) rc = SQLITE_NOMEM;
44482 }
44483
44484 if( rc==SQLITE_OK ){
44485 pager_reset(pPager);
 
 
44486 rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
44487 }
44488 if( rc==SQLITE_OK ){
44489 sqlite3PageFree(pPager->pTmpSpace);
44490 pPager->pTmpSpace = pNew;
44491 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
44492 pPager->pageSize = pageSize;
44493 }else{
44494 sqlite3PageFree(pNew);
44495 }
44496 }
44497
44498 *pPageSize = pPager->pageSize;
44499 if( rc==SQLITE_OK ){
@@ -51383,13 +51493,14 @@
51493 ** stored in MemPage.pBt->mutex.
51494 */
51495 struct MemPage {
51496 u8 isInit; /* True if previously initialized. MUST BE FIRST! */
51497 u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
51498 u8 intKey; /* True if table b-trees. False for index b-trees */
51499 u8 intKeyLeaf; /* True if the leaf of an intKey table */
51500 u8 noPayload; /* True if internal intKey page (thus w/o data) */
51501 u8 leaf; /* True if a leaf page */
51502 u8 hdrOffset; /* 100 for page 1. 0 otherwise */
51503 u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
51504 u8 max1bytePayload; /* min(maxLocal,127) */
51505 u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
51506 u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
@@ -51545,11 +51656,11 @@
51656 int nRef; /* Number of references to this structure */
51657 BtShared *pNext; /* Next on a list of sharable BtShared structs */
51658 BtLock *pLock; /* List of locks held on this shared-btree struct */
51659 Btree *pWriter; /* Btree with currently open write transaction */
51660 #endif
51661 u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
51662 };
51663
51664 /*
51665 ** Allowed values for BtShared.btsFlags
51666 */
@@ -51566,16 +51677,14 @@
51677 ** about a cell. The parseCellPtr() function fills in this structure
51678 ** based on information extract from the raw disk page.
51679 */
51680 typedef struct CellInfo CellInfo;
51681 struct CellInfo {
51682 i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
51683 u8 *pPayload; /* Pointer to the start of payload */
51684 u32 nPayload; /* Bytes of payload */
51685 u16 nLocal; /* Amount of payload held locally, not on overflow */
 
 
51686 u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
51687 u16 nSize; /* Size of the cell content on the main b-tree page */
51688 };
51689
51690 /*
@@ -51768,10 +51877,12 @@
51877 u8 *aPgRef; /* 1 bit per page in the db (see above) */
51878 Pgno nPage; /* Number of pages in the database */
51879 int mxErr; /* Stop accumulating errors when this reaches zero */
51880 int nErr; /* Number of messages written to zErrMsg so far */
51881 int mallocFailed; /* A memory allocation error has occurred */
51882 const char *zPfx; /* Error message prefix */
51883 int v1, v2; /* Values for up to two %d fields in zPfx */
51884 StrAccum errMsg; /* Accumulate the error message text here */
51885 };
51886
51887 /*
51888 ** Routines to read or write a two- and four-byte big-endian integer values.
@@ -52554,11 +52665,13 @@
52665 ){
52666 BtCursor *p;
52667 BtShared *pBt = pBtree->pBt;
52668 assert( sqlite3BtreeHoldsMutex(pBtree) );
52669 for(p=pBt->pCursor; p; p=p->pNext){
52670 if( (p->curFlags & BTCF_Incrblob)!=0
52671 && (isClearTable || p->info.nKey==iRow)
52672 ){
52673 p->eState = CURSOR_INVALID;
52674 }
52675 }
52676 }
52677
@@ -52727,13 +52840,13 @@
52840 ** the cursors if and when a cursor is found that actually requires saving.
52841 ** The common case is that no cursors need to be saved, so this routine is
52842 ** broken out from its caller to avoid unnecessary stack pointer movement.
52843 */
52844 static int SQLITE_NOINLINE saveCursorsOnList(
52845 BtCursor *p, /* The first cursor that needs saving */
52846 Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
52847 BtCursor *pExcept /* Do not save this cursor */
52848 ){
52849 do{
52850 if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
52851 if( p->eState==CURSOR_VALID ){
52852 int rc = saveCursorPosition(p);
@@ -52841,11 +52954,11 @@
52954 **
52955 ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
52956 ** back to where it ought to be if this routine returns true.
52957 */
52958 SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
52959 return pCur->eState!=CURSOR_VALID;
52960 }
52961
52962 /*
52963 ** This routine restores a cursor back to its original position after it
52964 ** has been moved by some outside activity (such as a btree rebalance or
@@ -53035,51 +53148,48 @@
53148 /*
53149 ** Parse a cell content block and fill in the CellInfo structure. There
53150 ** are two versions of this function. btreeParseCell() takes a
53151 ** cell index as the second argument and btreeParseCellPtr()
53152 ** takes a pointer to the body of the cell as its second argument.
 
 
 
53153 */
53154 static void btreeParseCellPtr(
53155 MemPage *pPage, /* Page containing the cell */
53156 u8 *pCell, /* Pointer to the cell text. */
53157 CellInfo *pInfo /* Fill in this structure */
53158 ){
53159 u8 *pIter; /* For scanning through pCell */
53160 u32 nPayload; /* Number of bytes of cell payload */
53161
53162 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 
 
53163 assert( pPage->leaf==0 || pPage->leaf==1 );
53164 if( pPage->intKeyLeaf ){
53165 assert( pPage->childPtrSize==0 );
53166 pIter = pCell + getVarint32(pCell, nPayload);
53167 pIter += getVarint(pIter, (u64*)&pInfo->nKey);
53168 }else if( pPage->noPayload ){
53169 assert( pPage->childPtrSize==4 );
53170 pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
53171 pInfo->nPayload = 0;
53172 pInfo->nLocal = 0;
53173 pInfo->iOverflow = 0;
53174 pInfo->pPayload = 0;
53175 return;
53176 }else{
53177 pIter = pCell + pPage->childPtrSize;
53178 pIter += getVarint32(pIter, nPayload);
53179 pInfo->nKey = nPayload;
53180 }
53181 pInfo->nPayload = nPayload;
53182 pInfo->pPayload = pIter;
53183 testcase( nPayload==pPage->maxLocal );
53184 testcase( nPayload==pPage->maxLocal+1 );
53185 if( nPayload<=pPage->maxLocal ){
53186 /* This is the (easy) common case where the entire payload fits
53187 ** on the local page. No overflow is required.
53188 */
53189 pInfo->nSize = nPayload + (u16)(pIter - pCell);
53190 if( pInfo->nSize<4 ) pInfo->nSize = 4;
53191 pInfo->nLocal = (u16)nPayload;
53192 pInfo->iOverflow = 0;
53193 }else{
53194 /* If the payload will not fit completely on the local page, we have
53195 ** to decide how much to store locally and how much to spill onto
@@ -53102,33 +53212,32 @@
53212 if( surplus <= maxLocal ){
53213 pInfo->nLocal = (u16)surplus;
53214 }else{
53215 pInfo->nLocal = (u16)minLocal;
53216 }
53217 pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
53218 pInfo->nSize = pInfo->iOverflow + 4;
53219 }
53220 }
 
 
53221 static void btreeParseCell(
53222 MemPage *pPage, /* Page containing the cell */
53223 int iCell, /* The cell index. First cell is 0 */
53224 CellInfo *pInfo /* Fill in this structure */
53225 ){
53226 btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo);
53227 }
53228
53229 /*
53230 ** Compute the total number of bytes that a Cell needs in the cell
53231 ** data area of the btree-page. The return number includes the cell
53232 ** data header and the local payload, but not any overflow page or
53233 ** the space used by the cell pointer.
53234 */
53235 static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
53236 u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
53237 u8 *pEnd; /* End mark for a varint */
53238 u32 nSize; /* Size value to return */
53239
53240 #ifdef SQLITE_DEBUG
53241 /* The value returned by this function should always be the same as
53242 ** the (CellInfo.nSize) value found by doing a full parse of the
53243 ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
@@ -53135,47 +53244,48 @@
53244 ** this function verifies that this invariant is not violated. */
53245 CellInfo debuginfo;
53246 btreeParseCellPtr(pPage, pCell, &debuginfo);
53247 #endif
53248
53249 if( pPage->noPayload ){
53250 pEnd = &pIter[9];
53251 while( (*pIter++)&0x80 && pIter<pEnd );
53252 assert( pPage->childPtrSize==4 );
53253 return (u16)(pIter - pCell);
53254 }
53255 nSize = *pIter;
53256 if( nSize>=0x80 ){
53257 pEnd = &pIter[9];
53258 nSize &= 0x7f;
53259 do{
53260 nSize = (nSize<<7) | (*++pIter & 0x7f);
53261 }while( *(pIter)>=0x80 && pIter<pEnd );
53262 }
53263 pIter++;
53264 if( pPage->intKey ){
 
 
 
 
 
 
 
53265 /* pIter now points at the 64-bit integer key value, a variable length
53266 ** integer. The following block moves pIter to point at the first byte
53267 ** past the end of the key value. */
53268 pEnd = &pIter[9];
53269 while( (*pIter++)&0x80 && pIter<pEnd );
 
 
53270 }
 
53271 testcase( nSize==pPage->maxLocal );
53272 testcase( nSize==pPage->maxLocal+1 );
53273 if( nSize<=pPage->maxLocal ){
53274 nSize += (u32)(pIter - pCell);
53275 if( nSize<4 ) nSize = 4;
53276 }else{
53277 int minLocal = pPage->minLocal;
53278 nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
53279 testcase( nSize==pPage->maxLocal );
53280 testcase( nSize==pPage->maxLocal+1 );
53281 if( nSize>pPage->maxLocal ){
53282 nSize = minLocal;
53283 }
53284 nSize += 4 + (u16)(pIter - pCell);
53285 }
53286 assert( nSize==debuginfo.nSize || CORRUPT_DB );
 
 
 
 
 
 
 
53287 return (u16)nSize;
53288 }
53289
53290 #ifdef SQLITE_DEBUG
53291 /* This variation on cellSizePtr() is used inside of assert() statements
@@ -53194,11 +53304,10 @@
53304 static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
53305 CellInfo info;
53306 if( *pRC ) return;
53307 assert( pCell!=0 );
53308 btreeParseCellPtr(pPage, pCell, &info);
 
53309 if( info.iOverflow ){
53310 Pgno ovfl = get4byte(&pCell[info.iOverflow]);
53311 ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
53312 }
53313 }
@@ -53407,11 +53516,11 @@
53516 ** does it detect cells or freeblocks that encrouch into the reserved bytes
53517 ** at the end of the page. So do additional corruption checks inside this
53518 ** routine and return SQLITE_CORRUPT if any problems are found.
53519 */
53520 static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
53521 u16 iPtr; /* Address of ptr to next freeblock */
53522 u16 iFreeBlk; /* Address of the next freeblock */
53523 u8 hdr; /* Page header size. 0 or 100 */
53524 u8 nFrag = 0; /* Reduction in fragmentation */
53525 u16 iOrigSize = iSize; /* Original value of iSize */
53526 u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
@@ -53459,13 +53568,13 @@
53568 iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
53569 iSize = iEnd - iStart;
53570 iFreeBlk = get2byte(&data[iFreeBlk]);
53571 }
53572
53573 /* If iPtr is another freeblock (that is, if iPtr is not the freelist
53574 ** pointer in the page header) then check to see if iStart should be
53575 ** coalesced onto the end of iPtr.
53576 */
53577 if( iPtr>hdr+1 ){
53578 int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
53579 if( iPtrEnd+3>=iStart ){
53580 if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
@@ -53515,16 +53624,18 @@
53624 flagByte &= ~PTF_LEAF;
53625 pPage->childPtrSize = 4-4*pPage->leaf;
53626 pBt = pPage->pBt;
53627 if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
53628 pPage->intKey = 1;
53629 pPage->intKeyLeaf = pPage->leaf;
53630 pPage->noPayload = !pPage->leaf;
53631 pPage->maxLocal = pBt->maxLeaf;
53632 pPage->minLocal = pBt->minLeaf;
53633 }else if( flagByte==PTF_ZERODATA ){
53634 pPage->intKey = 0;
53635 pPage->intKeyLeaf = 0;
53636 pPage->noPayload = 0;
53637 pPage->maxLocal = pBt->maxLocal;
53638 pPage->minLocal = pBt->minLocal;
53639 }else{
53640 return SQLITE_CORRUPT_BKPT;
53641 }
@@ -54175,11 +54286,12 @@
54286 #endif
54287 }
54288
54289 /*
54290 ** Make sure pBt->pTmpSpace points to an allocation of
54291 ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
54292 ** pointer.
54293 */
54294 static void allocateTempSpace(BtShared *pBt){
54295 if( !pBt->pTmpSpace ){
54296 pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
54297
@@ -54190,21 +54302,32 @@
54302 ** can mean that fillInCell() only initializes the first 2 or 3
54303 ** bytes of pTmpSpace, but that the first 4 bytes are copied from
54304 ** it into a database page. This is not actually a problem, but it
54305 ** does cause a valgrind error when the 1 or 2 bytes of unitialized
54306 ** data is passed to system call write(). So to avoid this error,
54307 ** zero the first 4 bytes of temp space here.
54308 **
54309 ** Also: Provide four bytes of initialized space before the
54310 ** beginning of pTmpSpace as an area available to prepend the
54311 ** left-child pointer to the beginning of a cell.
54312 */
54313 if( pBt->pTmpSpace ){
54314 memset(pBt->pTmpSpace, 0, 8);
54315 pBt->pTmpSpace += 4;
54316 }
54317 }
54318 }
54319
54320 /*
54321 ** Free the pBt->pTmpSpace allocation
54322 */
54323 static void freeTempSpace(BtShared *pBt){
54324 if( pBt->pTmpSpace ){
54325 pBt->pTmpSpace -= 4;
54326 sqlite3PageFree(pBt->pTmpSpace);
54327 pBt->pTmpSpace = 0;
54328 }
54329 }
54330
54331 /*
54332 ** Close an open database and invalidate all cursors.
54333 */
@@ -54694,15 +54817,15 @@
54817 */
54818 static void unlockBtreeIfUnused(BtShared *pBt){
54819 assert( sqlite3_mutex_held(pBt->mutex) );
54820 assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE );
54821 if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
54822 MemPage *pPage1 = pBt->pPage1;
54823 assert( pPage1->aData );
54824 assert( sqlite3PagerRefcount(pBt->pPager)==1 );
 
 
54825 pBt->pPage1 = 0;
54826 releasePage(pPage1);
54827 }
54828 }
54829
54830 /*
54831 ** If pBt points to an empty file then convert that empty file
@@ -55739,10 +55862,14 @@
55862 assert( pBt->pPage1 && pBt->pPage1->aData );
55863
55864 if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
55865 return SQLITE_READONLY;
55866 }
55867 if( wrFlag ){
55868 allocateTempSpace(pBt);
55869 if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
55870 }
55871 if( iTable==1 && btreePagecount(pBt)==0 ){
55872 assert( wrFlag==0 );
55873 iTable = 0;
55874 }
55875
@@ -55928,12 +56055,13 @@
56055 ** to return an integer result code for historical reasons.
56056 */
56057 SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
56058 assert( cursorHoldsMutex(pCur) );
56059 assert( pCur->eState==CURSOR_VALID );
56060 assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
56061 getCellInfo(pCur);
56062 *pSize = pCur->info.nPayload;
56063 return SQLITE_OK;
56064 }
56065
56066 /*
56067 ** Given the page number of an overflow page in the database (parameter
@@ -56080,34 +56208,32 @@
56208 unsigned char *pBuf, /* Write the bytes into this buffer */
56209 int eOp /* zero to read. non-zero to write. */
56210 ){
56211 unsigned char *aPayload;
56212 int rc = SQLITE_OK;
 
56213 int iIdx = 0;
56214 MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
56215 BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
56216 #ifdef SQLITE_DIRECT_OVERFLOW_READ
56217 unsigned char * const pBufStart = pBuf;
56218 int bEnd; /* True if reading to end of data */
56219 #endif
56220
56221 assert( pPage );
56222 assert( pCur->eState==CURSOR_VALID );
56223 assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
56224 assert( cursorHoldsMutex(pCur) );
56225 assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */
56226
56227 getCellInfo(pCur);
56228 aPayload = pCur->info.pPayload;
 
56229 #ifdef SQLITE_DIRECT_OVERFLOW_READ
56230 bEnd = offset+amt==pCur->info.nPayload;
56231 #endif
56232 assert( offset+amt <= pCur->info.nPayload );
56233
56234 if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){
 
 
56235 /* Trying to read or write past the end of the data is an error */
56236 return SQLITE_CORRUPT_BKPT;
56237 }
56238
56239 /* Check if data must be read/written to/from the btree page itself. */
@@ -56159,11 +56285,13 @@
56285
56286 /* If the overflow page-list cache has been allocated and the
56287 ** entry for the first required overflow page is valid, skip
56288 ** directly to it.
56289 */
56290 if( (pCur->curFlags & BTCF_ValidOvfl)!=0
56291 && pCur->aOverflow[offset/ovflSize]
56292 ){
56293 iIdx = (offset/ovflSize);
56294 nextPage = pCur->aOverflow[iIdx];
56295 offset = (offset%ovflSize);
56296 }
56297
@@ -56212,10 +56340,11 @@
56340 ** 2) data is required from the start of this overflow page, and
56341 ** 3) the database is file-backed, and
56342 ** 4) there is no open write-transaction, and
56343 ** 5) the database is not a WAL database,
56344 ** 6) all data from the page is being read.
56345 ** 7) at least 4 bytes have already been read into the output buffer
56346 **
56347 ** then data can be read directly from the database file into the
56348 ** output buffer, bypassing the page-cache altogether. This speeds
56349 ** up loading large records that span many overflow pages.
56350 */
@@ -56223,13 +56352,15 @@
56352 && offset==0 /* (2) */
56353 && (bEnd || a==ovflSize) /* (6) */
56354 && pBt->inTransaction==TRANS_READ /* (4) */
56355 && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
56356 && pBt->pPage1->aData[19]==0x01 /* (5) */
56357 && &pBuf[-4]>=pBufStart /* (7) */
56358 ){
56359 u8 aSave[4];
56360 u8 *aWrite = &pBuf[-4];
56361 assert( aWrite>=pBufStart ); /* hence (7) */
56362 memcpy(aSave, aWrite, 4);
56363 rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
56364 nextPage = get4byte(aWrite);
56365 memcpy(aWrite, aSave, 4);
56366 }else
@@ -56337,11 +56468,11 @@
56468 assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
56469 assert( cursorHoldsMutex(pCur) );
56470 assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
56471 assert( pCur->info.nSize>0 );
56472 *pAmt = pCur->info.nLocal;
56473 return (void*)pCur->info.pPayload;
56474 }
56475
56476
56477 /*
56478 ** For the entry that cursor pCur is point to, return as
@@ -56765,11 +56896,11 @@
56896 pCur->aiIdx[pCur->iPage] = (u16)idx;
56897 if( xRecordCompare==0 ){
56898 for(;;){
56899 i64 nCellKey;
56900 pCell = findCell(pPage, idx) + pPage->childPtrSize;
56901 if( pPage->intKeyLeaf ){
56902 while( 0x80 <= *(pCell++) ){
56903 if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
56904 }
56905 }
56906 getVarint(pCell, (u64*)&nCellKey);
@@ -57024,13 +57155,13 @@
57155 ** was already pointing to the first entry in the database before
57156 ** this routine was called, then set *pRes=1.
57157 **
57158 ** The main entry point is sqlite3BtreePrevious(). That routine is optimized
57159 ** for the common case of merely decrementing the cell counter BtCursor.aiIdx
57160 ** to the previous cell on the current page. The (slower) btreePrevious()
57161 ** helper routine is called when it is necessary to move to a different page
57162 ** or to restore the cursor.
57163 **
57164 ** The calling function will set *pRes to 0 or 1. The initial *pRes value
57165 ** will be 1 if the cursor being stepped corresponds to an SQL index and
57166 ** if this routine could have been skipped if that SQL index had been
57167 ** a unique index. Otherwise the caller will have set *pRes to zero.
@@ -57048,12 +57179,11 @@
57179 assert( *pRes==0 );
57180 assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
57181 assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
57182 assert( pCur->info.nSize==0 );
57183 if( pCur->eState!=CURSOR_VALID ){
57184 rc = restoreCursorPosition(pCur);
 
57185 if( rc!=SQLITE_OK ){
57186 return rc;
57187 }
57188 if( CURSOR_INVALID==pCur->eState ){
57189 *pRes = 1;
@@ -57354,11 +57484,11 @@
57484 if( rc ) goto end_allocate_page;
57485 if( closest<k-1 ){
57486 memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
57487 }
57488 put4byte(&aData[4], k-1);
57489 noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
57490 rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
57491 if( rc==SQLITE_OK ){
57492 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
57493 if( rc!=SQLITE_OK ){
57494 releasePage(*ppPage);
@@ -57387,11 +57517,11 @@
57517 ** content for any page that really does lie past the end of the database
57518 ** file on disk. So the effects of disabling the no-content optimization
57519 ** here are confined to those pages that lie between the end of the
57520 ** database image and the end of the database file.
57521 */
57522 int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0;
57523
57524 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
57525 if( rc ) return rc;
57526 pBt->nPage++;
57527 if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
@@ -57586,22 +57716,29 @@
57716 *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
57717 }
57718 }
57719
57720 /*
57721 ** Free any overflow pages associated with the given Cell. Write the
57722 ** local Cell size (the number of bytes on the original page, omitting
57723 ** overflow) into *pnSize.
57724 */
57725 static int clearCell(
57726 MemPage *pPage, /* The page that contains the Cell */
57727 unsigned char *pCell, /* First byte of the Cell */
57728 u16 *pnSize /* Write the size of the Cell here */
57729 ){
57730 BtShared *pBt = pPage->pBt;
57731 CellInfo info;
57732 Pgno ovflPgno;
57733 int rc;
57734 int nOvfl;
57735 u32 ovflPageSize;
57736
57737 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
57738 btreeParseCellPtr(pPage, pCell, &info);
57739 *pnSize = info.nSize;
57740 if( info.iOverflow==0 ){
57741 return SQLITE_OK; /* No overflow pages. Return without doing anything */
57742 }
57743 if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
57744 return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
@@ -57681,54 +57818,87 @@
57818 unsigned char *pPrior;
57819 unsigned char *pPayload;
57820 BtShared *pBt = pPage->pBt;
57821 Pgno pgnoOvfl = 0;
57822 int nHeader;
 
57823
57824 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
57825
57826 /* pPage is not necessarily writeable since pCell might be auxiliary
57827 ** buffer space that is separate from the pPage buffer area */
57828 assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
57829 || sqlite3PagerIswriteable(pPage->pDbPage) );
57830
57831 /* Fill in the header. */
57832 nHeader = pPage->childPtrSize;
57833 nPayload = nData + nZero;
57834 if( pPage->intKeyLeaf ){
57835 nHeader += putVarint32(&pCell[nHeader], nPayload);
 
 
57836 }else{
57837 assert( nData==0 );
57838 assert( nZero==0 );
57839 }
57840 nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
 
 
 
 
57841
57842 /* Fill in the payload size */
 
57843 if( pPage->intKey ){
57844 pSrc = pData;
57845 nSrc = nData;
57846 nData = 0;
57847 }else{
57848 if( NEVER(nKey>0x7fffffff || pKey==0) ){
57849 return SQLITE_CORRUPT_BKPT;
57850 }
57851 nPayload = (int)nKey;
57852 pSrc = pKey;
57853 nSrc = (int)nKey;
57854 }
57855 if( nPayload<=pPage->maxLocal ){
57856 n = nHeader + nPayload;
57857 testcase( n==3 );
57858 testcase( n==4 );
57859 if( n<4 ) n = 4;
57860 *pnSize = n;
57861 spaceLeft = nPayload;
57862 pPrior = pCell;
57863 }else{
57864 int mn = pPage->minLocal;
57865 n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
57866 testcase( n==pPage->maxLocal );
57867 testcase( n==pPage->maxLocal+1 );
57868 if( n > pPage->maxLocal ) n = mn;
57869 spaceLeft = n;
57870 *pnSize = n + nHeader + 4;
57871 pPrior = &pCell[nHeader+n];
57872 }
57873 pPayload = &pCell[nHeader];
 
57874
57875 /* At this point variables should be set as follows:
57876 **
57877 ** nPayload Total payload size in bytes
57878 ** pPayload Begin writing payload here
57879 ** spaceLeft Space available at pPayload. If nPayload>spaceLeft,
57880 ** that means content must spill into overflow pages.
57881 ** *pnSize Size of the local cell (not counting overflow pages)
57882 ** pPrior Where to write the pgno of the first overflow page
57883 **
57884 ** Use a call to btreeParseCellPtr() to verify that the values above
57885 ** were computed correctly.
57886 */
57887 #if SQLITE_DEBUG
57888 {
57889 CellInfo info;
57890 btreeParseCellPtr(pPage, pCell, &info);
57891 assert( nHeader=(int)(info.pPayload - pCell) );
57892 assert( info.nKey==nKey );
57893 assert( *pnSize == info.nSize );
57894 assert( spaceLeft == info.nLocal );
57895 assert( pPrior == &pCell[info.iOverflow] );
57896 }
57897 #endif
57898
57899 /* Write the payload into the local Cell and any extra into overflow pages */
57900 while( nPayload>0 ){
57901 if( spaceLeft==0 ){
57902 #ifndef SQLITE_OMIT_AUTOVACUUM
57903 Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
57904 if( pBt->autoVacuum ){
@@ -57865,15 +58035,10 @@
58035 ** pTemp is not null. Regardless of pTemp, allocate a new entry
58036 ** in pPage->apOvfl[] and make it point to the cell content (either
58037 ** in pTemp or the original pCell) and also record its index.
58038 ** Allocating a new entry in pPage->aCell[] implies that
58039 ** pPage->nOverflow is incremented.
 
 
 
 
 
58040 */
58041 static void insertCell(
58042 MemPage *pPage, /* Page into which we are copying */
58043 int i, /* New cell becomes the i-th cell of the page */
58044 u8 *pCell, /* Content of the new cell */
@@ -57886,11 +58051,10 @@
58051 int j; /* Loop counter */
58052 int end; /* First byte past the last cell pointer in data[] */
58053 int ins; /* Index in data[] where new cell pointer is inserted */
58054 int cellOffset; /* Address of first cell pointer in data[] */
58055 u8 *data; /* The content of the whole page */
 
58056
58057 if( *pRC ) return;
58058
58059 assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
58060 assert( MX_CELL(pPage->pBt)<=10921 );
@@ -57904,11 +58068,11 @@
58068 ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
58069 ** the term after the || in the following assert(). */
58070 assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
58071 if( pPage->nOverflow || sz+2>pPage->nFree ){
58072 if( pTemp ){
58073 memcpy(pTemp, pCell, sz);
58074 pCell = pTemp;
58075 }
58076 if( iChild ){
58077 put4byte(pCell, iChild);
58078 }
@@ -57933,11 +58097,11 @@
58097 ** if it returns success */
58098 assert( idx >= end+2 );
58099 assert( idx+sz <= (int)pPage->pBt->usableSize );
58100 pPage->nCell++;
58101 pPage->nFree -= (u16)(2 + sz);
58102 memcpy(&data[idx], pCell, sz);
58103 if( iChild ){
58104 put4byte(&data[idx], iChild);
58105 }
58106 memmove(&data[ins+2], &data[ins], end-ins);
58107 put2byte(&data[ins], idx);
@@ -58432,11 +58596,11 @@
58596 **
58597 ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
58598 ** leafData: 1 if pPage holds key+data and pParent holds only keys.
58599 */
58600 leafCorrection = apOld[0]->leaf*4;
58601 leafData = apOld[0]->intKeyLeaf;
58602 for(i=0; i<nOld; i++){
58603 int limit;
58604
58605 /* Before doing anything else, take a copy of the i'th original sibling
58606 ** The rest of this function will use data from the copies rather
@@ -59008,11 +59172,11 @@
59172 int const iIdx = pCur->aiIdx[iPage-1];
59173
59174 rc = sqlite3PagerWrite(pParent->pDbPage);
59175 if( rc==SQLITE_OK ){
59176 #ifndef SQLITE_OMIT_QUICKBALANCE
59177 if( pPage->intKeyLeaf
59178 && pPage->nOverflow==1
59179 && pPage->aiOvfl[0]==pPage->nCell
59180 && pParent->pgno!=1
59181 && pParent->nCell==iIdx
59182 ){
@@ -59127,11 +59291,12 @@
59291 assert( pCur->skipNext!=SQLITE_OK );
59292 return pCur->skipNext;
59293 }
59294
59295 assert( cursorHoldsMutex(pCur) );
59296 assert( (pCur->curFlags & BTCF_WriteFlag)!=0
59297 && pBt->inTransaction==TRANS_WRITE
59298 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
59299 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
59300
59301 /* Assert that the caller has been consistent. If this cursor was opened
59302 ** expecting an index b-tree, then the caller should be inserting blob
@@ -59160,11 +59325,12 @@
59325 invalidateIncrblobCursors(p, nKey, 0);
59326
59327 /* If the cursor is currently on the last row and we are appending a
59328 ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
59329 ** call */
59330 if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0
59331 && pCur->info.nKey==nKey-1 ){
59332 loc = -1;
59333 }
59334 }
59335
59336 if( !loc ){
@@ -59179,13 +59345,12 @@
59345
59346 TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
59347 pCur->pgnoRoot, nKey, nData, pPage->pgno,
59348 loc==0 ? "overwrite" : "new entry"));
59349 assert( pPage->isInit );
 
59350 newCell = pBt->pTmpSpace;
59351 assert( newCell!=0 );
59352 rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
59353 if( rc ) goto end_insert;
59354 assert( szNew==cellSizePtr(pPage, newCell) );
59355 assert( szNew <= MX_CELL_SIZE(pBt) );
59356 idx = pCur->aiIdx[pCur->iPage];
@@ -59198,12 +59363,11 @@
59363 }
59364 oldCell = findCell(pPage, idx);
59365 if( !pPage->leaf ){
59366 memcpy(newCell, oldCell, 4);
59367 }
59368 rc = clearCell(pPage, oldCell, &szOld);
 
59369 dropCell(pPage, idx, szOld, &rc);
59370 if( rc ) goto end_insert;
59371 }else if( loc<0 && pPage->nCell>0 ){
59372 assert( pPage->leaf );
59373 idx = ++pCur->aiIdx[pCur->iPage];
@@ -59261,10 +59425,11 @@
59425 int rc; /* Return code */
59426 MemPage *pPage; /* Page to delete cell from */
59427 unsigned char *pCell; /* Pointer to cell to delete */
59428 int iCellIdx; /* Index of cell to delete */
59429 int iCellDepth; /* Depth of node containing pCell */
59430 u16 szCell; /* Size of the cell being deleted */
59431
59432 assert( cursorHoldsMutex(pCur) );
59433 assert( pBt->inTransaction==TRANS_WRITE );
59434 assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
59435 assert( pCur->curFlags & BTCF_WriteFlag );
@@ -59309,12 +59474,12 @@
59474 invalidateIncrblobCursors(p, pCur->info.nKey, 0);
59475 }
59476
59477 rc = sqlite3PagerWrite(pPage->pDbPage);
59478 if( rc ) return rc;
59479 rc = clearCell(pPage, pCell, &szCell);
59480 dropCell(pPage, iCellIdx, szCell, &rc);
59481 if( rc ) return rc;
59482
59483 /* If the cell deleted was not located on a leaf page, then the cursor
59484 ** is currently pointing to the largest entry in the sub-tree headed
59485 ** by the child-page of the cell that was just deleted from an internal
@@ -59327,14 +59492,12 @@
59492 unsigned char *pTmp;
59493
59494 pCell = findCell(pLeaf, pLeaf->nCell-1);
59495 nCell = cellSizePtr(pLeaf, pCell);
59496 assert( MX_CELL_SIZE(pBt) >= nCell );
 
 
59497 pTmp = pBt->pTmpSpace;
59498 assert( pTmp!=0 );
59499 rc = sqlite3PagerWrite(pLeaf->pDbPage);
59500 insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
59501 dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
59502 if( rc ) return rc;
59503 }
@@ -59542,10 +59705,11 @@
59705 MemPage *pPage;
59706 int rc;
59707 unsigned char *pCell;
59708 int i;
59709 int hdr;
59710 u16 szCell;
59711
59712 assert( sqlite3_mutex_held(pBt->mutex) );
59713 if( pgno>btreePagecount(pBt) ){
59714 return SQLITE_CORRUPT_BKPT;
59715 }
@@ -59557,11 +59721,11 @@
59721 pCell = findCell(pPage, i);
59722 if( !pPage->leaf ){
59723 rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
59724 if( rc ) goto cleardatabasepage_out;
59725 }
59726 rc = clearCell(pPage, pCell, &szCell);
59727 if( rc ) goto cleardatabasepage_out;
59728 }
59729 if( !pPage->leaf ){
59730 rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
59731 if( rc ) goto cleardatabasepage_out;
@@ -59903,24 +60067,25 @@
60067 /*
60068 ** Append a message to the error message string.
60069 */
60070 static void checkAppendMsg(
60071 IntegrityCk *pCheck,
 
60072 const char *zFormat,
60073 ...
60074 ){
60075 va_list ap;
60076 char zBuf[200];
60077 if( !pCheck->mxErr ) return;
60078 pCheck->mxErr--;
60079 pCheck->nErr++;
60080 va_start(ap, zFormat);
60081 if( pCheck->errMsg.nChar ){
60082 sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
60083 }
60084 if( pCheck->zPfx ){
60085 sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2);
60086 sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf);
60087 }
60088 sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
60089 va_end(ap);
60090 if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
60091 pCheck->mallocFailed = 1;
@@ -59954,18 +60119,18 @@
60119 ** Return 1 if there are 2 or more references to the page and 0 if
60120 ** if this is the first reference to the page.
60121 **
60122 ** Also check that the page number is in bounds.
60123 */
60124 static int checkRef(IntegrityCk *pCheck, Pgno iPage){
60125 if( iPage==0 ) return 1;
60126 if( iPage>pCheck->nPage ){
60127 checkAppendMsg(pCheck, "invalid page number %d", iPage);
60128 return 1;
60129 }
60130 if( getPageReferenced(pCheck, iPage) ){
60131 checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
60132 return 1;
60133 }
60134 setPageReferenced(pCheck, iPage);
60135 return 0;
60136 }
@@ -59978,26 +60143,25 @@
60143 */
60144 static void checkPtrmap(
60145 IntegrityCk *pCheck, /* Integrity check context */
60146 Pgno iChild, /* Child page number */
60147 u8 eType, /* Expected pointer map type */
60148 Pgno iParent /* Expected pointer map parent page number */
 
60149 ){
60150 int rc;
60151 u8 ePtrmapType;
60152 Pgno iPtrmapParent;
60153
60154 rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
60155 if( rc!=SQLITE_OK ){
60156 if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
60157 checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild);
60158 return;
60159 }
60160
60161 if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
60162 checkAppendMsg(pCheck,
60163 "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
60164 iChild, eType, iParent, ePtrmapType, iPtrmapParent);
60165 }
60166 }
60167 #endif
@@ -60008,51 +60172,50 @@
60172 */
60173 static void checkList(
60174 IntegrityCk *pCheck, /* Integrity checking context */
60175 int isFreeList, /* True for a freelist. False for overflow page list */
60176 int iPage, /* Page number for first page in the list */
60177 int N /* Expected number of pages in the list */
 
60178 ){
60179 int i;
60180 int expected = N;
60181 int iFirst = iPage;
60182 while( N-- > 0 && pCheck->mxErr ){
60183 DbPage *pOvflPage;
60184 unsigned char *pOvflData;
60185 if( iPage<1 ){
60186 checkAppendMsg(pCheck,
60187 "%d of %d pages missing from overflow list starting at %d",
60188 N+1, expected, iFirst);
60189 break;
60190 }
60191 if( checkRef(pCheck, iPage) ) break;
60192 if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
60193 checkAppendMsg(pCheck, "failed to get page %d", iPage);
60194 break;
60195 }
60196 pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
60197 if( isFreeList ){
60198 int n = get4byte(&pOvflData[4]);
60199 #ifndef SQLITE_OMIT_AUTOVACUUM
60200 if( pCheck->pBt->autoVacuum ){
60201 checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
60202 }
60203 #endif
60204 if( n>(int)pCheck->pBt->usableSize/4-2 ){
60205 checkAppendMsg(pCheck,
60206 "freelist leaf count too big on page %d", iPage);
60207 N--;
60208 }else{
60209 for(i=0; i<n; i++){
60210 Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
60211 #ifndef SQLITE_OMIT_AUTOVACUUM
60212 if( pCheck->pBt->autoVacuum ){
60213 checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0);
60214 }
60215 #endif
60216 checkRef(pCheck, iFreePage);
60217 }
60218 N -= n;
60219 }
60220 }
60221 #ifndef SQLITE_OMIT_AUTOVACUUM
@@ -60061,11 +60224,11 @@
60224 ** page in this overflow list, check that the pointer-map entry for
60225 ** the following page matches iPage.
60226 */
60227 if( pCheck->pBt->autoVacuum && N>0 ){
60228 i = get4byte(pOvflData);
60229 checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage);
60230 }
60231 }
60232 #endif
60233 iPage = get4byte(pOvflData);
60234 sqlite3PagerUnref(pOvflPage);
@@ -60093,11 +60256,10 @@
60256 ** the root of the tree.
60257 */
60258 static int checkTreePage(
60259 IntegrityCk *pCheck, /* Context for the sanity check */
60260 int iPage, /* Page number of the page to check */
 
60261 i64 *pnParentMinKey,
60262 i64 *pnParentMaxKey
60263 ){
60264 MemPage *pPage;
60265 int i, rc, depth, d2, pgno, cnt;
@@ -60104,38 +60266,42 @@
60266 int hdr, cellStart;
60267 int nCell;
60268 u8 *data;
60269 BtShared *pBt;
60270 int usableSize;
 
60271 char *hit = 0;
60272 i64 nMinKey = 0;
60273 i64 nMaxKey = 0;
60274 const char *saved_zPfx = pCheck->zPfx;
60275 int saved_v1 = pCheck->v1;
60276 int saved_v2 = pCheck->v2;
60277
60278 /* Check that the page exists
60279 */
60280 pBt = pCheck->pBt;
60281 usableSize = pBt->usableSize;
60282 if( iPage==0 ) return 0;
60283 if( checkRef(pCheck, iPage) ) return 0;
60284 pCheck->zPfx = "Page %d: ";
60285 pCheck->v1 = iPage;
60286 if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
60287 checkAppendMsg(pCheck,
60288 "unable to get the page. error code=%d", rc);
60289 depth = -1;
60290 goto end_of_check;
60291 }
60292
60293 /* Clear MemPage.isInit to make sure the corruption detection code in
60294 ** btreeInitPage() is executed. */
60295 pPage->isInit = 0;
60296 if( (rc = btreeInitPage(pPage))!=0 ){
60297 assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */
60298 checkAppendMsg(pCheck,
60299 "btreeInitPage() returns error code %d", rc);
60300 releasePage(pPage);
60301 depth = -1;
60302 goto end_of_check;
60303 }
60304
60305 /* Check out all the cells.
60306 */
60307 depth = 0;
@@ -60144,99 +60310,101 @@
60310 u32 sz;
60311 CellInfo info;
60312
60313 /* Check payload overflow pages
60314 */
60315 pCheck->zPfx = "On tree page %d cell %d: ";
60316 pCheck->v1 = iPage;
60317 pCheck->v2 = i;
60318 pCell = findCell(pPage,i);
60319 btreeParseCellPtr(pPage, pCell, &info);
60320 sz = info.nPayload;
 
60321 /* For intKey pages, check that the keys are in order.
60322 */
60323 if( pPage->intKey ){
60324 if( i==0 ){
60325 nMinKey = nMaxKey = info.nKey;
60326 }else if( info.nKey <= nMaxKey ){
60327 checkAppendMsg(pCheck,
60328 "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
60329 }
60330 nMaxKey = info.nKey;
60331 }
 
60332 if( (sz>info.nLocal)
60333 && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
60334 ){
60335 int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
60336 Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
60337 #ifndef SQLITE_OMIT_AUTOVACUUM
60338 if( pBt->autoVacuum ){
60339 checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
60340 }
60341 #endif
60342 checkList(pCheck, 0, pgnoOvfl, nPage);
60343 }
60344
60345 /* Check sanity of left child page.
60346 */
60347 if( !pPage->leaf ){
60348 pgno = get4byte(pCell);
60349 #ifndef SQLITE_OMIT_AUTOVACUUM
60350 if( pBt->autoVacuum ){
60351 checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
60352 }
60353 #endif
60354 d2 = checkTreePage(pCheck, pgno, &nMinKey, i==0?NULL:&nMaxKey);
60355 if( i>0 && d2!=depth ){
60356 checkAppendMsg(pCheck, "Child page depth differs");
60357 }
60358 depth = d2;
60359 }
60360 }
60361
60362 if( !pPage->leaf ){
60363 pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
60364 pCheck->zPfx = "On page %d at right child: ";
60365 pCheck->v1 = iPage;
60366 #ifndef SQLITE_OMIT_AUTOVACUUM
60367 if( pBt->autoVacuum ){
60368 checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
60369 }
60370 #endif
60371 checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey);
60372 }
60373
60374 /* For intKey leaf pages, check that the min/max keys are in order
60375 ** with any left/parent/right pages.
60376 */
60377 pCheck->zPfx = "Page %d: ";
60378 pCheck->v1 = iPage;
60379 if( pPage->leaf && pPage->intKey ){
60380 /* if we are a left child page */
60381 if( pnParentMinKey ){
60382 /* if we are the left most child page */
60383 if( !pnParentMaxKey ){
60384 if( nMaxKey > *pnParentMinKey ){
60385 checkAppendMsg(pCheck,
60386 "Rowid %lld out of order (max larger than parent min of %lld)",
60387 nMaxKey, *pnParentMinKey);
60388 }
60389 }else{
60390 if( nMinKey <= *pnParentMinKey ){
60391 checkAppendMsg(pCheck,
60392 "Rowid %lld out of order (min less than parent min of %lld)",
60393 nMinKey, *pnParentMinKey);
60394 }
60395 if( nMaxKey > *pnParentMaxKey ){
60396 checkAppendMsg(pCheck,
60397 "Rowid %lld out of order (max larger than parent max of %lld)",
60398 nMaxKey, *pnParentMaxKey);
60399 }
60400 *pnParentMinKey = nMaxKey;
60401 }
60402 /* else if we're a right child page */
60403 } else if( pnParentMaxKey ){
60404 if( nMinKey <= *pnParentMaxKey ){
60405 checkAppendMsg(pCheck,
60406 "Rowid %lld out of order (min less than parent max of %lld)",
60407 nMinKey, *pnParentMaxKey);
60408 }
60409 }
60410 }
@@ -60244,10 +60412,11 @@
60412 /* Check for complete coverage of the page
60413 */
60414 data = pPage->aData;
60415 hdr = pPage->hdrOffset;
60416 hit = sqlite3PageMalloc( pBt->pageSize );
60417 pCheck->zPfx = 0;
60418 if( hit==0 ){
60419 pCheck->mallocFailed = 1;
60420 }else{
60421 int contentOffset = get2byteNotZero(&data[hdr+5]);
60422 assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
@@ -60261,11 +60430,12 @@
60430 int j;
60431 if( pc<=usableSize-4 ){
60432 size = cellSizePtr(pPage, &data[pc]);
60433 }
60434 if( (int)(pc+size-1)>=usableSize ){
60435 pCheck->zPfx = 0;
60436 checkAppendMsg(pCheck,
60437 "Corruption detected in cell %d on page %d",i,iPage);
60438 }else{
60439 for(j=pc+size-1; j>=pc; j--) hit[j]++;
60440 }
60441 }
@@ -60283,23 +60453,28 @@
60453 }
60454 for(i=cnt=0; i<usableSize; i++){
60455 if( hit[i]==0 ){
60456 cnt++;
60457 }else if( hit[i]>1 ){
60458 checkAppendMsg(pCheck,
60459 "Multiple uses for byte %d of page %d", i, iPage);
60460 break;
60461 }
60462 }
60463 if( cnt!=data[hdr+7] ){
60464 checkAppendMsg(pCheck,
60465 "Fragmentation of %d bytes reported as %d on page %d",
60466 cnt, data[hdr+7], iPage);
60467 }
60468 }
60469 sqlite3PageFree(hit);
60470 releasePage(pPage);
60471
60472 end_of_check:
60473 pCheck->zPfx = saved_zPfx;
60474 pCheck->v1 = saved_v1;
60475 pCheck->v2 = saved_v2;
60476 return depth+1;
60477 }
60478 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
60479
60480 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
@@ -60336,10 +60511,13 @@
60511 sCheck.pPager = pBt->pPager;
60512 sCheck.nPage = btreePagecount(sCheck.pBt);
60513 sCheck.mxErr = mxErr;
60514 sCheck.nErr = 0;
60515 sCheck.mallocFailed = 0;
60516 sCheck.zPfx = 0;
60517 sCheck.v1 = 0;
60518 sCheck.v2 = 0;
60519 *pnErr = 0;
60520 if( sCheck.nPage==0 ){
60521 sqlite3BtreeLeave(p);
60522 return 0;
60523 }
@@ -60355,53 +60533,57 @@
60533 sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
60534 sCheck.errMsg.useMalloc = 2;
60535
60536 /* Check the integrity of the freelist
60537 */
60538 sCheck.zPfx = "Main freelist: ";
60539 checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
60540 get4byte(&pBt->pPage1->aData[36]));
60541 sCheck.zPfx = 0;
60542
60543 /* Check all the tables.
60544 */
60545 for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
60546 if( aRoot[i]==0 ) continue;
60547 #ifndef SQLITE_OMIT_AUTOVACUUM
60548 if( pBt->autoVacuum && aRoot[i]>1 ){
60549 checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
60550 }
60551 #endif
60552 sCheck.zPfx = "List of tree roots: ";
60553 checkTreePage(&sCheck, aRoot[i], NULL, NULL);
60554 sCheck.zPfx = 0;
60555 }
60556
60557 /* Make sure every page in the file is referenced
60558 */
60559 for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
60560 #ifdef SQLITE_OMIT_AUTOVACUUM
60561 if( getPageReferenced(&sCheck, i)==0 ){
60562 checkAppendMsg(&sCheck, "Page %d is never used", i);
60563 }
60564 #else
60565 /* If the database supports auto-vacuum, make sure no tables contain
60566 ** references to pointer-map pages.
60567 */
60568 if( getPageReferenced(&sCheck, i)==0 &&
60569 (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
60570 checkAppendMsg(&sCheck, "Page %d is never used", i);
60571 }
60572 if( getPageReferenced(&sCheck, i)!=0 &&
60573 (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
60574 checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
60575 }
60576 #endif
60577 }
60578
60579 /* Make sure this analysis did not leave any unref() pages.
60580 ** This is an internal consistency check; an integrity check
60581 ** of the integrity check.
60582 */
60583 if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
60584 checkAppendMsg(&sCheck,
60585 "Outstanding page count goes from %d to %d during this analysis",
60586 nRef, sqlite3PagerRefcount(pBt->pPager)
60587 );
60588 }
60589
@@ -60593,11 +60775,11 @@
60775
60776 /* Save the positions of all other cursors open on this table. This is
60777 ** required in case any of them are holding references to an xFetch
60778 ** version of the b-tree page modified by the accessPayload call below.
60779 **
60780 ** Note that pCsr must be open on a INTKEY table and saveCursorPosition()
60781 ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
60782 ** saveAllCursors can only return SQLITE_OK.
60783 */
60784 VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
60785 assert( rc==SQLITE_OK );
@@ -61461,11 +61643,14 @@
61643 /* If MEM_Dyn is set then Mem.xDel!=0.
61644 ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
61645 */
61646 assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
61647
61648 /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we
61649 ** ensure that if Mem.szMalloc>0 then it is safe to do
61650 ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
61651 ** That saves a few cycles in inner loops. */
61652 assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
61653
61654 /* Cannot be both MEM_Int and MEM_Real at the same time */
61655 assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
61656
@@ -61570,11 +61755,11 @@
61755 }else{
61756 pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
61757 }
61758 }
61759
61760 if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
61761 memcpy(pMem->zMalloc, pMem->z, pMem->n);
61762 }
61763 if( (pMem->flags&MEM_Dyn)!=0 ){
61764 assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
61765 pMem->xDel((void *)(pMem->z));
@@ -61597,11 +61782,12 @@
61782 **
61783 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
61784 ** if unable to complete the resizing.
61785 */
61786 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
61787 assert( szNew>0 );
61788 assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
61789 if( pMem->szMalloc<szNew ){
61790 return sqlite3VdbeMemGrow(pMem, szNew, 0);
61791 }
61792 assert( (pMem->flags & MEM_Dyn)==0 );
61793 pMem->z = pMem->zMalloc;
@@ -62321,11 +62507,14 @@
62507 nAlloc += (enc==SQLITE_UTF8?1:2);
62508 }
62509 if( nByte>iLimit ){
62510 return SQLITE_TOOBIG;
62511 }
62512 testcase( nAlloc==0 );
62513 testcase( nAlloc==31 );
62514 testcase( nAlloc==32 );
62515 if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
62516 return SQLITE_NOMEM;
62517 }
62518 memcpy(pMem->z, z, nAlloc);
62519 }else if( xDel==SQLITE_DYNAMIC ){
62520 sqlite3VdbeMemRelease(pMem);
@@ -62424,11 +62613,11 @@
62613 /*
62614 ** The pVal argument is known to be a value other than NULL.
62615 ** Convert it into a string with encoding enc and return a pointer
62616 ** to a zero-terminated version of that string.
62617 */
62618 static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
62619 assert( pVal!=0 );
62620 assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
62621 assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
62622 assert( (pVal->flags & MEM_RowSet)==0 );
62623 assert( (pVal->flags & (MEM_Null))==0 );
@@ -63751,11 +63940,12 @@
63940 if( addr==p->nOp-1 ) p->nOp--;
63941 }
63942 }
63943
63944 /*
63945 ** If the last opcode is "op" and it is not a jump destination,
63946 ** then remove it. Return true if and only if an opcode was removed.
63947 */
63948 SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
63949 if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
63950 sqlite3VdbeChangeToNoop(p, p->nOp-1);
63951 return 1;
@@ -64743,11 +64933,11 @@
64933 ** the call above. */
64934 }else if( pCx->pCursor ){
64935 sqlite3BtreeCloseCursor(pCx->pCursor);
64936 }
64937 #ifndef SQLITE_OMIT_VIRTUALTABLE
64938 else if( pCx->pVtabCursor ){
64939 sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
64940 const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
64941 p->inVtabMethod = 1;
64942 pModule->xClose(pVtabCursor);
64943 p->inVtabMethod = 0;
@@ -64786,13 +64976,14 @@
64976 static void closeAllCursors(Vdbe *p){
64977 if( p->pFrame ){
64978 VdbeFrame *pFrame;
64979 for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
64980 sqlite3VdbeFrameRestore(pFrame);
64981 p->pFrame = 0;
64982 p->nFrame = 0;
64983 }
64984 assert( p->nFrame==0 );
 
64985
64986 if( p->apCsr ){
64987 int i;
64988 for(i=0; i<p->nCursor; i++){
64989 VdbeCursor *pC = p->apCsr[i];
@@ -64810,11 +65001,11 @@
65001 p->pDelFrame = pDel->pParent;
65002 sqlite3VdbeFrameDelete(pDel);
65003 }
65004
65005 /* Delete any auxdata allocations made by the VM */
65006 if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
65007 assert( p->pAuxData==0 );
65008 }
65009
65010 /*
65011 ** Clean up the VM after a single run.
@@ -65676,14 +65867,10 @@
65867 for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
65868 vdbeFreeOpArray(db, p->aOp, p->nOp);
65869 sqlite3DbFree(db, p->aColName);
65870 sqlite3DbFree(db, p->zSql);
65871 sqlite3DbFree(db, p->pFree);
 
 
 
 
65872 }
65873
65874 /*
65875 ** Delete an entire VDBE.
65876 */
@@ -65720,13 +65907,11 @@
65907 #endif
65908 assert( p->deferredMoveto );
65909 assert( p->isTable );
65910 rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
65911 if( rc ) return rc;
 
65912 if( res!=0 ) return SQLITE_CORRUPT_BKPT;
 
65913 #ifdef SQLITE_TEST
65914 sqlite3_search_count++;
65915 #endif
65916 p->deferredMoveto = 0;
65917 p->cacheStatus = CACHE_STALE;
@@ -65747,10 +65932,21 @@
65932 rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
65933 p->cacheStatus = CACHE_STALE;
65934 if( isDifferentRow ) p->nullRow = 1;
65935 return rc;
65936 }
65937
65938 /*
65939 ** Check to ensure that the cursor is valid. Restore the cursor
65940 ** if need be. Return any I/O error from the restore operation.
65941 */
65942 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
65943 if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
65944 return handleMovedCursor(p);
65945 }
65946 return SQLITE_OK;
65947 }
65948
65949 /*
65950 ** Make sure the cursor p is ready to read or write the row to which it
65951 ** was last positioned. Return an error code if an OOM fault or I/O error
65952 ** prevents us from positioning the cursor to its correct position.
@@ -65765,11 +65961,11 @@
65961 */
65962 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
65963 if( p->deferredMoveto ){
65964 return handleDeferredMoveto(p);
65965 }
65966 if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
65967 return handleMovedCursor(p);
65968 }
65969 return SQLITE_OK;
65970 }
65971
@@ -67390,10 +67586,11 @@
67586 void (*xDel)(void *),
67587 unsigned char enc
67588 ){
67589 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
67590 assert( xDel!=SQLITE_DYNAMIC );
67591 if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
67592 if( n>0x7fffffff ){
67593 (void)invokeValueDestructor(z, xDel, pCtx);
67594 }else{
67595 setResultStrOrError(pCtx, z, (int)n, enc, xDel);
67596 }
@@ -68712,125 +68909,10 @@
68909 return sqlite3StrAccumFinish(&out);
68910 }
68911
68912 #endif /* #ifndef SQLITE_OMIT_TRACE */
68913
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68914 /************** End of vdbetrace.c *******************************************/
68915 /************** Begin file vdbe.c ********************************************/
68916 /*
68917 ** 2001 September 15
68918 **
@@ -69043,10 +69125,11 @@
69125 if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
69126 p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
69127 memset(pCx, 0, sizeof(VdbeCursor));
69128 pCx->iDb = iDb;
69129 pCx->nField = nField;
69130 pCx->aOffset = &pCx->aType[nField];
69131 if( isBtreeCursor ){
69132 pCx->pCursor = (BtCursor*)
69133 &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
69134 sqlite3BtreeCursorZero(pCx->pCursor);
69135 }
@@ -70475,21 +70558,14 @@
70558 assert( pOp->p4type==P4_FUNCDEF );
70559 ctx.pFunc = pOp->p4.pFunc;
70560 ctx.iOp = pc;
70561 ctx.pVdbe = p;
70562 MemSetTypeFlag(ctx.pOut, MEM_Null);
 
70563 ctx.fErrorOrAux = 0;
 
 
 
 
 
 
70564 db->lastRowid = lastRowid;
70565 (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
70566 lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
70567
70568 /* If the function returned an error, throw an exception */
70569 if( ctx.fErrorOrAux ){
70570 if( ctx.isError ){
70571 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
@@ -71201,11 +71277,11 @@
71277 memAboutToChange(p, pDest);
71278 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
71279 pC = p->apCsr[pOp->p1];
71280 assert( pC!=0 );
71281 assert( p2<pC->nField );
71282 aOffset = pC->aOffset;
71283 #ifndef SQLITE_OMIT_VIRTUALTABLE
71284 assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
71285 #endif
71286 pCrsr = pC->pCursor;
71287 assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
@@ -71212,11 +71288,11 @@
71288 assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
71289
71290 /* If the cursor cache is stale, bring it up-to-date */
71291 rc = sqlite3VdbeCursorMoveto(pC);
71292 if( rc ) goto abort_due_to_error;
71293 if( pC->cacheStatus!=p->cacheCtr ){
71294 if( pC->nullRow ){
71295 if( pCrsr==0 ){
71296 assert( pC->pseudoTableReg>0 );
71297 pReg = &aMem[pC->pseudoTableReg];
71298 assert( pReg->flags & MEM_Blob );
@@ -71257,18 +71333,10 @@
71333 }
71334 pC->cacheStatus = p->cacheCtr;
71335 pC->iHdrOffset = getVarint32(pC->aRow, offset);
71336 pC->nHdrParsed = 0;
71337 aOffset[0] = offset;
 
 
 
 
 
 
 
 
71338
71339 /* Make sure a corrupt database has not given us an oversize header.
71340 ** Do this now to avoid an oversize memory allocation.
71341 **
71342 ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
@@ -71279,19 +71347,36 @@
71347 */
71348 if( offset > 98307 || offset > pC->payloadSize ){
71349 rc = SQLITE_CORRUPT_BKPT;
71350 goto op_column_error;
71351 }
71352
71353 if( avail<offset ){
71354 /* pC->aRow does not have to hold the entire row, but it does at least
71355 ** need to cover the header of the record. If pC->aRow does not contain
71356 ** the complete header, then set it to zero, forcing the header to be
71357 ** dynamically allocated. */
71358 pC->aRow = 0;
71359 pC->szRow = 0;
71360 }
71361
71362 /* The following goto is an optimization. It can be omitted and
71363 ** everything will still work. But OP_Column is measurably faster
71364 ** by skipping the subsequent conditional, which is always true.
71365 */
71366 assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
71367 goto op_column_read_header;
71368 }
71369
71370 /* Make sure at least the first p2+1 entries of the header have been
71371 ** parsed and valid information is in aOffset[] and pC->aType[].
71372 */
71373 if( pC->nHdrParsed<=p2 ){
71374 /* If there is more header available for parsing in the record, try
71375 ** to extract additional fields up through the p2+1-th field
71376 */
71377 op_column_read_header:
71378 if( pC->iHdrOffset<aOffset[0] ){
71379 /* Make sure zData points to enough of the record to cover the header. */
71380 if( pC->aRow==0 ){
71381 memset(&sMem, 0, sizeof(sMem));
71382 rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
@@ -71332,19 +71417,20 @@
71417 if( pC->aRow==0 ){
71418 sqlite3VdbeMemRelease(&sMem);
71419 sMem.flags = MEM_Null;
71420 }
71421
71422 /* The record is corrupt if any of the following are true:
71423 ** (1) the bytes of the header extend past the declared header size
71424 ** (zHdr>zEndHdr)
71425 ** (2) the entire header was used but not all data was used
71426 ** (zHdr==zEndHdr && offset!=pC->payloadSize)
71427 ** (3) the end of the data extends beyond the end of the record.
71428 ** (offset > pC->payloadSize)
71429 */
71430 if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
71431 || (offset > pC->payloadSize)
 
71432 ){
71433 rc = SQLITE_CORRUPT_BKPT;
71434 goto op_column_error;
71435 }
71436 }
@@ -71531,11 +71617,11 @@
71617 ** out how much space is required for the new record.
71618 */
71619 pRec = pLast;
71620 do{
71621 assert( memIsValid(pRec) );
71622 pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
71623 len = sqlite3VdbeSerialTypeLen(serial_type);
71624 if( pRec->flags & MEM_Zero ){
71625 if( nData ){
71626 sqlite3VdbeMemExpandBlob(pRec);
71627 }else{
@@ -71580,11 +71666,11 @@
71666 i = putVarint32(zNewRecord, nHdr);
71667 j = nHdr;
71668 assert( pData0<=pLast );
71669 pRec = pData0;
71670 do{
71671 serial_type = pRec->uTemp;
71672 i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
71673 j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
71674 }while( (++pRec)<=pLast );
71675 assert( i==nHdr );
71676 assert( j==nByte );
@@ -72205,14 +72291,10 @@
72291 rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
72292 pCur->pKeyInfo = pKeyInfo;
72293 assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
72294 sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
72295
 
 
 
 
72296 /* Set the VdbeCursor.isTable variable. Previous versions of
72297 ** SQLite used to check if the root-page flags were sane at this point
72298 ** and report database corruption if they were not, but this check has
72299 ** since moved into the btree layer. */
72300 pCur->isTable = pOp->p4type!=P4_KEYINFO;
@@ -72483,11 +72565,10 @@
72565 pIn3 = &aMem[pOp->p3];
72566 if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
72567 applyNumericAffinity(pIn3, 0);
72568 }
72569 iKey = sqlite3VdbeIntValue(pIn3);
 
72570
72571 /* If the P3 value could not be converted into an integer without
72572 ** loss of information, then special processing is required... */
72573 if( (pIn3->flags & MEM_Int)==0 ){
72574 if( (pIn3->flags & MEM_Real)==0 ){
@@ -72519,17 +72600,14 @@
72600 assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
72601 if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
72602 }
72603 }
72604 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
72605 pC->movetoTarget = iKey; /* Used by OP_Delete */
72606 if( rc!=SQLITE_OK ){
72607 goto abort_due_to_error;
72608 }
 
 
 
 
72609 }else{
72610 nField = pOp->p4.i;
72611 assert( pOp->p4type==P4_INT32 );
72612 assert( nField>0 );
72613 r.pKeyInfo = pC->pKeyInfo;
@@ -72555,11 +72633,10 @@
72633 ExpandBlob(r.aMem);
72634 rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
72635 if( rc!=SQLITE_OK ){
72636 goto abort_due_to_error;
72637 }
 
72638 }
72639 pC->deferredMoveto = 0;
72640 pC->cacheStatus = CACHE_STALE;
72641 #ifdef SQLITE_TEST
72642 sqlite3_search_count++;
@@ -72567,21 +72644,19 @@
72644 if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
72645 if( res<0 || (res==0 && oc==OP_SeekGT) ){
72646 res = 0;
72647 rc = sqlite3BtreeNext(pC->pCursor, &res);
72648 if( rc!=SQLITE_OK ) goto abort_due_to_error;
 
72649 }else{
72650 res = 0;
72651 }
72652 }else{
72653 assert( oc==OP_SeekLT || oc==OP_SeekLE );
72654 if( res>0 || (res==0 && oc==OP_SeekLT) ){
72655 res = 0;
72656 rc = sqlite3BtreePrevious(pC->pCursor, &res);
72657 if( rc!=SQLITE_OK ) goto abort_due_to_error;
 
72658 }else{
72659 /* res might be negative because the table is empty. Check to
72660 ** see if this is the case.
72661 */
72662 res = sqlite3BtreeEof(pC->pCursor);
@@ -72614,11 +72689,10 @@
72689 assert( pC->pCursor!=0 );
72690 assert( pC->isTable );
72691 pC->nullRow = 0;
72692 pIn2 = &aMem[pOp->p2];
72693 pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
 
72694 pC->deferredMoveto = 1;
72695 break;
72696 }
72697
72698
@@ -72800,19 +72874,17 @@
72874 pCrsr = pC->pCursor;
72875 assert( pCrsr!=0 );
72876 res = 0;
72877 iKey = pIn3->u.i;
72878 rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
72879 pC->movetoTarget = iKey; /* Used by OP_Delete */
 
72880 pC->nullRow = 0;
72881 pC->cacheStatus = CACHE_STALE;
72882 pC->deferredMoveto = 0;
72883 VdbeBranchTaken(res!=0,2);
72884 if( res!=0 ){
72885 pc = pOp->p2 - 1;
 
72886 }
72887 pC->seekResult = res;
72888 break;
72889 }
72890
@@ -72942,36 +73014,24 @@
73014 ** largest possible integer (9223372036854775807) then the database
73015 ** engine starts picking positive candidate ROWIDs at random until
73016 ** it finds one that is not previously used. */
73017 assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is
73018 ** an AUTOINCREMENT table. */
 
 
 
 
73019 cnt = 0;
73020 do{
73021 sqlite3_randomness(sizeof(v), &v);
73022 v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */
73023 }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
73024 0, &res))==SQLITE_OK)
73025 && (res==0)
73026 && (++cnt<100));
 
 
 
 
 
 
 
 
 
 
73027 if( rc==SQLITE_OK && res==0 ){
73028 rc = SQLITE_FULL; /* IMP: R-38219-53002 */
73029 goto abort_due_to_error;
73030 }
73031 assert( v>0 ); /* EV: R-40812-03570 */
73032 }
 
73033 pC->deferredMoveto = 0;
73034 pC->cacheStatus = CACHE_STALE;
73035 }
73036 pOut->u.i = v;
73037 break;
@@ -73072,11 +73132,10 @@
73132 }
73133 rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
73134 pData->z, pData->n, nZero,
73135 (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
73136 );
 
73137 pC->deferredMoveto = 0;
73138 pC->cacheStatus = CACHE_STALE;
73139
73140 /* Invoke the update-hook if required. */
73141 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
@@ -73109,37 +73168,36 @@
73168 ** pointing to. The update hook will be invoked, if it exists.
73169 ** If P4 is not NULL then the P1 cursor must have been positioned
73170 ** using OP_NotFound prior to invoking this opcode.
73171 */
73172 case OP_Delete: {
 
73173 VdbeCursor *pC;
73174
73175 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73176 pC = p->apCsr[pOp->p1];
73177 assert( pC!=0 );
73178 assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
 
 
 
 
 
 
 
 
 
73179 assert( pC->deferredMoveto==0 );
 
 
73180
73181 #ifdef SQLITE_DEBUG
73182 /* The seek operation that positioned the cursor prior to OP_Delete will
73183 ** have also set the pC->movetoTarget field to the rowid of the row that
73184 ** is being deleted */
73185 if( pOp->p4.z && pC->isTable ){
73186 i64 iKey = 0;
73187 sqlite3BtreeKeySize(pC->pCursor, &iKey);
73188 assert( pC->movetoTarget==iKey );
73189 }
73190 #endif
73191
73192 rc = sqlite3BtreeDelete(pC->pCursor);
73193 pC->cacheStatus = CACHE_STALE;
73194
73195 /* Invoke the update-hook if required. */
73196 if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
73197 db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
73198 db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
73199 assert( pC->iDb>=0 );
73200 }
73201 if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
73202 break;
73203 }
@@ -73188,23 +73246,32 @@
73246 pc = pOp->p2-1;
73247 }
73248 break;
73249 };
73250
73251 /* Opcode: SorterData P1 P2 P3 * *
73252 ** Synopsis: r[P2]=data
73253 **
73254 ** Write into register P2 the current sorter data for sorter cursor P1.
73255 ** Then clear the column header cache on cursor P3.
73256 **
73257 ** This opcode is normally use to move a record out of the sorter and into
73258 ** a register that is the source for a pseudo-table cursor created using
73259 ** OpenPseudo. That pseudo-table cursor is the one that is identified by
73260 ** parameter P3. Clearing the P3 column cache as part of this opcode saves
73261 ** us from having to issue a separate NullRow instruction to clear that cache.
73262 */
73263 case OP_SorterData: {
73264 VdbeCursor *pC;
73265
73266 pOut = &aMem[pOp->p2];
73267 pC = p->apCsr[pOp->p1];
73268 assert( isSorter(pC) );
73269 rc = sqlite3VdbeSorterRowkey(pC, pOut);
73270 assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
73271 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73272 p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
73273 break;
73274 }
73275
73276 /* Opcode: RowData P1 P2 * * *
73277 ** Synopsis: r[P2]=data
@@ -73247,20 +73314,24 @@
73314 assert( pC!=0 );
73315 assert( pC->nullRow==0 );
73316 assert( pC->pseudoTableReg==0 );
73317 assert( pC->pCursor!=0 );
73318 pCrsr = pC->pCursor;
 
73319
73320 /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
73321 ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
73322 ** the cursor. If this where not the case, on of the following assert()s
73323 ** would fail. Should this ever change (because of changes in the code
73324 ** generator) then the fix would be to insert a call to
73325 ** sqlite3VdbeCursorMoveto().
73326 */
73327 assert( pC->deferredMoveto==0 );
73328 assert( sqlite3BtreeCursorIsValid(pCrsr) );
73329 #if 0 /* Not required due to the previous to assert() statements */
73330 rc = sqlite3VdbeCursorMoveto(pC);
73331 if( rc!=SQLITE_OK ) goto abort_due_to_error;
73332 #endif
73333
73334 if( pC->isTable==0 ){
73335 assert( !pC->isTable );
73336 VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
73337 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -73273,11 +73344,12 @@
73344 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
73345 if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
73346 goto too_big;
73347 }
73348 }
73349 testcase( n==0 );
73350 if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
73351 goto no_mem;
73352 }
73353 pOut->n = n;
73354 MemSetTypeFlag(pOut, MEM_Blob);
73355 if( pC->isTable==0 ){
@@ -73324,18 +73396,14 @@
73396 rc = pModule->xRowid(pC->pVtabCursor, &v);
73397 sqlite3VtabImportErrmsg(p, pVtab);
73398 #endif /* SQLITE_OMIT_VIRTUALTABLE */
73399 }else{
73400 assert( pC->pCursor!=0 );
73401 rc = sqlite3VdbeCursorRestore(pC);
73402 if( rc ) goto abort_due_to_error;
73403 rc = sqlite3BtreeKeySize(pC->pCursor, &v);
73404 assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
 
 
 
 
73405 }
73406 pOut->u.i = v;
73407 break;
73408 }
73409
@@ -73350,11 +73418,10 @@
73418
73419 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
73420 pC = p->apCsr[pOp->p1];
73421 assert( pC!=0 );
73422 pC->nullRow = 1;
 
73423 pC->cacheStatus = CACHE_STALE;
73424 if( pC->pCursor ){
73425 sqlite3BtreeClearCursor(pC->pCursor);
73426 }
73427 break;
@@ -73384,11 +73451,10 @@
73451 res = 0;
73452 assert( pCrsr!=0 );
73453 rc = sqlite3BtreeLast(pCrsr, &res);
73454 pC->nullRow = (u8)res;
73455 pC->deferredMoveto = 0;
 
73456 pC->cacheStatus = CACHE_STALE;
73457 #ifdef SQLITE_DEBUG
73458 pC->seekOp = OP_Last;
73459 #endif
73460 if( pOp->p2>0 ){
@@ -73451,11 +73517,10 @@
73517 pCrsr = pC->pCursor;
73518 assert( pCrsr );
73519 rc = sqlite3BtreeFirst(pCrsr, &res);
73520 pC->deferredMoveto = 0;
73521 pC->cacheStatus = CACHE_STALE;
 
73522 }
73523 pC->nullRow = (u8)res;
73524 assert( pOp->p2>0 && pOp->p2<p->nOp );
73525 VdbeBranchTaken(res!=0,2);
73526 if( res ){
@@ -73577,11 +73642,10 @@
73642 sqlite3_search_count++;
73643 #endif
73644 }else{
73645 pC->nullRow = 1;
73646 }
 
73647 goto check_for_interrupt;
73648 }
73649
73650 /* Opcode: IdxInsert P1 P2 P3 * P5
73651 ** Synopsis: key=r[P2]
@@ -73693,14 +73757,20 @@
73757 pC = p->apCsr[pOp->p1];
73758 assert( pC!=0 );
73759 pCrsr = pC->pCursor;
73760 assert( pCrsr!=0 );
73761 pOut->flags = MEM_Null;
73762 assert( pC->isTable==0 );
 
73763 assert( pC->deferredMoveto==0 );
73764
73765 /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
73766 ** out from under the cursor. That will never happend for an IdxRowid
73767 ** opcode, hence the NEVER() arround the check of the return value.
73768 */
73769 rc = sqlite3VdbeCursorRestore(pC);
73770 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
73771
73772 if( !pC->nullRow ){
73773 rowid = 0; /* Not needed. Only used to silence a warning. */
73774 rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
73775 if( rc!=SQLITE_OK ){
73776 goto abort_due_to_error;
@@ -74556,18 +74626,13 @@
74626 ctx.pMem = pMem = &aMem[pOp->p3];
74627 pMem->n++;
74628 sqlite3VdbeMemInit(&t, db, MEM_Null);
74629 ctx.pOut = &t;
74630 ctx.isError = 0;
74631 ctx.pVdbe = p;
74632 ctx.iOp = pc;
74633 ctx.skipFlag = 0;
 
 
 
 
 
 
74634 (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
74635 if( ctx.isError ){
74636 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
74637 rc = ctx.isError;
74638 }
@@ -78162,11 +78227,11 @@
78227 if( rc==SQLITE_OK ){
78228 #if SQLITE_MAX_WORKER_THREADS
78229 assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
78230 if( pSorter->bUseThreads ){
78231 int iTask;
78232 PmaReader *pReadr = 0;
78233 SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
78234 rc = vdbeSortAllocUnpacked(pLast);
78235 if( rc==SQLITE_OK ){
78236 pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
78237 pSorter->pReader = pReadr;
@@ -81597,10 +81662,11 @@
81662 pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
81663 pNew->addrOpenEphm[0] = -1;
81664 pNew->addrOpenEphm[1] = -1;
81665 pNew->nSelectRow = p->nSelectRow;
81666 pNew->pWith = withDup(db, p->pWith);
81667 sqlite3SelectSetName(pNew, p->zSelName);
81668 return pNew;
81669 }
81670 #else
81671 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
81672 assert( p==0 );
@@ -81739,36 +81805,44 @@
81805 }
81806
81807 /*
81808 ** These routines are Walker callbacks. Walker.u.pi is a pointer
81809 ** to an integer. These routines are checking an expression to see
81810 ** if it is a constant. Set *Walker.u.i to 0 if the expression is
81811 ** not constant.
81812 **
81813 ** These callback routines are used to implement the following:
81814 **
81815 ** sqlite3ExprIsConstant() pWalker->u.i==1
81816 ** sqlite3ExprIsConstantNotJoin() pWalker->u.i==2
81817 ** sqlite3ExprIsConstantOrFunction() pWalker->u.i==3 or 4
81818 **
81819 ** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
81820 ** in a CREATE TABLE statement. The Walker.u.i value is 4 when parsing
81821 ** an existing schema and 3 when processing a new statement. A bound
81822 ** parameter raises an error for new statements, but is silently converted
81823 ** to NULL for existing schemas. This allows sqlite_master tables that
81824 ** contain a bound parameter because they were generated by older versions
81825 ** of SQLite to be parsed by newer versions of SQLite without raising a
81826 ** malformed schema error.
81827 */
81828 static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
81829
81830 /* If pWalker->u.i is 2 then any term of the expression that comes from
81831 ** the ON or USING clauses of a join disqualifies the expression
81832 ** from being considered constant. */
81833 if( pWalker->u.i==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
81834 pWalker->u.i = 0;
81835 return WRC_Abort;
81836 }
81837
81838 switch( pExpr->op ){
81839 /* Consider functions to be constant if all their arguments are constant
81840 ** and either pWalker->u.i==3 or 4 or the function as the SQLITE_FUNC_CONST
81841 ** flag. */
81842 case TK_FUNCTION:
81843 if( pWalker->u.i>=3 || ExprHasProperty(pExpr,EP_Constant) ){
81844 return WRC_Continue;
81845 }
81846 /* Fall through */
81847 case TK_ID:
81848 case TK_COLUMN:
@@ -81778,10 +81852,23 @@
81852 testcase( pExpr->op==TK_COLUMN );
81853 testcase( pExpr->op==TK_AGG_FUNCTION );
81854 testcase( pExpr->op==TK_AGG_COLUMN );
81855 pWalker->u.i = 0;
81856 return WRC_Abort;
81857 case TK_VARIABLE:
81858 if( pWalker->u.i==4 ){
81859 /* Silently convert bound parameters that appear inside of CREATE
81860 ** statements into a NULL when parsing the CREATE statement text out
81861 ** of the sqlite_master table */
81862 pExpr->op = TK_NULL;
81863 }else if( pWalker->u.i==3 ){
81864 /* A bound parameter in a CREATE statement that originates from
81865 ** sqlite3_prepare() causes an error */
81866 pWalker->u.i = 0;
81867 return WRC_Abort;
81868 }
81869 /* Fall through */
81870 default:
81871 testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
81872 testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
81873 return WRC_Continue;
81874 }
@@ -81818,11 +81905,11 @@
81905 ** that does no originate from the ON or USING clauses of a join.
81906 ** Return 0 if it involves variables or function calls or terms from
81907 ** an ON or USING clause.
81908 */
81909 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
81910 return exprIsConst(p, 2);
81911 }
81912
81913 /*
81914 ** Walk an expression tree. Return 1 if the expression is constant
81915 ** or a function call with constant arguments. Return and 0 if there
@@ -81830,12 +81917,13 @@
81917 **
81918 ** For the purposes of this function, a double-quoted string (ex: "abc")
81919 ** is considered a variable but a single-quoted string (ex: 'abc') is
81920 ** a constant.
81921 */
81922 SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
81923 assert( isInit==0 || isInit==1 );
81924 return exprIsConst(p, 3+isInit);
81925 }
81926
81927 /*
81928 ** If the expression p codes a constant integer that is small enough
81929 ** to fit in a 32-bit integer, return 1 and put the value of the integer
@@ -83741,94 +83829,90 @@
83829 iMem = ++pParse->nMem;
83830 sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
83831 exprToRegister(pExpr, iMem);
83832 }
83833
83834 #ifdef SQLITE_DEBUG
83835 /*
83836 ** Generate a human-readable explanation of an expression tree.
83837 */
83838 SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
 
83839 const char *zBinOp = 0; /* Binary operator */
83840 const char *zUniOp = 0; /* Unary operator */
83841 pView = sqlite3TreeViewPush(pView, moreToFollow);
83842 if( pExpr==0 ){
83843 sqlite3TreeViewLine(pView, "nil");
83844 sqlite3TreeViewPop(pView);
83845 return;
83846 }
83847 switch( pExpr->op ){
83848 case TK_AGG_COLUMN: {
83849 sqlite3TreeViewLine(pView, "AGG{%d:%d}",
83850 pExpr->iTable, pExpr->iColumn);
83851 break;
83852 }
83853 case TK_COLUMN: {
83854 if( pExpr->iTable<0 ){
83855 /* This only happens when coding check constraints */
83856 sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
83857 }else{
83858 sqlite3TreeViewLine(pView, "{%d:%d}",
83859 pExpr->iTable, pExpr->iColumn);
83860 }
83861 break;
83862 }
83863 case TK_INTEGER: {
83864 if( pExpr->flags & EP_IntValue ){
83865 sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
83866 }else{
83867 sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
83868 }
83869 break;
83870 }
83871 #ifndef SQLITE_OMIT_FLOATING_POINT
83872 case TK_FLOAT: {
83873 sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
83874 break;
83875 }
83876 #endif
83877 case TK_STRING: {
83878 sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
83879 break;
83880 }
83881 case TK_NULL: {
83882 sqlite3TreeViewLine(pView,"NULL");
83883 break;
83884 }
83885 #ifndef SQLITE_OMIT_BLOB_LITERAL
83886 case TK_BLOB: {
83887 sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
83888 break;
83889 }
83890 #endif
83891 case TK_VARIABLE: {
83892 sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
83893 pExpr->u.zToken, pExpr->iColumn);
83894 break;
83895 }
83896 case TK_REGISTER: {
83897 sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
83898 break;
83899 }
83900 case TK_AS: {
83901 sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
83902 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
83903 break;
83904 }
83905 case TK_ID: {
83906 sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
83907 break;
83908 }
83909 #ifndef SQLITE_OMIT_CAST
83910 case TK_CAST: {
83911 /* Expressions of the form: CAST(pLeft AS token) */
83912 sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
83913 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
 
 
 
 
 
 
 
 
 
83914 break;
83915 }
83916 #endif /* SQLITE_OMIT_CAST */
83917 case TK_LT: zBinOp = "LT"; break;
83918 case TK_LE: zBinOp = "LE"; break;
@@ -83848,21 +83932,22 @@
83932 case TK_BITOR: zBinOp = "BITOR"; break;
83933 case TK_SLASH: zBinOp = "DIV"; break;
83934 case TK_LSHIFT: zBinOp = "LSHIFT"; break;
83935 case TK_RSHIFT: zBinOp = "RSHIFT"; break;
83936 case TK_CONCAT: zBinOp = "CONCAT"; break;
83937 case TK_DOT: zBinOp = "DOT"; break;
83938
83939 case TK_UMINUS: zUniOp = "UMINUS"; break;
83940 case TK_UPLUS: zUniOp = "UPLUS"; break;
83941 case TK_BITNOT: zUniOp = "BITNOT"; break;
83942 case TK_NOT: zUniOp = "NOT"; break;
83943 case TK_ISNULL: zUniOp = "ISNULL"; break;
83944 case TK_NOTNULL: zUniOp = "NOTNULL"; break;
83945
83946 case TK_COLLATE: {
83947 sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
83948 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
83949 break;
83950 }
83951
83952 case TK_AGG_FUNCTION:
83953 case TK_FUNCTION: {
@@ -83870,45 +83955,40 @@
83955 if( ExprHasProperty(pExpr, EP_TokenOnly) ){
83956 pFarg = 0;
83957 }else{
83958 pFarg = pExpr->x.pList;
83959 }
83960 if( pExpr->op==TK_AGG_FUNCTION ){
83961 sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
83962 pExpr->op2, pExpr->u.zToken);
83963 }else{
83964 sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
83965 }
83966 if( pFarg ){
83967 sqlite3TreeViewExprList(pView, pFarg, 0, 0);
83968 }
 
83969 break;
83970 }
83971 #ifndef SQLITE_OMIT_SUBQUERY
83972 case TK_EXISTS: {
83973 sqlite3TreeViewLine(pView, "EXISTS-expr");
83974 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
 
83975 break;
83976 }
83977 case TK_SELECT: {
83978 sqlite3TreeViewLine(pView, "SELECT-expr");
83979 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
 
83980 break;
83981 }
83982 case TK_IN: {
83983 sqlite3TreeViewLine(pView, "IN");
83984 sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
 
83985 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
83986 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
83987 }else{
83988 sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
83989 }
 
83990 break;
83991 }
83992 #endif /* SQLITE_OMIT_SUBQUERY */
83993
83994 /*
@@ -83924,17 +84004,14 @@
84004 */
84005 case TK_BETWEEN: {
84006 Expr *pX = pExpr->pLeft;
84007 Expr *pY = pExpr->x.pList->a[0].pExpr;
84008 Expr *pZ = pExpr->x.pList->a[1].pExpr;
84009 sqlite3TreeViewLine(pView, "BETWEEN");
84010 sqlite3TreeViewExpr(pView, pX, 1);
84011 sqlite3TreeViewExpr(pView, pY, 1);
84012 sqlite3TreeViewExpr(pView, pZ, 0);
 
 
 
84013 break;
84014 }
84015 case TK_TRIGGER: {
84016 /* If the opcode is TK_TRIGGER, then the expression is a reference
84017 ** to a column in the new.* or old.* pseudo-tables available to
@@ -83941,19 +84018,18 @@
84018 ** trigger programs. In this case Expr.iTable is set to 1 for the
84019 ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
84020 ** is set to the column of the pseudo-table to read, or to -1 to
84021 ** read the rowid field.
84022 */
84023 sqlite3TreeViewLine(pView, "%s(%d)",
84024 pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
84025 break;
84026 }
84027 case TK_CASE: {
84028 sqlite3TreeViewLine(pView, "CASE");
84029 sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
84030 sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
 
84031 break;
84032 }
84033 #ifndef SQLITE_OMIT_TRIGGER
84034 case TK_RAISE: {
84035 const char *zType = "unk";
@@ -83961,59 +84037,61 @@
84037 case OE_Rollback: zType = "rollback"; break;
84038 case OE_Abort: zType = "abort"; break;
84039 case OE_Fail: zType = "fail"; break;
84040 case OE_Ignore: zType = "ignore"; break;
84041 }
84042 sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
84043 break;
84044 }
84045 #endif
84046 default: {
84047 sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
84048 break;
84049 }
84050 }
84051 if( zBinOp ){
84052 sqlite3TreeViewLine(pView, "%s", zBinOp);
84053 sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
84054 sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
 
 
84055 }else if( zUniOp ){
84056 sqlite3TreeViewLine(pView, "%s", zUniOp);
84057 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
84058 }
84059 sqlite3TreeViewPop(pView);
84060 }
84061 #endif /* SQLITE_DEBUG */
84062
84063 #ifdef SQLITE_DEBUG
84064 /*
84065 ** Generate a human-readable explanation of an expression list.
84066 */
84067 SQLITE_PRIVATE void sqlite3TreeViewExprList(
84068 TreeView *pView,
84069 const ExprList *pList,
84070 u8 moreToFollow,
84071 const char *zLabel
84072 ){
84073 int i;
84074 pView = sqlite3TreeViewPush(pView, moreToFollow);
84075 if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
84076 if( pList==0 ){
84077 sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
 
84078 }else{
84079 sqlite3TreeViewLine(pView, "%s", zLabel);
84080 for(i=0; i<pList->nExpr; i++){
84081 sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
84082 #if 0
84083 if( pList->a[i].zName ){
 
 
84084 sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
84085 }
84086 if( pList->a[i].bSpanIsTab ){
84087 sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
84088 }
84089 #endif
 
 
84090 }
 
84091 }
84092 sqlite3TreeViewPop(pView);
84093 }
84094 #endif /* SQLITE_DEBUG */
84095
84096 /*
84097 ** Generate code that pushes the value of every element of the given
@@ -87130,29 +87208,27 @@
87208 tRowcnt v;
87209
87210 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87211 if( z==0 ) z = "";
87212 #else
87213 assert( z!=0 );
87214 #endif
87215 for(i=0; *z && i<nOut; i++){
87216 v = 0;
87217 while( (c=z[0])>='0' && c<='9' ){
87218 v = v*10 + c - '0';
87219 z++;
87220 }
87221 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87222 if( aOut ) aOut[i] = v;
87223 if( aLog ) aLog[i] = sqlite3LogEst(v);
 
87224 #else
87225 assert( aOut==0 );
87226 UNUSED_PARAMETER(aOut);
87227 assert( aLog!=0 );
87228 aLog[i] = sqlite3LogEst(v);
87229 #endif
 
 
 
87230 if( *z==' ' ) z++;
87231 }
87232 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4
87233 assert( pIndex!=0 );
87234 #else
@@ -87209,12 +87285,21 @@
87285 pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
87286 }
87287 z = argv[2];
87288
87289 if( pIndex ){
87290 int nCol = pIndex->nKeyCol+1;
87291 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
87292 tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
87293 sizeof(tRowcnt) * nCol
87294 );
87295 if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
87296 #else
87297 tRowcnt * const aiRowEst = 0;
87298 #endif
87299 pIndex->bUnordered = 0;
87300 decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
87301 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
87302 }else{
87303 Index fakeIdx;
87304 fakeIdx.szIdxRow = pTable->szTabRow;
87305 #ifdef SQLITE_ENABLE_COSTMULT
@@ -87269,29 +87354,42 @@
87354 ** unique. */
87355 nCol = pIdx->nSampleCol-1;
87356 pIdx->aAvgEq[nCol] = 1;
87357 }
87358 for(iCol=0; iCol<nCol; iCol++){
87359 int nSample = pIdx->nSample;
87360 int i; /* Used to iterate through samples */
87361 tRowcnt sumEq = 0; /* Sum of the nEq values */
 
87362 tRowcnt avgEq = 0;
87363 tRowcnt nRow; /* Number of rows in index */
87364 i64 nSum100 = 0; /* Number of terms contributing to sumEq */
87365 i64 nDist100; /* Number of distinct values in index */
87366
87367 if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
87368 nRow = pFinal->anLt[iCol];
87369 nDist100 = (i64)100 * pFinal->anDLt[iCol];
87370 nSample--;
87371 }else{
87372 nRow = pIdx->aiRowEst[0];
87373 nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
87374 }
87375
87376 /* Set nSum to the number of distinct (iCol+1) field prefixes that
87377 ** occur in the stat4 table for this index. Set sumEq to the sum of
87378 ** the nEq values for column iCol for the same set (adding the value
87379 ** only once where there exist duplicate prefixes). */
87380 for(i=0; i<nSample; i++){
87381 if( i==(pIdx->nSample-1)
87382 || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol]
87383 ){
87384 sumEq += aSample[i].anEq[iCol];
87385 nSum100 += 100;
87386 }
87387 }
87388
87389 if( nDist100>nSum100 ){
87390 avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
87391 }
87392 if( avgEq==0 ) avgEq = 1;
87393 pIdx->aAvgEq[iCol] = avgEq;
87394 }
87395 }
@@ -87538,10 +87636,15 @@
87636 if( rc==SQLITE_OK ){
87637 int lookasideEnabled = db->lookaside.bEnabled;
87638 db->lookaside.bEnabled = 0;
87639 rc = loadStat4(db, sInfo.zDatabase);
87640 db->lookaside.bEnabled = lookasideEnabled;
87641 }
87642 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
87643 Index *pIdx = sqliteHashData(i);
87644 sqlite3_free(pIdx->aiRowEst);
87645 pIdx->aiRowEst = 0;
87646 }
87647 #endif
87648
87649 if( rc==SQLITE_NOMEM ){
87650 db->mallocFailed = 1;
@@ -88832,10 +88935,13 @@
88935 #endif
88936 if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
88937 sqlite3ExprDelete(db, p->pPartIdxWhere);
88938 sqlite3DbFree(db, p->zColAff);
88939 if( p->isResized ) sqlite3DbFree(db, p->azColl);
88940 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
88941 sqlite3_free(p->aiRowEst);
88942 #endif
88943 sqlite3DbFree(db, p);
88944 }
88945
88946 /*
88947 ** For the index called zIdxName which is found in the database iDb,
@@ -89633,11 +89739,11 @@
89739 Column *pCol;
89740 sqlite3 *db = pParse->db;
89741 p = pParse->pNewTable;
89742 if( p!=0 ){
89743 pCol = &(p->aCol[p->nCol-1]);
89744 if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
89745 sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
89746 pCol->zName);
89747 }else{
89748 /* A copy of pExpr is used instead of the original, as pExpr contains
89749 ** tokens that point to volatile memory. The 'span' of the expression
@@ -91141,11 +91247,11 @@
91247 pIndex->nKeyCol); VdbeCoverage(v);
91248 sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
91249 }else{
91250 addr2 = sqlite3VdbeCurrentAddr(v);
91251 }
91252 sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
91253 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
91254 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
91255 sqlite3ReleaseTempReg(pParse, regRecord);
91256 sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
91257 sqlite3VdbeJumpHere(v, addr1);
@@ -94030,11 +94136,14 @@
94136
94137 /*
94138 ** Return the collating function associated with a function.
94139 */
94140 static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
94141 VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
94142 assert( pOp->opcode==OP_CollSeq );
94143 assert( pOp->p4type==P4_COLLSEQ );
94144 return pOp->p4.pColl;
94145 }
94146
94147 /*
94148 ** Indicate that the accumulator load should be skipped on this
94149 ** iteration of the aggregate loop.
@@ -94575,14 +94684,16 @@
94684 ** character is exactly one byte in size. Also, all characters are
94685 ** able to participate in upper-case-to-lower-case mappings in EBCDIC
94686 ** whereas only characters less than 0x80 do in ASCII.
94687 */
94688 #if defined(SQLITE_EBCDIC)
94689 # define sqlite3Utf8Read(A) (*((*A)++))
94690 # define GlobUpperToLower(A) A = sqlite3UpperToLower[A]
94691 # define GlobUpperToLowerAscii(A) A = sqlite3UpperToLower[A]
94692 #else
94693 # define GlobUpperToLower(A) if( A<=0x7f ){ A = sqlite3UpperToLower[A]; }
94694 # define GlobUpperToLowerAscii(A) A = sqlite3UpperToLower[A]
94695 #endif
94696
94697 static const struct compareInfo globInfo = { '*', '?', '[', 0 };
94698 /* The correct SQL-92 behavior is for the LIKE operator to ignore
94699 ** case. Thus 'a' LIKE 'A' would be true. */
@@ -94591,11 +94702,11 @@
94702 ** is case sensitive causing 'a' LIKE 'A' to be false */
94703 static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
94704
94705 /*
94706 ** Compare two UTF-8 strings for equality where the first string can
94707 ** potentially be a "glob" or "like" expression. Return true (1) if they
94708 ** are the same and false (0) if they are different.
94709 **
94710 ** Globbing rules:
94711 **
94712 ** '*' Matches any sequence of zero or more characters.
@@ -94611,120 +94722,147 @@
94722 ** in the list by making it the first character after '[' or '^'. A
94723 ** range of characters can be specified using '-'. Example:
94724 ** "[a-z]" matches any single lower-case letter. To match a '-', make
94725 ** it the last character in the list.
94726 **
94727 ** Like matching rules:
94728 **
94729 ** '%' Matches any sequence of zero or more characters
94730 **
94731 *** '_' Matches any one character
94732 **
94733 ** Ec Where E is the "esc" character and c is any other
94734 ** character, including '%', '_', and esc, match exactly c.
94735 **
94736 ** The comments through this routine usually assume glob matching.
94737 **
94738 ** This routine is usually quick, but can be N**2 in the worst case.
 
 
 
 
94739 */
94740 static int patternCompare(
94741 const u8 *zPattern, /* The glob pattern */
94742 const u8 *zString, /* The string to compare against the glob */
94743 const struct compareInfo *pInfo, /* Information about how to do the compare */
94744 u32 esc /* The escape character */
94745 ){
94746 u32 c, c2; /* Next pattern and input string chars */
94747 u32 matchOne = pInfo->matchOne; /* "?" or "_" */
94748 u32 matchAll = pInfo->matchAll; /* "*" or "%" */
94749 u32 matchOther; /* "[" or the escape character */
94750 u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */
94751 const u8 *zEscaped = 0; /* One past the last escaped input char */
94752
94753 /* The GLOB operator does not have an ESCAPE clause. And LIKE does not
94754 ** have the matchSet operator. So we either have to look for one or
94755 ** the other, never both. Hence the single variable matchOther is used
94756 ** to store the one we have to look for.
94757 */
94758 matchOther = esc ? esc : pInfo->matchSet;
94759
94760 while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
94761 if( c==matchAll ){ /* Match "*" */
94762 /* Skip over multiple "*" characters in the pattern. If there
94763 ** are also "?" characters, skip those as well, but consume a
94764 ** single character of the input string for each "?" skipped */
94765 while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
94766 || c == matchOne ){
94767 if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
94768 return 0;
94769 }
94770 }
94771 if( c==0 ){
94772 return 1; /* "*" at the end of the pattern matches */
94773 }else if( c==matchOther ){
94774 if( esc ){
94775 c = sqlite3Utf8Read(&zPattern);
94776 if( c==0 ) return 0;
94777 }else{
94778 /* "[...]" immediately follows the "*". We have to do a slow
94779 ** recursive search in this case, but it is an unusual case. */
94780 assert( matchOther<0x80 ); /* '[' is a single-byte character */
94781 while( *zString
94782 && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
94783 SQLITE_SKIP_UTF8(zString);
94784 }
94785 return *zString!=0;
94786 }
94787 }
94788
94789 /* At this point variable c contains the first character of the
94790 ** pattern string past the "*". Search in the input string for the
94791 ** first matching character and recursively contine the match from
94792 ** that point.
94793 **
94794 ** For a case-insensitive search, set variable cx to be the same as
94795 ** c but in the other case and search the input string for either
94796 ** c or cx.
94797 */
94798 if( c<=0x80 ){
94799 u32 cx;
94800 if( noCase ){
94801 cx = sqlite3Toupper(c);
94802 c = sqlite3Tolower(c);
94803 }else{
94804 cx = c;
94805 }
94806 while( (c2 = *(zString++))!=0 ){
94807 if( c2!=c && c2!=cx ) continue;
94808 if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
94809 }
94810 }else{
94811 while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
94812 if( c2!=c ) continue;
94813 if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
94814 }
94815 }
94816 return 0;
94817 }
94818 if( c==matchOther ){
94819 if( esc ){
94820 c = sqlite3Utf8Read(&zPattern);
94821 if( c==0 ) return 0;
94822 zEscaped = zPattern;
94823 }else{
94824 u32 prior_c = 0;
94825 int seen = 0;
94826 int invert = 0;
94827 c = sqlite3Utf8Read(&zString);
94828 if( c==0 ) return 0;
94829 c2 = sqlite3Utf8Read(&zPattern);
94830 if( c2=='^' ){
94831 invert = 1;
94832 c2 = sqlite3Utf8Read(&zPattern);
94833 }
94834 if( c2==']' ){
94835 if( c==']' ) seen = 1;
94836 c2 = sqlite3Utf8Read(&zPattern);
94837 }
94838 while( c2 && c2!=']' ){
94839 if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
94840 c2 = sqlite3Utf8Read(&zPattern);
94841 if( c>=prior_c && c<=c2 ) seen = 1;
94842 prior_c = 0;
94843 }else{
94844 if( c==c2 ){
94845 seen = 1;
94846 }
94847 prior_c = c2;
94848 }
94849 c2 = sqlite3Utf8Read(&zPattern);
94850 }
94851 if( c2==0 || (seen ^ invert)==0 ){
94852 return 0;
94853 }
94854 continue;
94855 }
94856 }
94857 c2 = sqlite3Utf8Read(&zString);
94858 if( c==c2 ) continue;
94859 if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
94860 continue;
94861 }
94862 if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
94863 return 0;
94864 }
94865 return *zString==0;
94866 }
94867
94868 /*
@@ -103884,10 +104022,24 @@
104022 **
104023 *************************************************************************
104024 ** This file contains C code routines that are called by the parser
104025 ** to handle SELECT statements in SQLite.
104026 */
104027
104028 /*
104029 ** Trace output macros
104030 */
104031 #if SELECTTRACE_ENABLED
104032 /***/ int sqlite3SelectTrace = 0;
104033 # define SELECTTRACE(K,P,S,X) \
104034 if(sqlite3SelectTrace&(K)) \
104035 sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",(S)->zSelName,(S)),\
104036 sqlite3DebugPrintf X
104037 #else
104038 # define SELECTTRACE(K,P,S,X)
104039 #endif
104040
104041
104042 /*
104043 ** An instance of the following object is used to record information about
104044 ** how to process the DISTINCT keyword, to simplify passing that information
104045 ** into the selectInnerLoop() routine.
@@ -103996,10 +104148,22 @@
104148 assert( pNew->pSrc!=0 || pParse->nErr>0 );
104149 }
104150 assert( pNew!=&standin );
104151 return pNew;
104152 }
104153
104154 #if SELECTTRACE_ENABLED
104155 /*
104156 ** Set the name of a Select object
104157 */
104158 SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
104159 if( p && zName ){
104160 sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
104161 }
104162 }
104163 #endif
104164
104165
104166 /*
104167 ** Delete the given Select structure and all of its substructures.
104168 */
104169 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
@@ -105026,11 +105190,10 @@
105190 int regRow;
105191 int regRowid;
105192 int nKey;
105193 int iSortTab; /* Sorter cursor to read from */
105194 int nSortData; /* Trailing values to read from sorter */
 
105195 int i;
105196 int bSeq; /* True if sorter record includes seq. no. */
105197 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
105198 struct ExprList_item *aOutEx = p->pEList->a;
105199 #endif
@@ -105060,23 +105223,20 @@
105223 sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
105224 if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
105225 addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
105226 VdbeCoverage(v);
105227 codeOffset(v, p->iOffset, addrContinue);
105228 sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
 
105229 bSeq = 0;
105230 }else{
105231 addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
105232 codeOffset(v, p->iOffset, addrContinue);
105233 iSortTab = iTab;
 
105234 bSeq = 1;
105235 }
105236 for(i=0; i<nSortData; i++){
105237 sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
 
105238 VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
105239 }
105240 switch( eDest ){
105241 case SRT_Table:
105242 case SRT_EphemTab: {
@@ -107226,10 +107386,12 @@
107386 }
107387 }
107388 }
107389
107390 /***** If we reach this point, flattening is permitted. *****/
107391 SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
107392 pSub->zSelName, pSub, iFrom));
107393
107394 /* Authorize the subquery */
107395 pParse->zAuthContext = pSubitem->zName;
107396 TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
107397 testcase( i==SQLITE_DENY );
@@ -107278,10 +107440,11 @@
107440 p->pSrc = 0;
107441 p->pPrior = 0;
107442 p->pLimit = 0;
107443 p->pOffset = 0;
107444 pNew = sqlite3SelectDup(db, p, 0);
107445 sqlite3SelectSetName(pNew, pSub->zSelName);
107446 p->pOffset = pOffset;
107447 p->pLimit = pLimit;
107448 p->pOrderBy = pOrderBy;
107449 p->pSrc = pSrc;
107450 p->op = TK_ALL;
@@ -107290,10 +107453,13 @@
107453 }else{
107454 pNew->pPrior = pPrior;
107455 if( pPrior ) pPrior->pNext = pNew;
107456 pNew->pNext = p;
107457 p->pPrior = pNew;
107458 SELECTTRACE(2,pParse,p,
107459 ("compound-subquery flattener creates %s.%p as peer\n",
107460 pNew->zSelName, pNew));
107461 }
107462 if( db->mallocFailed ) return 1;
107463 }
107464
107465 /* Begin flattening the iFrom-th entry of the FROM clause
@@ -107419,12 +107585,27 @@
107585 if( isAgg ){
107586 substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
107587 pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
107588 }
107589 if( pSub->pOrderBy ){
107590 /* At this point, any non-zero iOrderByCol values indicate that the
107591 ** ORDER BY column expression is identical to the iOrderByCol'th
107592 ** expression returned by SELECT statement pSub. Since these values
107593 ** do not necessarily correspond to columns in SELECT statement pParent,
107594 ** zero them before transfering the ORDER BY clause.
107595 **
107596 ** Not doing this may cause an error if a subsequent call to this
107597 ** function attempts to flatten a compound sub-query into pParent
107598 ** (the only way this can happen is if the compound sub-query is
107599 ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */
107600 ExprList *pOrderBy = pSub->pOrderBy;
107601 for(i=0; i<pOrderBy->nExpr; i++){
107602 pOrderBy->a[i].u.x.iOrderByCol = 0;
107603 }
107604 assert( pParent->pOrderBy==0 );
107605 assert( pSub->pPrior==0 );
107606 pParent->pOrderBy = pOrderBy;
107607 pSub->pOrderBy = 0;
107608 }else if( pParent->pOrderBy ){
107609 substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
107610 }
107611 if( pSub->pWhere ){
@@ -107465,10 +107646,17 @@
107646
107647 /* Finially, delete what is left of the subquery and return
107648 ** success.
107649 */
107650 sqlite3SelectDelete(db, pSub1);
107651
107652 #if SELECTTRACE_ENABLED
107653 if( sqlite3SelectTrace & 0x100 ){
107654 sqlite3DebugPrintf("After flattening:\n");
107655 sqlite3TreeViewSelect(0, p, 0);
107656 }
107657 #endif
107658
107659 return 1;
107660 }
107661 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
107662
@@ -107936,10 +108124,11 @@
108124 if( pTab->pSelect || IsVirtual(pTab) ){
108125 /* We reach here if the named table is a really a view */
108126 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
108127 assert( pFrom->pSelect==0 );
108128 pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
108129 sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
108130 sqlite3WalkSelect(pWalker, pFrom->pSelect);
108131 }
108132 #endif
108133 }
108134
@@ -108470,10 +108659,17 @@
108659 if( p==0 || db->mallocFailed || pParse->nErr ){
108660 return 1;
108661 }
108662 if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
108663 memset(&sAggInfo, 0, sizeof(sAggInfo));
108664 #if SELECTTRACE_ENABLED
108665 pParse->nSelectIndent++;
108666 SELECTTRACE(1,pParse,p, ("begin processing:\n"));
108667 if( sqlite3SelectTrace & 0x100 ){
108668 sqlite3TreeViewSelect(0, p, 0);
108669 }
108670 #endif
108671
108672 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
108673 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
108674 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
108675 assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
@@ -108626,10 +108822,14 @@
108822 /* If there is are a sequence of queries, do the earlier ones first.
108823 */
108824 if( p->pPrior ){
108825 rc = multiSelect(pParse, p, pDest);
108826 explainSetInteger(pParse->iSelectId, iRestoreSelectId);
108827 #if SELECTTRACE_ENABLED
108828 SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
108829 pParse->nSelectIndent--;
108830 #endif
108831 return rc;
108832 }
108833 #endif
108834
108835 /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
@@ -108961,16 +109161,15 @@
109161 ** from the previous row currently stored in a0, a1, a2...
109162 */
109163 addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
109164 sqlite3ExprCacheClear(pParse);
109165 if( groupBySort ){
109166 sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
109167 }
109168 for(j=0; j<pGroupBy->nExpr; j++){
109169 if( groupBySort ){
109170 sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
 
109171 }else{
109172 sAggInfo.directMode = 1;
109173 sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
109174 }
109175 }
@@ -109225,107 +109424,110 @@
109424 generateColumnNames(pParse, pTabList, pEList);
109425 }
109426
109427 sqlite3DbFree(db, sAggInfo.aCol);
109428 sqlite3DbFree(db, sAggInfo.aFunc);
109429 #if SELECTTRACE_ENABLED
109430 SELECTTRACE(1,pParse,p,("end processing\n"));
109431 pParse->nSelectIndent--;
109432 #endif
109433 return rc;
109434 }
109435
109436 #ifdef SQLITE_DEBUG
109437 /*
109438 ** Generate a human-readable description of a the Select object.
109439 */
109440 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
109441 int n = 0;
109442 pView = sqlite3TreeViewPush(pView, moreToFollow);
109443 sqlite3TreeViewLine(pView, "SELECT%s%s",
109444 ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
109445 ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
109446 );
109447 if( p->pSrc && p->pSrc->nSrc ) n++;
109448 if( p->pWhere ) n++;
109449 if( p->pGroupBy ) n++;
109450 if( p->pHaving ) n++;
109451 if( p->pOrderBy ) n++;
109452 if( p->pLimit ) n++;
109453 if( p->pOffset ) n++;
109454 if( p->pPrior ) n++;
109455 sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
109456 if( p->pSrc && p->pSrc->nSrc ){
109457 int i;
109458 pView = sqlite3TreeViewPush(pView, (n--)>0);
109459 sqlite3TreeViewLine(pView, "FROM");
109460 for(i=0; i<p->pSrc->nSrc; i++){
109461 struct SrcList_item *pItem = &p->pSrc->a[i];
109462 StrAccum x;
109463 char zLine[100];
109464 sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
109465 sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
109466 if( pItem->zDatabase ){
109467 sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
109468 }else if( pItem->zName ){
109469 sqlite3XPrintf(&x, 0, " %s", pItem->zName);
109470 }
109471 if( pItem->pTab ){
109472 sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
109473 }
109474 if( pItem->zAlias ){
109475 sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
109476 }
109477 if( pItem->jointype & JT_LEFT ){
109478 sqlite3XPrintf(&x, 0, " LEFT-JOIN");
109479 }
109480 sqlite3StrAccumFinish(&x);
109481 sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
109482 if( pItem->pSelect ){
109483 sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
109484 }
109485 sqlite3TreeViewPop(pView);
109486 }
109487 sqlite3TreeViewPop(pView);
109488 }
109489 if( p->pWhere ){
109490 sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
109491 sqlite3TreeViewExpr(pView, p->pWhere, 0);
109492 sqlite3TreeViewPop(pView);
109493 }
109494 if( p->pGroupBy ){
109495 sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
 
 
109496 }
109497 if( p->pHaving ){
109498 sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
109499 sqlite3TreeViewExpr(pView, p->pHaving, 0);
109500 sqlite3TreeViewPop(pView);
109501 }
109502 if( p->pOrderBy ){
109503 sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
 
 
109504 }
109505 if( p->pLimit ){
109506 sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
109507 sqlite3TreeViewExpr(pView, p->pLimit, 0);
109508 sqlite3TreeViewPop(pView);
109509 }
109510 if( p->pOffset ){
109511 sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
109512 sqlite3TreeViewExpr(pView, p->pOffset, 0);
109513 sqlite3TreeViewPop(pView);
109514 }
109515 if( p->pPrior ){
109516 const char *zOp = "UNION";
109517 switch( p->op ){
109518 case TK_ALL: zOp = "UNION ALL"; break;
109519 case TK_INTERSECT: zOp = "INTERSECT"; break;
109520 case TK_EXCEPT: zOp = "EXCEPT"; break;
109521 }
109522 sqlite3TreeViewItem(pView, zOp, (n--)>0);
109523 sqlite3TreeViewSelect(pView, p->pPrior, 0);
109524 sqlite3TreeViewPop(pView);
109525 }
109526 sqlite3TreeViewPop(pView);
109527 }
109528 #endif /* SQLITE_DEBUG */
 
 
 
 
 
 
 
109529
109530 /************** End of select.c **********************************************/
109531 /************** Begin file table.c *******************************************/
109532 /*
109533 ** 2001 September 15
@@ -112311,10 +112513,11 @@
112513 }
112514 sqlite3DbFree(db, pVTable);
112515 }else if( ALWAYS(pVTable->pVtab) ){
112516 /* Justification of ALWAYS(): A correct vtab constructor must allocate
112517 ** the sqlite3_vtab object if successful. */
112518 memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
112519 pVTable->pVtab->pModule = pMod->pModule;
112520 pVTable->nRef = 1;
112521 if( sCtx.pTab ){
112522 const char *zFormat = "vtable constructor did not declare schema: %s";
112523 *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
@@ -113719,15 +113922,10 @@
113922 assert( TK_LE>TK_EQ && TK_LE<TK_GE );
113923 assert( TK_GE==TK_EQ+4 );
113924 return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
113925 }
113926
 
 
 
 
 
113927 /*
113928 ** Commute a comparison operator. Expressions of the form "X op Y"
113929 ** are converted into "Y op X".
113930 **
113931 ** If left/right precedence rules come into play when determining the
@@ -115566,21 +115764,28 @@
115764 ** have been requested when testing key $P in whereEqualScanEst(). */
115765 whereKeyStats(pParse, p, pRec, 0, a);
115766 iLower = a[0];
115767 iUpper = a[0] + a[1];
115768 }
115769
115770 assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
115771 assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
115772 assert( p->aSortOrder!=0 );
115773 if( p->aSortOrder[nEq] ){
115774 /* The roles of pLower and pUpper are swapped for a DESC index */
115775 SWAP(WhereTerm*, pLower, pUpper);
115776 }
115777
115778 /* If possible, improve on the iLower estimate using ($P:$L). */
115779 if( pLower ){
115780 int bOk; /* True if value is extracted from pExpr */
115781 Expr *pExpr = pLower->pExpr->pRight;
 
115782 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115783 if( rc==SQLITE_OK && bOk ){
115784 tRowcnt iNew;
115785 whereKeyStats(pParse, p, pRec, 0, a);
115786 iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115787 if( iNew>iLower ) iLower = iNew;
115788 nOut--;
115789 pLower = 0;
115790 }
115791 }
@@ -115587,16 +115792,15 @@
115792
115793 /* If possible, improve on the iUpper estimate using ($P:$U). */
115794 if( pUpper ){
115795 int bOk; /* True if value is extracted from pExpr */
115796 Expr *pExpr = pUpper->pExpr->pRight;
 
115797 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
115798 if( rc==SQLITE_OK && bOk ){
115799 tRowcnt iNew;
115800 whereKeyStats(pParse, p, pRec, 1, a);
115801 iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
115802 if( iNew<iUpper ) iUpper = iNew;
115803 nOut--;
115804 pUpper = 0;
115805 }
115806 }
@@ -116091,65 +116295,52 @@
116295 sqlite3StrAccumAppend(pStr, "?", 1);
116296 }
116297
116298 /*
116299 ** Argument pLevel describes a strategy for scanning table pTab. This
116300 ** function appends text to pStr that describes the subset of table
116301 ** rows scanned by the strategy in the form of an SQL expression.
 
116302 **
116303 ** For example, if the query:
116304 **
116305 ** SELECT * FROM t1 WHERE a=1 AND b>2;
116306 **
116307 ** is run and there is an index on (a, b), then this function returns a
116308 ** string similar to:
116309 **
116310 ** "a=? AND b>?"
 
 
 
 
116311 */
116312 static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
116313 Index *pIndex = pLoop->u.btree.pIndex;
116314 u16 nEq = pLoop->u.btree.nEq;
116315 u16 nSkip = pLoop->u.btree.nSkip;
116316 int i, j;
116317 Column *aCol = pTab->aCol;
116318 i16 *aiColumn = pIndex->aiColumn;
116319
116320 if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
116321 sqlite3StrAccumAppend(pStr, " (", 2);
 
 
 
 
 
116322 for(i=0; i<nEq; i++){
116323 char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
116324 if( i>=nSkip ){
116325 explainAppendTerm(pStr, i, z, "=");
116326 }else{
116327 if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
116328 sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
 
 
116329 }
116330 }
116331
116332 j = i;
116333 if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
116334 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116335 explainAppendTerm(pStr, i++, z, ">");
116336 }
116337 if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
116338 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
116339 explainAppendTerm(pStr, i, z, "<");
116340 }
116341 sqlite3StrAccumAppend(pStr, ")", 1);
 
116342 }
116343
116344 /*
116345 ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
116346 ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
@@ -116169,72 +116360,90 @@
116360 #endif
116361 {
116362 struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
116363 Vdbe *v = pParse->pVdbe; /* VM being constructed */
116364 sqlite3 *db = pParse->db; /* Database handle */
 
116365 int iId = pParse->iSelectId; /* Select id (left-most output column) */
116366 int isSearch; /* True for a SEARCH. False for SCAN. */
116367 WhereLoop *pLoop; /* The controlling WhereLoop object */
116368 u32 flags; /* Flags that describe this loop */
116369 char *zMsg; /* Text to add to EQP output */
116370 StrAccum str; /* EQP output string */
116371 char zBuf[100]; /* Initial space for EQP output string */
116372
116373 pLoop = pLevel->pWLoop;
116374 flags = pLoop->wsFlags;
116375 if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
116376
116377 isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
116378 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
116379 || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
116380
116381 sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
116382 str.db = db;
116383 sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
116384 if( pItem->pSelect ){
116385 sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
116386 }else{
116387 sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
116388 }
116389
116390 if( pItem->zAlias ){
116391 sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
116392 }
116393 if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
116394 const char *zFmt = 0;
116395 Index *pIdx;
116396
116397 assert( pLoop->u.btree.pIndex!=0 );
116398 pIdx = pLoop->u.btree.pIndex;
116399 assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
116400 if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
116401 if( isSearch ){
116402 zFmt = "PRIMARY KEY";
116403 }
116404 }else if( flags & WHERE_AUTO_INDEX ){
116405 zFmt = "AUTOMATIC COVERING INDEX";
116406 }else if( flags & WHERE_IDX_ONLY ){
116407 zFmt = "COVERING INDEX %s";
116408 }else{
116409 zFmt = "INDEX %s";
116410 }
116411 if( zFmt ){
116412 sqlite3StrAccumAppend(&str, " USING ", 7);
116413 sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
116414 explainIndexRange(&str, pLoop, pItem->pTab);
116415 }
116416 }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
116417 const char *zRange;
 
116418 if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
116419 zRange = "(rowid=?)";
116420 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
116421 zRange = "(rowid>? AND rowid<?)";
116422 }else if( flags&WHERE_BTM_LIMIT ){
116423 zRange = "(rowid>?)";
116424 }else{
116425 assert( flags&WHERE_TOP_LIMIT);
116426 zRange = "(rowid<?)";
116427 }
116428 sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
116429 sqlite3StrAccumAppendAll(&str, zRange);
116430 }
116431 #ifndef SQLITE_OMIT_VIRTUALTABLE
116432 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
116433 sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
116434 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
116435 }
116436 #endif
116437 #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
116438 if( pLoop->nOut>=10 ){
116439 sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
116440 }else{
116441 sqlite3StrAccumAppend(&str, " (~1 row)", 9);
116442 }
116443 #endif
116444 zMsg = sqlite3StrAccumFinish(&str);
116445 sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
116446 }
116447 }
116448 #else
116449 # define explainOneScan(u,v,w,x,y,z)
@@ -116884,12 +117093,13 @@
117093
117094 /* Run a separate WHERE clause for each term of the OR clause. After
117095 ** eliminating duplicates from other WHERE clauses, the action for each
117096 ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
117097 */
117098 wctrlFlags = WHERE_OMIT_OPEN_CLOSE
117099 | WHERE_FORCE_TABLE
117100 | WHERE_ONETABLE_ONLY;
117101 for(ii=0; ii<pOrWc->nTerm; ii++){
117102 WhereTerm *pOrTerm = &pOrWc->a[ii];
117103 if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
117104 WhereInfo *pSubWInfo; /* Info for single OR-term scan */
117105 Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
@@ -116897,10 +117107,11 @@
117107 if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
117108 pAndExpr->pLeft = pOrExpr;
117109 pOrExpr = pAndExpr;
117110 }
117111 /* Loop through table entries that match term pOrTerm. */
117112 WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
117113 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
117114 wctrlFlags, iCovCur);
117115 assert( pSubWInfo || pParse->nErr || db->mallocFailed );
117116 if( pSubWInfo ){
117117 WhereLoop *pSubLoop;
@@ -117116,25 +117327,30 @@
117327 }
117328
117329 return pLevel->notReady;
117330 }
117331
117332 #ifdef WHERETRACE_ENABLED
117333 /*
117334 ** Print the content of a WhereTerm object
117335 */
117336 static void whereTermPrint(WhereTerm *pTerm, int iTerm){
117337 if( pTerm==0 ){
117338 sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
117339 }else{
117340 char zType[4];
117341 memcpy(zType, "...", 4);
117342 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
117343 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
117344 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
117345 sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
117346 iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
117347 pTerm->eOperator);
117348 sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
117349 }
117350 }
117351 #endif
117352
117353 #ifdef WHERETRACE_ENABLED
117354 /*
117355 ** Print a WhereLoop object for debugging purposes
117356 */
@@ -117174,31 +117390,16 @@
117390 sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
117391 }else{
117392 sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
117393 }
117394 sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
117395 if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
 
 
 
 
117396 int i;
 
 
117397 for(i=0; i<p->nLTerm; i++){
117398 whereTermPrint(p->aLTerm[i], i);
117399 }
117400 }
 
 
 
 
 
 
 
 
 
117401 }
117402 #endif
117403
117404 /*
117405 ** Convert bulk memory into a valid WhereLoop that can be passed
@@ -117507,11 +117708,11 @@
117708 if( ppPrev==0 ){
117709 /* There already exists a WhereLoop on the list that is better
117710 ** than pTemplate, so just ignore pTemplate */
117711 #if WHERETRACE_ENABLED /* 0x8 */
117712 if( sqlite3WhereTrace & 0x8 ){
117713 sqlite3DebugPrintf(" skip: ");
117714 whereLoopPrint(pTemplate, pBuilder->pWC);
117715 }
117716 #endif
117717 return SQLITE_OK;
117718 }else{
@@ -117523,14 +117724,14 @@
117724 ** WhereLoop and insert it.
117725 */
117726 #if WHERETRACE_ENABLED /* 0x8 */
117727 if( sqlite3WhereTrace & 0x8 ){
117728 if( p!=0 ){
117729 sqlite3DebugPrintf("replace: ");
117730 whereLoopPrint(p, pBuilder->pWC);
117731 }
117732 sqlite3DebugPrintf(" add: ");
117733 whereLoopPrint(pTemplate, pBuilder->pWC);
117734 }
117735 #endif
117736 if( p==0 ){
117737 /* Allocate a new WhereLoop to add to the end of the list */
@@ -117550,11 +117751,11 @@
117751 pToDel = *ppTail;
117752 if( pToDel==0 ) break;
117753 *ppTail = pToDel->pNextLoop;
117754 #if WHERETRACE_ENABLED /* 0x8 */
117755 if( sqlite3WhereTrace & 0x8 ){
117756 sqlite3DebugPrintf(" delete: ");
117757 whereLoopPrint(pToDel, pBuilder->pWC);
117758 }
117759 #endif
117760 whereLoopDelete(db, pToDel);
117761 }
@@ -117714,15 +117915,18 @@
117915 pNew->aLTerm[pNew->nLTerm++] = 0;
117916 pNew->wsFlags |= WHERE_SKIPSCAN;
117917 nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
117918 if( pTerm ){
117919 /* TUNING: When estimating skip-scan for a term that is also indexable,
117920 ** multiply the cost of the skip-scan by 2.0, to make it a little less
117921 ** desirable than the regular index lookup. */
117922 nIter += 10; assert( 10==sqlite3LogEst(2) );
117923 }
117924 pNew->nOut -= nIter;
117925 /* TUNING: Because uncertainties in the estimates for skip-scan queries,
117926 ** add a 1.375 fudge factor to make skip-scan slightly less likely. */
117927 nIter += 5;
117928 whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
117929 pNew->nOut = saved_nOut;
117930 pNew->u.btree.nEq = saved_nEq;
117931 pNew->u.btree.nSkip = saved_nSkip;
117932 }
@@ -118073,13 +118277,21 @@
118277 pNew->u.btree.nSkip = 0;
118278 pNew->u.btree.pIndex = 0;
118279 pNew->nLTerm = 1;
118280 pNew->aLTerm[0] = pTerm;
118281 /* TUNING: One-time cost for computing the automatic index is
118282 ** estimated to be X*N*log2(N) where N is the number of rows in
118283 ** the table being indexed and where X is 7 (LogEst=28) for normal
118284 ** tables or 1.375 (LogEst=4) for views and subqueries. The value
118285 ** of X is smaller for views and subqueries so that the query planner
118286 ** will be more aggressive about generating automatic indexes for
118287 ** those objects, since there is no opportunity to add schema
118288 ** indexes on subqueries and views. */
118289 pNew->rSetup = rLogSize + rSize + 4;
118290 if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
118291 pNew->rSetup += 24;
118292 }
118293 ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
118294 /* TUNING: Each index lookup yields 20 rows in the table. This
118295 ** is more than the usual guess of 10 rows, since we have no way
118296 ** of knowing how selective the index will ultimately be. It would
118297 ** not be unreasonable to make this value much larger. */
@@ -118363,11 +118575,10 @@
118575 WhereLoopBuilder sSubBuild;
118576 WhereOrSet sSum, sCur;
118577 struct SrcList_item *pItem;
118578
118579 pWC = pBuilder->pWC;
 
118580 pWCEnd = pWC->a + pWC->nTerm;
118581 pNew = pBuilder->pNew;
118582 memset(&sSum, 0, sizeof(sSum));
118583 pItem = pWInfo->pTabList->a + pNew->iTab;
118584 iCur = pItem->iCursor;
@@ -118384,10 +118595,11 @@
118595
118596 sSubBuild = *pBuilder;
118597 sSubBuild.pOrderBy = 0;
118598 sSubBuild.pOrSet = &sCur;
118599
118600 WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
118601 for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
118602 if( (pOrTerm->eOperator & WO_AND)!=0 ){
118603 sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
118604 }else if( pOrTerm->leftCursor==iCur ){
118605 tempWC.pWInfo = pWC->pWInfo;
@@ -118398,18 +118610,30 @@
118610 sSubBuild.pWC = &tempWC;
118611 }else{
118612 continue;
118613 }
118614 sCur.n = 0;
118615 #ifdef WHERETRACE_ENABLED
118616 WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n",
118617 (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
118618 if( sqlite3WhereTrace & 0x400 ){
118619 for(i=0; i<sSubBuild.pWC->nTerm; i++){
118620 whereTermPrint(&sSubBuild.pWC->a[i], i);
118621 }
118622 }
118623 #endif
118624 #ifndef SQLITE_OMIT_VIRTUALTABLE
118625 if( IsVirtual(pItem->pTab) ){
118626 rc = whereLoopAddVirtual(&sSubBuild, mExtra);
118627 }else
118628 #endif
118629 {
118630 rc = whereLoopAddBtree(&sSubBuild, mExtra);
118631 }
118632 if( rc==SQLITE_OK ){
118633 rc = whereLoopAddOr(&sSubBuild, mExtra);
118634 }
118635 assert( rc==SQLITE_OK || sCur.n==0 );
118636 if( sCur.n==0 ){
118637 sSum.n = 0;
118638 break;
118639 }else if( once ){
@@ -118450,10 +118674,11 @@
118674 pNew->rRun = sSum.a[i].rRun + 1;
118675 pNew->nOut = sSum.a[i].nOut;
118676 pNew->prereq = sSum.a[i].prereq;
118677 rc = whereLoopInsert(pBuilder, pNew);
118678 }
118679 WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm));
118680 }
118681 }
118682 return rc;
118683 }
118684
@@ -118693,11 +118918,11 @@
118918 if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
118919 }
118920 isMatch = 1;
118921 break;
118922 }
118923 if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
118924 /* Make sure the sort order is compatible in an ORDER BY clause.
118925 ** Sort order is irrelevant for a GROUP BY clause. */
118926 if( revSet ){
118927 if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
118928 }else{
@@ -119158,16 +119383,19 @@
119383 pWInfo->revMask = pFrom->revLoop;
119384 }
119385 if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
119386 && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
119387 ){
119388 Bitmask revMask = 0;
119389 int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
119390 pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
119391 );
119392 assert( pWInfo->sorted==0 );
119393 if( nOrder==pWInfo->pOrderBy->nExpr ){
119394 pWInfo->sorted = 1;
119395 pWInfo->revMask = revMask;
119396 }
119397 }
119398 }
119399
119400
119401 pWInfo->nRowOut = pFrom->nRow;
@@ -119516,27 +119744,20 @@
119744 }
119745 }
119746
119747 /* Construct the WhereLoop objects */
119748 WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
119749 #if defined(WHERETRACE_ENABLED)
119750 /* Display all terms of the WHERE clause */
 
119751 if( sqlite3WhereTrace & 0x100 ){
119752 int i;
 
 
119753 for(i=0; i<sWLB.pWC->nTerm; i++){
119754 whereTermPrint(&sWLB.pWC->a[i], i);
119755 }
 
 
 
 
 
 
119756 }
119757 #endif
119758
119759 if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
119760 rc = whereLoopAddAll(&sWLB);
119761 if( rc ) goto whereBeginError;
119762
119763 /* Display all of the WhereLoop objects if wheretrace is enabled */
@@ -120059,11 +120280,11 @@
120280
120281 /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
120282 ** unary TK_ISNULL or TK_NOTNULL expression. */
120283 static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
120284 sqlite3 *db = pParse->db;
120285 if( pY && pA && pY->op==TK_NULL ){
120286 pA->op = (u8)op;
120287 sqlite3ExprDelete(db, pA->pRight);
120288 pA->pRight = 0;
120289 }
120290 }
@@ -122318,13 +122539,10 @@
122539 break;
122540 case 111: /* cmd ::= select */
122541 {
122542 SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
122543 sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
 
 
 
122544 sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
122545 }
122546 break;
122547 case 112: /* select ::= with selectnowith */
122548 {
@@ -122377,10 +122595,34 @@
122595 {yygotominor.yy328 = TK_ALL;}
122596 break;
122597 case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
122598 {
122599 yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
122600 #if SELECTTRACE_ENABLED
122601 /* Populate the Select.zSelName[] string that is used to help with
122602 ** query planner debugging, to differentiate between multiple Select
122603 ** objects in a complex query.
122604 **
122605 ** If the SELECT keyword is immediately followed by a C-style comment
122606 ** then extract the first few alphanumeric characters from within that
122607 ** comment to be the zSelName value. Otherwise, the label is #N where
122608 ** is an integer that is incremented with each SELECT statement seen.
122609 */
122610 if( yygotominor.yy3!=0 ){
122611 const char *z = yymsp[-8].minor.yy0.z+6;
122612 int i;
122613 sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "#%d",
122614 ++pParse->nSelect);
122615 while( z[0]==' ' ) z++;
122616 if( z[0]=='/' && z[1]=='*' ){
122617 z += 2;
122618 while( z[0]==' ' ) z++;
122619 for(i=0; sqlite3Isalnum(z[i]); i++){}
122620 sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "%.*s", i, z);
122621 }
122622 }
122623 #endif /* SELECTRACE_ENABLED */
122624 }
122625 break;
122626 case 120: /* values ::= VALUES LP nexprlist RP */
122627 {
122628 yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
@@ -123868,10 +124110,11 @@
124110 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */
124111 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */
124112 };
124113 #define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
124114 #endif
124115 SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
124116
124117
124118 /*
124119 ** Return the length of the token that begins at z[0].
124120 ** Store the token type in *tokenType before returning.
@@ -125138,10 +125381,15 @@
125381 sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
125382 sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
125383 break;
125384 }
125385
125386 /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames
125387 ** can be changed at start-time using the
125388 ** sqlite3_config(SQLITE_CONFIG_URI,1) or
125389 ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls.
125390 */
125391 case SQLITE_CONFIG_URI: {
125392 sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
125393 break;
125394 }
125395
@@ -126875,11 +127123,11 @@
127123 int nUri = sqlite3Strlen30(zUri);
127124
127125 assert( *pzErrMsg==0 );
127126
127127 if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
127128 && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
127129 ){
127130 char *zOpt;
127131 int eState; /* Parser state when parsing URI */
127132 int iIn; /* Input character index */
127133 int iOut = 0; /* Output character index */
@@ -127105,11 +127353,13 @@
127353 assert( SQLITE_OPEN_READWRITE == 0x02 );
127354 assert( SQLITE_OPEN_CREATE == 0x04 );
127355 testcase( (1<<(flags&7))==0x02 ); /* READONLY */
127356 testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
127357 testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
127358 if( ((1<<(flags&7)) & 0x46)==0 ){
127359 return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */
127360 }
127361
127362 if( sqlite3GlobalConfig.bCoreMutex==0 ){
127363 isThreadsafe = 0;
127364 }else if( flags & SQLITE_OPEN_NOMUTEX ){
127365 isThreadsafe = 0;
@@ -127989,26 +128239,10 @@
128239 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
128240 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
128241 break;
128242 }
128243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128244 /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
128245 **
128246 ** Set or clear a flag that indicates that the database file is always well-
128247 ** formed and never corrupt. This flag is clear by default, indicating that
128248 ** database files might have arbitrary corruption. Setting the flag during
@@ -132464,10 +132698,11 @@
132698 assert( iIdx==nVal );
132699
132700 /* In case the cursor has been used before, clear it now. */
132701 sqlite3_finalize(pCsr->pStmt);
132702 sqlite3_free(pCsr->aDoclist);
132703 sqlite3_free(pCsr->aMatchinfo);
132704 sqlite3Fts3ExprFree(pCsr->pExpr);
132705 memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
132706
132707 /* Set the lower and upper bounds on docids to return */
132708 pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -133774,11 +134009,11 @@
134009 if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
134010 iMax = a[i].iDocid;
134011 bMaxSet = 1;
134012 }
134013 }
134014 assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
134015 assert( rc!=SQLITE_OK || bMaxSet );
134016
134017 /* Keep advancing iterators until they all point to the same document */
134018 for(i=0; i<p->nToken; i++){
134019 while( rc==SQLITE_OK && bEof==0
@@ -135891,11 +136126,11 @@
136126 int i = 0;
136127
136128 /* Set variable i to the maximum number of bytes of input to tokenize. */
136129 for(i=0; i<n; i++){
136130 if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
136131 if( z[i]=='"' ) break;
136132 }
136133
136134 *pnConsumed = i;
136135 rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
136136 if( rc==SQLITE_OK ){
136137
+16 -18
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.8.7"
111111
#define SQLITE_VERSION_NUMBER 3008007
112
-#define SQLITE_SOURCE_ID "2014-09-20 00:35:05 59e2c9df02d7e988c5ad44c560ead1e5288b12e7"
112
+#define SQLITE_SOURCE_ID "2014-10-17 11:24:17 e4ab094f8afce0817f4074e823fabe59fc29ebb4"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -2667,13 +2667,13 @@
26672667
** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
26682668
** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
26692669
** an English language description of the error following a failure of any
26702670
** of the sqlite3_open() routines.
26712671
**
2672
-** ^The default encoding for the database will be UTF-8 if
2673
-** sqlite3_open() or sqlite3_open_v2() is called and
2674
-** UTF-16 in the native byte order if sqlite3_open16() is used.
2672
+** ^The default encoding will be UTF-8 for databases created using
2673
+** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases
2674
+** created using sqlite3_open16() will be UTF-16 in the native byte order.
26752675
**
26762676
** Whether or not an error occurs when it is opened, resources
26772677
** associated with the [database connection] handle should be released by
26782678
** passing it to [sqlite3_close()] when it is no longer required.
26792679
**
@@ -2757,17 +2757,18 @@
27572757
** ^SQLite uses the path component of the URI as the name of the disk file
27582758
** which contains the database. ^If the path begins with a '/' character,
27592759
** then it is interpreted as an absolute path. ^If the path does not begin
27602760
** with a '/' (meaning that the authority section is omitted from the URI)
27612761
** then the path is interpreted as a relative path.
2762
-** ^On windows, the first component of an absolute path
2763
-** is a drive specification (e.g. "C:").
2762
+** ^(On windows, the first component of an absolute path
2763
+** is a drive specification (e.g. "C:").)^
27642764
**
27652765
** [[core URI query parameters]]
27662766
** The query component of a URI may contain parameters that are interpreted
27672767
** either by SQLite itself, or by a [VFS | custom VFS implementation].
2768
-** SQLite interprets the following three query parameters:
2768
+** SQLite and its built-in [VFSes] interpret the
2769
+** following query parameters:
27692770
**
27702771
** <ul>
27712772
** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
27722773
** a VFS object that provides the operating system interface that should
27732774
** be used to access the database file on disk. ^If this option is set to
@@ -2798,15 +2799,13 @@
27982799
** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
27992800
** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
28002801
** a URI filename, its value overrides any behavior requested by setting
28012802
** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
28022803
**
2803
-** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
2804
-** "1") or "false" (or "off" or "no" or "0") to indicate that the
2804
+** <li> <b>psow</b>: ^The psow parameter indicates whether or not the
28052805
** [powersafe overwrite] property does or does not apply to the
2806
-** storage media on which the database file resides. ^The psow query
2807
-** parameter only works for the built-in unix and Windows VFSes.
2806
+** storage media on which the database file resides.
28082807
**
28092808
** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
28102809
** which if set disables file locking in rollback journal modes. This
28112810
** is useful for accessing a database on a filesystem that does not
28122811
** support locking. Caution: Database corruption might result if two
@@ -3397,15 +3396,14 @@
33973396
** terminated. If any NUL characters occur at byte offsets less than
33983397
** the value of the fourth parameter then the resulting string value will
33993398
** contain embedded NULs. The result of expressions involving strings
34003399
** with embedded NULs is undefined.
34013400
**
3402
-** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3403
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3401
+** ^The fifth argument to the BLOB and string binding interfaces
3402
+** is a destructor used to dispose of the BLOB or
34043403
** string after SQLite has finished with it. ^The destructor is called
3405
-** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
3406
-** sqlite3_bind_text(), or sqlite3_bind_text16() fails.
3404
+** to dispose of the BLOB or string even if the call to bind API fails.
34073405
** ^If the fifth argument is
34083406
** the special value [SQLITE_STATIC], then SQLite assumes that the
34093407
** information is in static, unmanaged space and does not need to be freed.
34103408
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
34113409
** SQLite makes its own private copy of the data immediately, before
@@ -3412,11 +3410,11 @@
34123410
** the sqlite3_bind_*() routine returns.
34133411
**
34143412
** ^The sixth argument to sqlite3_bind_text64() must be one of
34153413
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
34163414
** to specify the encoding of the text in the third parameter. If
3417
-** the sixth argument to sqlite3_bind_text64() is not how of the
3415
+** the sixth argument to sqlite3_bind_text64() is not one of the
34183416
** allowed values shown above, or if the text encoding is different
34193417
** from the encoding specified by the sixth parameter, then the behavior
34203418
** is undefined.
34213419
**
34223420
** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
@@ -4448,11 +4446,11 @@
44484446
**
44494447
** ^The sqlite3_result_null() interface sets the return value
44504448
** of the application-defined function to be NULL.
44514449
**
44524450
** ^The sqlite3_result_text(), sqlite3_result_text16(),
4453
-** sqlite3_result_text16le(), and sqlite3_result_text16be()
4451
+** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
44544452
** set the return value of the application-defined function to be
44554453
** a text string which is represented as UTF-8, UTF-16 native byte order,
44564454
** UTF-16 little endian, or UTF-16 big endian, respectively.
44574455
** ^The sqlite3_result_text64() interface sets the return value of an
44584456
** application-defined function to be a text string in an encoding
@@ -6208,11 +6206,11 @@
62086206
#define SQLITE_TESTCTRL_RESERVE 14
62096207
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
62106208
#define SQLITE_TESTCTRL_ISKEYWORD 16
62116209
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
62126210
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
6213
-#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
6211
+#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
62146212
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
62156213
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
62166214
#define SQLITE_TESTCTRL_BYTEORDER 22
62176215
#define SQLITE_TESTCTRL_ISINIT 23
62186216
#define SQLITE_TESTCTRL_SORTER_MMAP 24
62196217
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.8.7"
111 #define SQLITE_VERSION_NUMBER 3008007
112 #define SQLITE_SOURCE_ID "2014-09-20 00:35:05 59e2c9df02d7e988c5ad44c560ead1e5288b12e7"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -2667,13 +2667,13 @@
2667 ** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
2668 ** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
2669 ** an English language description of the error following a failure of any
2670 ** of the sqlite3_open() routines.
2671 **
2672 ** ^The default encoding for the database will be UTF-8 if
2673 ** sqlite3_open() or sqlite3_open_v2() is called and
2674 ** UTF-16 in the native byte order if sqlite3_open16() is used.
2675 **
2676 ** Whether or not an error occurs when it is opened, resources
2677 ** associated with the [database connection] handle should be released by
2678 ** passing it to [sqlite3_close()] when it is no longer required.
2679 **
@@ -2757,17 +2757,18 @@
2757 ** ^SQLite uses the path component of the URI as the name of the disk file
2758 ** which contains the database. ^If the path begins with a '/' character,
2759 ** then it is interpreted as an absolute path. ^If the path does not begin
2760 ** with a '/' (meaning that the authority section is omitted from the URI)
2761 ** then the path is interpreted as a relative path.
2762 ** ^On windows, the first component of an absolute path
2763 ** is a drive specification (e.g. "C:").
2764 **
2765 ** [[core URI query parameters]]
2766 ** The query component of a URI may contain parameters that are interpreted
2767 ** either by SQLite itself, or by a [VFS | custom VFS implementation].
2768 ** SQLite interprets the following three query parameters:
 
2769 **
2770 ** <ul>
2771 ** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
2772 ** a VFS object that provides the operating system interface that should
2773 ** be used to access the database file on disk. ^If this option is set to
@@ -2798,15 +2799,13 @@
2798 ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
2799 ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
2800 ** a URI filename, its value overrides any behavior requested by setting
2801 ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
2802 **
2803 ** <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
2804 ** "1") or "false" (or "off" or "no" or "0") to indicate that the
2805 ** [powersafe overwrite] property does or does not apply to the
2806 ** storage media on which the database file resides. ^The psow query
2807 ** parameter only works for the built-in unix and Windows VFSes.
2808 **
2809 ** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
2810 ** which if set disables file locking in rollback journal modes. This
2811 ** is useful for accessing a database on a filesystem that does not
2812 ** support locking. Caution: Database corruption might result if two
@@ -3397,15 +3396,14 @@
3397 ** terminated. If any NUL characters occur at byte offsets less than
3398 ** the value of the fourth parameter then the resulting string value will
3399 ** contain embedded NULs. The result of expressions involving strings
3400 ** with embedded NULs is undefined.
3401 **
3402 ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3403 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3404 ** string after SQLite has finished with it. ^The destructor is called
3405 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
3406 ** sqlite3_bind_text(), or sqlite3_bind_text16() fails.
3407 ** ^If the fifth argument is
3408 ** the special value [SQLITE_STATIC], then SQLite assumes that the
3409 ** information is in static, unmanaged space and does not need to be freed.
3410 ** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
3411 ** SQLite makes its own private copy of the data immediately, before
@@ -3412,11 +3410,11 @@
3412 ** the sqlite3_bind_*() routine returns.
3413 **
3414 ** ^The sixth argument to sqlite3_bind_text64() must be one of
3415 ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
3416 ** to specify the encoding of the text in the third parameter. If
3417 ** the sixth argument to sqlite3_bind_text64() is not how of the
3418 ** allowed values shown above, or if the text encoding is different
3419 ** from the encoding specified by the sixth parameter, then the behavior
3420 ** is undefined.
3421 **
3422 ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
@@ -4448,11 +4446,11 @@
4448 **
4449 ** ^The sqlite3_result_null() interface sets the return value
4450 ** of the application-defined function to be NULL.
4451 **
4452 ** ^The sqlite3_result_text(), sqlite3_result_text16(),
4453 ** sqlite3_result_text16le(), and sqlite3_result_text16be()
4454 ** set the return value of the application-defined function to be
4455 ** a text string which is represented as UTF-8, UTF-16 native byte order,
4456 ** UTF-16 little endian, or UTF-16 big endian, respectively.
4457 ** ^The sqlite3_result_text64() interface sets the return value of an
4458 ** application-defined function to be a text string in an encoding
@@ -6208,11 +6206,11 @@
6208 #define SQLITE_TESTCTRL_RESERVE 14
6209 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
6210 #define SQLITE_TESTCTRL_ISKEYWORD 16
6211 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17
6212 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
6213 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19
6214 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
6215 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
6216 #define SQLITE_TESTCTRL_BYTEORDER 22
6217 #define SQLITE_TESTCTRL_ISINIT 23
6218 #define SQLITE_TESTCTRL_SORTER_MMAP 24
6219
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.8.7"
111 #define SQLITE_VERSION_NUMBER 3008007
112 #define SQLITE_SOURCE_ID "2014-10-17 11:24:17 e4ab094f8afce0817f4074e823fabe59fc29ebb4"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -2667,13 +2667,13 @@
2667 ** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
2668 ** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
2669 ** an English language description of the error following a failure of any
2670 ** of the sqlite3_open() routines.
2671 **
2672 ** ^The default encoding will be UTF-8 for databases created using
2673 ** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases
2674 ** created using sqlite3_open16() will be UTF-16 in the native byte order.
2675 **
2676 ** Whether or not an error occurs when it is opened, resources
2677 ** associated with the [database connection] handle should be released by
2678 ** passing it to [sqlite3_close()] when it is no longer required.
2679 **
@@ -2757,17 +2757,18 @@
2757 ** ^SQLite uses the path component of the URI as the name of the disk file
2758 ** which contains the database. ^If the path begins with a '/' character,
2759 ** then it is interpreted as an absolute path. ^If the path does not begin
2760 ** with a '/' (meaning that the authority section is omitted from the URI)
2761 ** then the path is interpreted as a relative path.
2762 ** ^(On windows, the first component of an absolute path
2763 ** is a drive specification (e.g. "C:").)^
2764 **
2765 ** [[core URI query parameters]]
2766 ** The query component of a URI may contain parameters that are interpreted
2767 ** either by SQLite itself, or by a [VFS | custom VFS implementation].
2768 ** SQLite and its built-in [VFSes] interpret the
2769 ** following query parameters:
2770 **
2771 ** <ul>
2772 ** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
2773 ** a VFS object that provides the operating system interface that should
2774 ** be used to access the database file on disk. ^If this option is set to
@@ -2798,15 +2799,13 @@
2799 ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
2800 ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
2801 ** a URI filename, its value overrides any behavior requested by setting
2802 ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
2803 **
2804 ** <li> <b>psow</b>: ^The psow parameter indicates whether or not the
 
2805 ** [powersafe overwrite] property does or does not apply to the
2806 ** storage media on which the database file resides.
 
2807 **
2808 ** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
2809 ** which if set disables file locking in rollback journal modes. This
2810 ** is useful for accessing a database on a filesystem that does not
2811 ** support locking. Caution: Database corruption might result if two
@@ -3397,15 +3396,14 @@
3396 ** terminated. If any NUL characters occur at byte offsets less than
3397 ** the value of the fourth parameter then the resulting string value will
3398 ** contain embedded NULs. The result of expressions involving strings
3399 ** with embedded NULs is undefined.
3400 **
3401 ** ^The fifth argument to the BLOB and string binding interfaces
3402 ** is a destructor used to dispose of the BLOB or
3403 ** string after SQLite has finished with it. ^The destructor is called
3404 ** to dispose of the BLOB or string even if the call to bind API fails.
 
3405 ** ^If the fifth argument is
3406 ** the special value [SQLITE_STATIC], then SQLite assumes that the
3407 ** information is in static, unmanaged space and does not need to be freed.
3408 ** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
3409 ** SQLite makes its own private copy of the data immediately, before
@@ -3412,11 +3410,11 @@
3410 ** the sqlite3_bind_*() routine returns.
3411 **
3412 ** ^The sixth argument to sqlite3_bind_text64() must be one of
3413 ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
3414 ** to specify the encoding of the text in the third parameter. If
3415 ** the sixth argument to sqlite3_bind_text64() is not one of the
3416 ** allowed values shown above, or if the text encoding is different
3417 ** from the encoding specified by the sixth parameter, then the behavior
3418 ** is undefined.
3419 **
3420 ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
@@ -4448,11 +4446,11 @@
4446 **
4447 ** ^The sqlite3_result_null() interface sets the return value
4448 ** of the application-defined function to be NULL.
4449 **
4450 ** ^The sqlite3_result_text(), sqlite3_result_text16(),
4451 ** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
4452 ** set the return value of the application-defined function to be
4453 ** a text string which is represented as UTF-8, UTF-16 native byte order,
4454 ** UTF-16 little endian, or UTF-16 big endian, respectively.
4455 ** ^The sqlite3_result_text64() interface sets the return value of an
4456 ** application-defined function to be a text string in an encoding
@@ -6208,11 +6206,11 @@
6206 #define SQLITE_TESTCTRL_RESERVE 14
6207 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
6208 #define SQLITE_TESTCTRL_ISKEYWORD 16
6209 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17
6210 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
6211 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
6212 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
6213 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
6214 #define SQLITE_TESTCTRL_BYTEORDER 22
6215 #define SQLITE_TESTCTRL_ISINIT 23
6216 #define SQLITE_TESTCTRL_SORTER_MMAP 24
6217
+7 -7
--- src/stash.c
+++ src/stash.c
@@ -23,17 +23,17 @@
2323
2424
/*
2525
** SQL code to implement the tables needed by the stash.
2626
*/
2727
static const char zStashInit[] =
28
-@ CREATE TABLE IF NOT EXISTS %s.stash(
28
+@ CREATE TABLE IF NOT EXISTS "%w".stash(
2929
@ stashid INTEGER PRIMARY KEY, -- Unique stash identifier
3030
@ vid INTEGER, -- The baseline check-out for this stash
3131
@ comment TEXT, -- Comment for this stash. Or NULL
3232
@ ctime TIMESTAMP -- When the stash was created
3333
@ );
34
-@ CREATE TABLE IF NOT EXISTS %s.stashfile(
34
+@ CREATE TABLE IF NOT EXISTS "%w".stashfile(
3535
@ stashid INTEGER REFERENCES stash, -- Stash that contains this file
3636
@ rid INTEGER, -- Baseline content in BLOB table or 0.
3737
@ isAdded BOOLEAN, -- True if this is an added file
3838
@ isRemoved BOOLEAN, -- True if this file is deleted
3939
@ isExec BOOLEAN, -- True if file is executable
@@ -61,24 +61,24 @@
6161
6262
zFile = mprintf("%/", zFName);
6363
file_tree_name(zFile, &fname, 1);
6464
zTreename = blob_str(&fname);
6565
blob_zero(&sql);
66
- blob_appendf(&sql,
66
+ blob_append_sql(&sql,
6767
"SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
6868
" FROM vfile"
6969
" WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
7070
vid
7171
);
7272
if( fossil_strcmp(zTreename,".")!=0 ){
73
- blob_appendf(&sql,
73
+ blob_append_sql(&sql,
7474
" AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
7575
" OR pathname=%Q OR origname=%Q)",
7676
zTreename, zTreename, zTreename, zTreename
7777
);
7878
}
79
- db_prepare(&q, blob_str(&sql));
79
+ db_prepare(&q, "%s", blob_sql_text(&sql));
8080
blob_reset(&sql);
8181
db_prepare(&ins,
8282
"INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
8383
"origname, newname, delta)"
8484
"VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
@@ -481,11 +481,11 @@
481481
undo_capture_command_line();
482482
db_must_be_within_tree();
483483
db_open_config(0);
484484
db_begin_transaction();
485485
zDb = db_name("localdb");
486
- db_multi_exec(zStashInit, zDb, zDb);
486
+ db_multi_exec(zStashInit /*works-like:"%w,%w"*/, zDb, zDb);
487487
if( g.argc<=2 ){
488488
zCmd = "save";
489489
}else{
490490
zCmd = g.argv[2];
491491
}
@@ -534,11 +534,11 @@
534534
}
535535
verify_all_options();
536536
db_prepare(&q,
537537
"SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
538538
" comment, datetime(ctime) FROM stash"
539
- " ORDER BY ctime DESC"
539
+ " ORDER BY ctime"
540540
);
541541
if( verboseFlag ){
542542
db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
543543
" FROM stashfile WHERE stashid=$id");
544544
}
545545
--- src/stash.c
+++ src/stash.c
@@ -23,17 +23,17 @@
23
24 /*
25 ** SQL code to implement the tables needed by the stash.
26 */
27 static const char zStashInit[] =
28 @ CREATE TABLE IF NOT EXISTS %s.stash(
29 @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier
30 @ vid INTEGER, -- The baseline check-out for this stash
31 @ comment TEXT, -- Comment for this stash. Or NULL
32 @ ctime TIMESTAMP -- When the stash was created
33 @ );
34 @ CREATE TABLE IF NOT EXISTS %s.stashfile(
35 @ stashid INTEGER REFERENCES stash, -- Stash that contains this file
36 @ rid INTEGER, -- Baseline content in BLOB table or 0.
37 @ isAdded BOOLEAN, -- True if this is an added file
38 @ isRemoved BOOLEAN, -- True if this file is deleted
39 @ isExec BOOLEAN, -- True if file is executable
@@ -61,24 +61,24 @@
61
62 zFile = mprintf("%/", zFName);
63 file_tree_name(zFile, &fname, 1);
64 zTreename = blob_str(&fname);
65 blob_zero(&sql);
66 blob_appendf(&sql,
67 "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
68 " FROM vfile"
69 " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
70 vid
71 );
72 if( fossil_strcmp(zTreename,".")!=0 ){
73 blob_appendf(&sql,
74 " AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
75 " OR pathname=%Q OR origname=%Q)",
76 zTreename, zTreename, zTreename, zTreename
77 );
78 }
79 db_prepare(&q, blob_str(&sql));
80 blob_reset(&sql);
81 db_prepare(&ins,
82 "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
83 "origname, newname, delta)"
84 "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
@@ -481,11 +481,11 @@
481 undo_capture_command_line();
482 db_must_be_within_tree();
483 db_open_config(0);
484 db_begin_transaction();
485 zDb = db_name("localdb");
486 db_multi_exec(zStashInit, zDb, zDb);
487 if( g.argc<=2 ){
488 zCmd = "save";
489 }else{
490 zCmd = g.argv[2];
491 }
@@ -534,11 +534,11 @@
534 }
535 verify_all_options();
536 db_prepare(&q,
537 "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
538 " comment, datetime(ctime) FROM stash"
539 " ORDER BY ctime DESC"
540 );
541 if( verboseFlag ){
542 db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
543 " FROM stashfile WHERE stashid=$id");
544 }
545
--- src/stash.c
+++ src/stash.c
@@ -23,17 +23,17 @@
23
24 /*
25 ** SQL code to implement the tables needed by the stash.
26 */
27 static const char zStashInit[] =
28 @ CREATE TABLE IF NOT EXISTS "%w".stash(
29 @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier
30 @ vid INTEGER, -- The baseline check-out for this stash
31 @ comment TEXT, -- Comment for this stash. Or NULL
32 @ ctime TIMESTAMP -- When the stash was created
33 @ );
34 @ CREATE TABLE IF NOT EXISTS "%w".stashfile(
35 @ stashid INTEGER REFERENCES stash, -- Stash that contains this file
36 @ rid INTEGER, -- Baseline content in BLOB table or 0.
37 @ isAdded BOOLEAN, -- True if this is an added file
38 @ isRemoved BOOLEAN, -- True if this file is deleted
39 @ isExec BOOLEAN, -- True if file is executable
@@ -61,24 +61,24 @@
61
62 zFile = mprintf("%/", zFName);
63 file_tree_name(zFile, &fname, 1);
64 zTreename = blob_str(&fname);
65 blob_zero(&sql);
66 blob_append_sql(&sql,
67 "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
68 " FROM vfile"
69 " WHERE vid=%d AND (chnged OR deleted OR origname NOT NULL OR mrid==0)",
70 vid
71 );
72 if( fossil_strcmp(zTreename,".")!=0 ){
73 blob_append_sql(&sql,
74 " AND (pathname GLOB '%q/*' OR origname GLOB '%q/*'"
75 " OR pathname=%Q OR origname=%Q)",
76 zTreename, zTreename, zTreename, zTreename
77 );
78 }
79 db_prepare(&q, "%s", blob_sql_text(&sql));
80 blob_reset(&sql);
81 db_prepare(&ins,
82 "INSERT INTO stashfile(stashid, rid, isAdded, isRemoved, isExec, isLink,"
83 "origname, newname, delta)"
84 "VALUES(%d,:rid,:isadd,:isrm,:isexe,:islink,:orig,:new,:content)",
@@ -481,11 +481,11 @@
481 undo_capture_command_line();
482 db_must_be_within_tree();
483 db_open_config(0);
484 db_begin_transaction();
485 zDb = db_name("localdb");
486 db_multi_exec(zStashInit /*works-like:"%w,%w"*/, zDb, zDb);
487 if( g.argc<=2 ){
488 zCmd = "save";
489 }else{
490 zCmd = g.argv[2];
491 }
@@ -534,11 +534,11 @@
534 }
535 verify_all_options();
536 db_prepare(&q,
537 "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid),"
538 " comment, datetime(ctime) FROM stash"
539 " ORDER BY ctime"
540 );
541 if( verboseFlag ){
542 db_prepare(&q2, "SELECT isAdded, isRemoved, origname, newname"
543 " FROM stashfile WHERE stashid=$id");
544 }
545
+47 -24
--- src/stat.c
+++ src/stat.c
@@ -137,49 +137,59 @@
137137
@ <tr><th>Repository Rebuilt:</th><td>
138138
@ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
139139
@ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
140140
@ <tr><th>Database&nbsp;Stats:</th><td>
141141
zDb = db_name("repository");
142
- @ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages,
143
- @ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page,
144
- @ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages,
145
- @ %s(db_text(0, "PRAGMA %s.encoding", zDb)),
146
- @ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode
142
+ @ %d(db_int(0, "PRAGMA \"%w\".page_count", zDb)) pages,
143
+ @ %d(db_int(0, "PRAGMA \"%w\".page_size", zDb)) bytes/page,
144
+ @ %d(db_int(0, "PRAGMA \"%w\".freelist_count", zDb)) free pages,
145
+ @ %s(db_text(0, "PRAGMA \"%w\".encoding", zDb)),
146
+ @ %s(db_text(0, "PRAGMA \"%w\".journal_mode", zDb)) mode
147147
@ </td></tr>
148148
149149
@ </table>
150150
style_footer();
151151
}
152152
153153
/*
154154
** COMMAND: dbstat*
155155
**
156
-** Usage: %fossil dbstat ?-brief | -b?
156
+** Usage: %fossil dbstat OPTIONS
157157
**
158158
** Shows statistics and global information about the repository.
159159
**
160
-** The (-brief|-b) option removes any "long-running" statistics, namely
161
-** those whose calculations are known to slow down as the repository
162
-** grows.
160
+** Options:
163161
**
162
+** --brief|-b Only show essential elements
163
+** --db-check Run a PRAGMA quick_check on the repository database
164
+** --omit-version-info Omit the SQLite and Fossil version information
164165
*/
165166
void dbstat_cmd(void){
166167
i64 t, fsize;
167168
int n, m;
168169
int szMax, szAvg;
169170
const char *zDb;
170171
int brief;
172
+ int omitVers; /* Omit Fossil and SQLite version information */
173
+ int dbCheck; /* True for the --db-check option */
171174
char zBuf[100];
172175
const int colWidth = -19 /* printf alignment/width for left column */;
173
- const char *p;
176
+ const char *p, *z;
174177
175178
brief = find_option("brief", "b",0)!=0;
179
+ omitVers = find_option("omit-version-info", 0, 0)!=0;
180
+ dbCheck = find_option("db-check",0,0)!=0;
176181
db_find_and_open_repository(0,0);
177182
178183
/* We should be done with options.. */
179184
verify_all_options();
180185
186
+ if( (z = db_get("project-name",0))!=0
187
+ || (z = db_get("short-project-name",0))!=0
188
+ ){
189
+ fossil_print("%*s%s\n", colWidth, "project-name:", z);
190
+ }
181191
fsize = file_size(g.zRepositoryName);
182192
bigSizeName(sizeof(zBuf), zBuf, fsize);
183193
fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
184194
if( !brief ){
185195
n = db_int(0, "SELECT count(*) FROM blob");
@@ -225,38 +235,51 @@
225235
fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
226236
n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
227237
fossil_print("%*s%d\n", colWidth, "events:", n);
228238
n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
229239
fossil_print("%*s%d\n", colWidth, "tagchanges:", n);
240
+ z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
241
+ " CAST(julianday('now') - mtime AS INTEGER)"
242
+ " || ' days ago' FROM event "
243
+ " ORDER BY mtime DESC LIMIT 1");
244
+ fossil_print("%*s%s\n", colWidth, "latest-change:", z);
230245
}
231246
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
232247
" + 0.99");
233248
fossil_print("%*s%d days or approximately %.2f years.\n",
234249
colWidth, "project-age:", n, n/365.2425);
235250
p = db_get("project-code", 0);
236251
if( p ){
237252
fossil_print("%*s%s\n", colWidth, "project-id:", p);
238253
}
254
+#if 0
255
+ /* Server-id is not useful information any more */
239256
fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
240
- fossil_print("%*s%s %s [%s] (%s)\n",
241
- colWidth, "fossil-version:",
242
- MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
243
- COMPILER_NAME);
244
- fossil_print("%*s%.19s [%.10s] (%s)\n",
245
- colWidth, "sqlite-version:",
246
- sqlite3_sourceid(), &sqlite3_sourceid()[20],
247
- sqlite3_libversion());
257
+#endif
258
+ if( !omitVers ){
259
+ fossil_print("%*s%s %s [%s] (%s)\n",
260
+ colWidth, "fossil-version:",
261
+ MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
262
+ COMPILER_NAME);
263
+ fossil_print("%*s%.19s [%.10s] (%s)\n",
264
+ colWidth, "sqlite-version:",
265
+ sqlite3_sourceid(), &sqlite3_sourceid()[20],
266
+ sqlite3_libversion());
267
+ }
248268
zDb = db_name("repository");
249269
fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
250270
"%s, %s mode\n",
251271
colWidth, "database-stats:",
252
- db_int(0, "PRAGMA %s.page_count", zDb),
253
- db_int(0, "PRAGMA %s.page_size", zDb),
254
- db_int(0, "PRAGMA %s.freelist_count", zDb),
255
- db_text(0, "PRAGMA %s.encoding", zDb),
256
- db_text(0, "PRAGMA %s.journal_mode", zDb));
257
-
272
+ db_int(0, "PRAGMA \"%w\".page_count", zDb),
273
+ db_int(0, "PRAGMA \"%w\".page_size", zDb),
274
+ db_int(0, "PRAGMA \"%w\".freelist_count", zDb),
275
+ db_text(0, "PRAGMA \"%w\".encoding", zDb),
276
+ db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
277
+ if( dbCheck ){
278
+ fossil_print("%*s%s\n", colWidth, "database-check:",
279
+ db_text(0, "PRAGMA quick_check(1)"));
280
+ }
258281
}
259282
260283
/*
261284
** WEBPAGE: urllist
262285
**
263286
--- src/stat.c
+++ src/stat.c
@@ -137,49 +137,59 @@
137 @ <tr><th>Repository Rebuilt:</th><td>
138 @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
139 @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
140 @ <tr><th>Database&nbsp;Stats:</th><td>
141 zDb = db_name("repository");
142 @ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages,
143 @ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page,
144 @ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages,
145 @ %s(db_text(0, "PRAGMA %s.encoding", zDb)),
146 @ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode
147 @ </td></tr>
148
149 @ </table>
150 style_footer();
151 }
152
153 /*
154 ** COMMAND: dbstat*
155 **
156 ** Usage: %fossil dbstat ?-brief | -b?
157 **
158 ** Shows statistics and global information about the repository.
159 **
160 ** The (-brief|-b) option removes any "long-running" statistics, namely
161 ** those whose calculations are known to slow down as the repository
162 ** grows.
163 **
 
 
 
164 */
165 void dbstat_cmd(void){
166 i64 t, fsize;
167 int n, m;
168 int szMax, szAvg;
169 const char *zDb;
170 int brief;
 
 
171 char zBuf[100];
172 const int colWidth = -19 /* printf alignment/width for left column */;
173 const char *p;
174
175 brief = find_option("brief", "b",0)!=0;
 
 
176 db_find_and_open_repository(0,0);
177
178 /* We should be done with options.. */
179 verify_all_options();
180
 
 
 
 
 
181 fsize = file_size(g.zRepositoryName);
182 bigSizeName(sizeof(zBuf), zBuf, fsize);
183 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
184 if( !brief ){
185 n = db_int(0, "SELECT count(*) FROM blob");
@@ -225,38 +235,51 @@
225 fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
226 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
227 fossil_print("%*s%d\n", colWidth, "events:", n);
228 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
229 fossil_print("%*s%d\n", colWidth, "tagchanges:", n);
 
 
 
 
 
230 }
231 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
232 " + 0.99");
233 fossil_print("%*s%d days or approximately %.2f years.\n",
234 colWidth, "project-age:", n, n/365.2425);
235 p = db_get("project-code", 0);
236 if( p ){
237 fossil_print("%*s%s\n", colWidth, "project-id:", p);
238 }
 
 
239 fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
240 fossil_print("%*s%s %s [%s] (%s)\n",
241 colWidth, "fossil-version:",
242 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
243 COMPILER_NAME);
244 fossil_print("%*s%.19s [%.10s] (%s)\n",
245 colWidth, "sqlite-version:",
246 sqlite3_sourceid(), &sqlite3_sourceid()[20],
247 sqlite3_libversion());
 
 
 
248 zDb = db_name("repository");
249 fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
250 "%s, %s mode\n",
251 colWidth, "database-stats:",
252 db_int(0, "PRAGMA %s.page_count", zDb),
253 db_int(0, "PRAGMA %s.page_size", zDb),
254 db_int(0, "PRAGMA %s.freelist_count", zDb),
255 db_text(0, "PRAGMA %s.encoding", zDb),
256 db_text(0, "PRAGMA %s.journal_mode", zDb));
257
 
 
 
258 }
259
260 /*
261 ** WEBPAGE: urllist
262 **
263
--- src/stat.c
+++ src/stat.c
@@ -137,49 +137,59 @@
137 @ <tr><th>Repository Rebuilt:</th><td>
138 @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
139 @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
140 @ <tr><th>Database&nbsp;Stats:</th><td>
141 zDb = db_name("repository");
142 @ %d(db_int(0, "PRAGMA \"%w\".page_count", zDb)) pages,
143 @ %d(db_int(0, "PRAGMA \"%w\".page_size", zDb)) bytes/page,
144 @ %d(db_int(0, "PRAGMA \"%w\".freelist_count", zDb)) free pages,
145 @ %s(db_text(0, "PRAGMA \"%w\".encoding", zDb)),
146 @ %s(db_text(0, "PRAGMA \"%w\".journal_mode", zDb)) mode
147 @ </td></tr>
148
149 @ </table>
150 style_footer();
151 }
152
153 /*
154 ** COMMAND: dbstat*
155 **
156 ** Usage: %fossil dbstat OPTIONS
157 **
158 ** Shows statistics and global information about the repository.
159 **
160 ** Options:
 
 
161 **
162 ** --brief|-b Only show essential elements
163 ** --db-check Run a PRAGMA quick_check on the repository database
164 ** --omit-version-info Omit the SQLite and Fossil version information
165 */
166 void dbstat_cmd(void){
167 i64 t, fsize;
168 int n, m;
169 int szMax, szAvg;
170 const char *zDb;
171 int brief;
172 int omitVers; /* Omit Fossil and SQLite version information */
173 int dbCheck; /* True for the --db-check option */
174 char zBuf[100];
175 const int colWidth = -19 /* printf alignment/width for left column */;
176 const char *p, *z;
177
178 brief = find_option("brief", "b",0)!=0;
179 omitVers = find_option("omit-version-info", 0, 0)!=0;
180 dbCheck = find_option("db-check",0,0)!=0;
181 db_find_and_open_repository(0,0);
182
183 /* We should be done with options.. */
184 verify_all_options();
185
186 if( (z = db_get("project-name",0))!=0
187 || (z = db_get("short-project-name",0))!=0
188 ){
189 fossil_print("%*s%s\n", colWidth, "project-name:", z);
190 }
191 fsize = file_size(g.zRepositoryName);
192 bigSizeName(sizeof(zBuf), zBuf, fsize);
193 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
194 if( !brief ){
195 n = db_int(0, "SELECT count(*) FROM blob");
@@ -225,38 +235,51 @@
235 fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
236 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
237 fossil_print("%*s%d\n", colWidth, "events:", n);
238 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
239 fossil_print("%*s%d\n", colWidth, "tagchanges:", n);
240 z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
241 " CAST(julianday('now') - mtime AS INTEGER)"
242 " || ' days ago' FROM event "
243 " ORDER BY mtime DESC LIMIT 1");
244 fossil_print("%*s%s\n", colWidth, "latest-change:", z);
245 }
246 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
247 " + 0.99");
248 fossil_print("%*s%d days or approximately %.2f years.\n",
249 colWidth, "project-age:", n, n/365.2425);
250 p = db_get("project-code", 0);
251 if( p ){
252 fossil_print("%*s%s\n", colWidth, "project-id:", p);
253 }
254 #if 0
255 /* Server-id is not useful information any more */
256 fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
257 #endif
258 if( !omitVers ){
259 fossil_print("%*s%s %s [%s] (%s)\n",
260 colWidth, "fossil-version:",
261 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
262 COMPILER_NAME);
263 fossil_print("%*s%.19s [%.10s] (%s)\n",
264 colWidth, "sqlite-version:",
265 sqlite3_sourceid(), &sqlite3_sourceid()[20],
266 sqlite3_libversion());
267 }
268 zDb = db_name("repository");
269 fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
270 "%s, %s mode\n",
271 colWidth, "database-stats:",
272 db_int(0, "PRAGMA \"%w\".page_count", zDb),
273 db_int(0, "PRAGMA \"%w\".page_size", zDb),
274 db_int(0, "PRAGMA \"%w\".freelist_count", zDb),
275 db_text(0, "PRAGMA \"%w\".encoding", zDb),
276 db_text(0, "PRAGMA \"%w\".journal_mode", zDb));
277 if( dbCheck ){
278 fossil_print("%*s%s\n", colWidth, "database-check:",
279 db_text(0, "PRAGMA quick_check(1)"));
280 }
281 }
282
283 /*
284 ** WEBPAGE: urllist
285 **
286
+9 -1
--- src/style.c
+++ src/style.c
@@ -175,11 +175,11 @@
175175
}
176176
for(i=0; i<nFormAction; i++){
177177
@ gebi("form%d(i+1)").action="%s(aFormAction[i])";
178178
}
179179
@ }
180
- if( strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT")) ){
180
+ if( sqlite3_strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT"))==0 ){
181181
/* Special case for Opera Mini, which executes JS server-side */
182182
@ var isOperaMini = Object.prototype.toString.call(window.operamini)
183183
@ === "[object OperaMini]";
184184
@ if( isOperaMini ){
185185
@ setTimeout("setAllHrefs();",%d(nDelay));
@@ -934,22 +934,26 @@
934934
@ white-space: nowrap;
935935
},
936936
{ "span.ueditInheritNobody",
937937
"color for capabilities, inherited by nobody",
938938
@ color: green;
939
+ @ padding: .2em;
939940
},
940941
{ "span.ueditInheritDeveloper",
941942
"color for capabilities, inherited by developer",
942943
@ color: red;
944
+ @ padding: .2em;
943945
},
944946
{ "span.ueditInheritReader",
945947
"color for capabilities, inherited by reader",
946948
@ color: black;
949
+ @ padding: .2em;
947950
},
948951
{ "span.ueditInheritAnonymous",
949952
"color for capabilities, inherited by anonymous",
950953
@ color: blue;
954
+ @ padding: .2em;
951955
},
952956
{ "span.capability",
953957
"format for capabilities, mentioned on the user edit page",
954958
@ font-weight: bold;
955959
},
@@ -1191,10 +1195,14 @@
11911195
@ /* use default */
11921196
},
11931197
{ "tr.row1",
11941198
"odd table row color",
11951199
@ /* Use default */
1200
+ },
1201
+ { "#usetupEditCapability",
1202
+ "format for capabilities string, mentioned on the user edit page",
1203
+ @ font-weight: bold;
11961204
},
11971205
{ "#canvas", "timeline graph node colors",
11981206
@ color: black;
11991207
@ background-color: white;
12001208
},
12011209
--- src/style.c
+++ src/style.c
@@ -175,11 +175,11 @@
175 }
176 for(i=0; i<nFormAction; i++){
177 @ gebi("form%d(i+1)").action="%s(aFormAction[i])";
178 }
179 @ }
180 if( strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT")) ){
181 /* Special case for Opera Mini, which executes JS server-side */
182 @ var isOperaMini = Object.prototype.toString.call(window.operamini)
183 @ === "[object OperaMini]";
184 @ if( isOperaMini ){
185 @ setTimeout("setAllHrefs();",%d(nDelay));
@@ -934,22 +934,26 @@
934 @ white-space: nowrap;
935 },
936 { "span.ueditInheritNobody",
937 "color for capabilities, inherited by nobody",
938 @ color: green;
 
939 },
940 { "span.ueditInheritDeveloper",
941 "color for capabilities, inherited by developer",
942 @ color: red;
 
943 },
944 { "span.ueditInheritReader",
945 "color for capabilities, inherited by reader",
946 @ color: black;
 
947 },
948 { "span.ueditInheritAnonymous",
949 "color for capabilities, inherited by anonymous",
950 @ color: blue;
 
951 },
952 { "span.capability",
953 "format for capabilities, mentioned on the user edit page",
954 @ font-weight: bold;
955 },
@@ -1191,10 +1195,14 @@
1191 @ /* use default */
1192 },
1193 { "tr.row1",
1194 "odd table row color",
1195 @ /* Use default */
 
 
 
 
1196 },
1197 { "#canvas", "timeline graph node colors",
1198 @ color: black;
1199 @ background-color: white;
1200 },
1201
--- src/style.c
+++ src/style.c
@@ -175,11 +175,11 @@
175 }
176 for(i=0; i<nFormAction; i++){
177 @ gebi("form%d(i+1)").action="%s(aFormAction[i])";
178 }
179 @ }
180 if( sqlite3_strglob("*Opera Mini/[1-9]*", P("HTTP_USER_AGENT"))==0 ){
181 /* Special case for Opera Mini, which executes JS server-side */
182 @ var isOperaMini = Object.prototype.toString.call(window.operamini)
183 @ === "[object OperaMini]";
184 @ if( isOperaMini ){
185 @ setTimeout("setAllHrefs();",%d(nDelay));
@@ -934,22 +934,26 @@
934 @ white-space: nowrap;
935 },
936 { "span.ueditInheritNobody",
937 "color for capabilities, inherited by nobody",
938 @ color: green;
939 @ padding: .2em;
940 },
941 { "span.ueditInheritDeveloper",
942 "color for capabilities, inherited by developer",
943 @ color: red;
944 @ padding: .2em;
945 },
946 { "span.ueditInheritReader",
947 "color for capabilities, inherited by reader",
948 @ color: black;
949 @ padding: .2em;
950 },
951 { "span.ueditInheritAnonymous",
952 "color for capabilities, inherited by anonymous",
953 @ color: blue;
954 @ padding: .2em;
955 },
956 { "span.capability",
957 "format for capabilities, mentioned on the user edit page",
958 @ font-weight: bold;
959 },
@@ -1191,10 +1195,14 @@
1195 @ /* use default */
1196 },
1197 { "tr.row1",
1198 "odd table row color",
1199 @ /* Use default */
1200 },
1201 { "#usetupEditCapability",
1202 "format for capabilities string, mentioned on the user edit page",
1203 @ font-weight: bold;
1204 },
1205 { "#canvas", "timeline graph node colors",
1206 @ color: black;
1207 @ background-color: white;
1208 },
1209
+7 -6
--- src/tag.c
+++ src/tag.c
@@ -213,11 +213,12 @@
213213
rid
214214
);
215215
}
216216
}
217217
if( zCol ){
218
- db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
218
+ db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
219
+ zCol, zValue, rid);
219220
if( tagid==TAG_COMMENT ){
220221
char *zCopy = mprintf("%s", zValue);
221222
wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
222223
free(zCopy);
223224
}
@@ -437,41 +438,41 @@
437438
if( zType==0 || zType[0]==0 ) zType = "*";
438439
if( g.argc!=4 ){
439440
usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
440441
}
441442
if( fRaw ){
442
- blob_appendf(&sql,
443
+ blob_append_sql(&sql,
443444
"SELECT blob.uuid FROM tagxref, blob"
444445
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
445446
" AND tagxref.tagtype>0"
446447
" AND blob.rid=tagxref.rid",
447448
g.argv[3]
448449
);
449450
if( nFindLimit>0 ){
450
- blob_appendf(&sql, " LIMIT %d", nFindLimit);
451
+ blob_append_sql(&sql, " LIMIT %d", nFindLimit);
451452
}
452
- db_prepare(&q, "%s", blob_str(&sql));
453
+ db_prepare(&q, "%s", blob_sql_text(&sql));
453454
blob_reset(&sql);
454455
while( db_step(&q)==SQLITE_ROW ){
455456
fossil_print("%s\n", db_column_text(&q, 0));
456457
}
457458
db_finalize(&q);
458459
}else{
459460
int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
460461
g.argv[3]);
461462
if( tagid>0 ){
462
- blob_appendf(&sql,
463
+ blob_append_sql(&sql,
463464
"%s"
464465
" AND event.type GLOB '%q'"
465466
" AND blob.rid IN ("
466467
" SELECT rid FROM tagxref"
467468
" WHERE tagtype>0 AND tagid=%d"
468469
")"
469470
" ORDER BY event.mtime DESC",
470471
timeline_query_for_tty(), zType, tagid
471472
);
472
- db_prepare(&q, "%s", blob_str(&sql));
473
+ db_prepare(&q, "%s", blob_sql_text(&sql));
473474
blob_reset(&sql);
474475
print_timeline(&q, nFindLimit, 79, 0);
475476
db_finalize(&q);
476477
}
477478
}
478479
--- src/tag.c
+++ src/tag.c
@@ -213,11 +213,12 @@
213 rid
214 );
215 }
216 }
217 if( zCol ){
218 db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
 
219 if( tagid==TAG_COMMENT ){
220 char *zCopy = mprintf("%s", zValue);
221 wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
222 free(zCopy);
223 }
@@ -437,41 +438,41 @@
437 if( zType==0 || zType[0]==0 ) zType = "*";
438 if( g.argc!=4 ){
439 usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
440 }
441 if( fRaw ){
442 blob_appendf(&sql,
443 "SELECT blob.uuid FROM tagxref, blob"
444 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
445 " AND tagxref.tagtype>0"
446 " AND blob.rid=tagxref.rid",
447 g.argv[3]
448 );
449 if( nFindLimit>0 ){
450 blob_appendf(&sql, " LIMIT %d", nFindLimit);
451 }
452 db_prepare(&q, "%s", blob_str(&sql));
453 blob_reset(&sql);
454 while( db_step(&q)==SQLITE_ROW ){
455 fossil_print("%s\n", db_column_text(&q, 0));
456 }
457 db_finalize(&q);
458 }else{
459 int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
460 g.argv[3]);
461 if( tagid>0 ){
462 blob_appendf(&sql,
463 "%s"
464 " AND event.type GLOB '%q'"
465 " AND blob.rid IN ("
466 " SELECT rid FROM tagxref"
467 " WHERE tagtype>0 AND tagid=%d"
468 ")"
469 " ORDER BY event.mtime DESC",
470 timeline_query_for_tty(), zType, tagid
471 );
472 db_prepare(&q, "%s", blob_str(&sql));
473 blob_reset(&sql);
474 print_timeline(&q, nFindLimit, 79, 0);
475 db_finalize(&q);
476 }
477 }
478
--- src/tag.c
+++ src/tag.c
@@ -213,11 +213,12 @@
213 rid
214 );
215 }
216 }
217 if( zCol ){
218 db_multi_exec("UPDATE event SET \"%w\"=%Q WHERE objid=%d",
219 zCol, zValue, rid);
220 if( tagid==TAG_COMMENT ){
221 char *zCopy = mprintf("%s", zValue);
222 wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
223 free(zCopy);
224 }
@@ -437,41 +438,41 @@
438 if( zType==0 || zType[0]==0 ) zType = "*";
439 if( g.argc!=4 ){
440 usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
441 }
442 if( fRaw ){
443 blob_append_sql(&sql,
444 "SELECT blob.uuid FROM tagxref, blob"
445 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
446 " AND tagxref.tagtype>0"
447 " AND blob.rid=tagxref.rid",
448 g.argv[3]
449 );
450 if( nFindLimit>0 ){
451 blob_append_sql(&sql, " LIMIT %d", nFindLimit);
452 }
453 db_prepare(&q, "%s", blob_sql_text(&sql));
454 blob_reset(&sql);
455 while( db_step(&q)==SQLITE_ROW ){
456 fossil_print("%s\n", db_column_text(&q, 0));
457 }
458 db_finalize(&q);
459 }else{
460 int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
461 g.argv[3]);
462 if( tagid>0 ){
463 blob_append_sql(&sql,
464 "%s"
465 " AND event.type GLOB '%q'"
466 " AND blob.rid IN ("
467 " SELECT rid FROM tagxref"
468 " WHERE tagtype>0 AND tagid=%d"
469 ")"
470 " ORDER BY event.mtime DESC",
471 timeline_query_for_tty(), zType, tagid
472 );
473 db_prepare(&q, "%s", blob_sql_text(&sql));
474 blob_reset(&sql);
475 print_timeline(&q, nFindLimit, 79, 0);
476 db_finalize(&q);
477 }
478 }
479
+139 -108
--- src/timeline.c
+++ src/timeline.c
@@ -393,14 +393,14 @@
393393
}else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
394394
Blob truncated;
395395
blob_zero(&truncated);
396396
blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
397397
blob_append(&truncated, "...", 3);
398
- @ <span class="timelineComment">%w(blob_str(&truncated))</span>
398
+ @ <span class="timelineComment">%W(blob_str(&truncated))</span>
399399
blob_reset(&truncated);
400400
}else{
401
- @ <span class="timelineComment">%w(blob_str(&comment))</span>
401
+ @ <span class="timelineComment">%W(blob_str(&comment))</span>
402402
}
403403
blob_reset(&comment);
404404
405405
/* Generate the "user: USERNAME" at the end of the comment, together
406406
** with a hyperlink to another timeline for that user.
@@ -860,11 +860,11 @@
860860
@ tagid INTEGER,
861861
@ short TEXT,
862862
@ sortby REAL
863863
@ )
864864
;
865
- db_multi_exec(zSql);
865
+ db_multi_exec("%s", zSql/*safe-for-%s*/);
866866
}
867867
868868
/*
869869
** Return a pointer to a constant string that forms the basis
870870
** for a timeline query for the WWW interface.
@@ -889,11 +889,11 @@
889889
@ event.mtime AS mtime
890890
@ FROM event CROSS JOIN blob
891891
@ WHERE blob.rid=event.objid
892892
;
893893
if( zBase==0 ){
894
- zBase = mprintf(zBaseSql, timeline_utc());
894
+ zBase = mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
895895
}
896896
return zBase;
897897
}
898898
899899
/*
@@ -965,11 +965,11 @@
965965
Stmt q;
966966
Blob out;
967967
const char *zSep = "";
968968
db_prepare(&q,
969969
"SELECT DISTINCT filename.name FROM mlink, filename"
970
- " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid='%s')"
970
+ " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid=%Q)"
971971
" AND filename.fnid=mlink.fnid",
972972
zUuid
973973
);
974974
blob_zero(&out);
975975
while( db_step(&q)==SQLITE_ROW ){
@@ -1129,13 +1129,15 @@
11291129
if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
11301130
tmFlags |= TIMELINE_FCHANGES;
11311131
url_add_parameter(&url, "v", 0);
11321132
}
11331133
if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1134
- blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM tagxref"
1135
- " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1136
- TAG_HIDDEN);
1134
+ blob_append_sql(&sql,
1135
+ " AND NOT EXISTS(SELECT 1 FROM tagxref"
1136
+ " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1137
+ TAG_HIDDEN
1138
+ );
11371139
}
11381140
if( !useDividers ) url_add_parameter(&url, "nd", 0);
11391141
if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
11401142
/* If from= and to= are present, display all nodes on a path connecting
11411143
** the two */
@@ -1154,21 +1156,21 @@
11541156
zFrom = P("me");
11551157
zTo = P("you");
11561158
}
11571159
blob_append(&sql, " AND event.objid IN (0", -1);
11581160
while( p ){
1159
- blob_appendf(&sql, ",%d", p->rid);
1161
+ blob_append_sql(&sql, ",%d", p->rid);
11601162
p = p->u.pTo;
11611163
}
11621164
blob_append(&sql, ")", -1);
11631165
path_reset();
11641166
blob_append(&desc, "All nodes on the path from ", -1);
11651167
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
11661168
blob_append(&desc, " to ", -1);
11671169
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
11681170
tmFlags |= TIMELINE_DISJOINT;
1169
- db_multi_exec("%s", blob_str(&sql));
1171
+ db_multi_exec("%s", blob_sql_text(&sql));
11701172
}else if( (p_rid || d_rid) && g.perm.Read ){
11711173
/* If p= or d= is present, ignore all other parameters other than n= */
11721174
char *zUuid;
11731175
int np, nd;
11741176
@@ -1179,16 +1181,16 @@
11791181
db_multi_exec(
11801182
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
11811183
);
11821184
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
11831185
p_rid ? p_rid : d_rid);
1184
- blob_appendf(&sql, " AND event.objid IN ok");
1186
+ blob_append_sql(&sql, " AND event.objid IN ok");
11851187
nd = 0;
11861188
if( d_rid ){
11871189
compute_descendants(d_rid, nEntry+1);
11881190
nd = db_int(0, "SELECT count(*)-1 FROM ok");
1189
- if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
1191
+ if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
11901192
if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
11911193
if( useDividers ) timeline_add_dividers(0, d_rid);
11921194
db_multi_exec("DELETE FROM ok");
11931195
}
11941196
if( p_rid ){
@@ -1195,11 +1197,11 @@
11951197
compute_ancestors(p_rid, nEntry+1, 0);
11961198
np = db_int(0, "SELECT count(*)-1 FROM ok");
11971199
if( np>0 ){
11981200
if( nd>0 ) blob_appendf(&desc, " and ");
11991201
blob_appendf(&desc, "%d ancestors", np);
1200
- db_multi_exec("%s", blob_str(&sql));
1202
+ db_multi_exec("%s", blob_sql_text(&sql));
12011203
}
12021204
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
12031205
}
12041206
blob_appendf(&desc, " of %z[%S]</a>",
12051207
href("%R/info/%s", zUuid), zUuid);
@@ -1235,12 +1237,12 @@
12351237
"INSERT INTO ok VALUES(%d);"
12361238
"INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
12371239
"INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
12381240
f_rid, f_rid, f_rid
12391241
);
1240
- blob_appendf(&sql, " AND event.objid IN ok");
1241
- db_multi_exec("%s", blob_str(&sql));
1242
+ blob_append_sql(&sql, " AND event.objid IN ok");
1243
+ db_multi_exec("%s", blob_sql_text(&sql));
12421244
if( useDividers ) timeline_add_dividers(0, f_rid);
12431245
blob_appendf(&desc, "Parents and children of check-in ");
12441246
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
12451247
blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
12461248
tmFlags |= TIMELINE_DISJOINT;
@@ -1257,25 +1259,25 @@
12571259
/* Otherwise, a timeline based on a span of time */
12581260
int n;
12591261
const char *zEType = "timeline item";
12601262
char *zDate;
12611263
if( zUses ){
1262
- blob_appendf(&sql, " AND event.objid IN usesfile ");
1264
+ blob_append_sql(&sql, " AND event.objid IN usesfile ");
12631265
}
12641266
if( renameOnly ){
1265
- blob_appendf(&sql, " AND event.objid IN rnfile ");
1267
+ blob_append_sql(&sql, " AND event.objid IN rnfile ");
12661268
}
12671269
if( zYearMonth ){
1268
- blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1270
+ blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
12691271
zYearMonth);
12701272
}
12711273
else if( zYearWeek ){
1272
- blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1274
+ blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
12731275
zYearWeek);
12741276
}
12751277
if( tagid>0 ){
1276
- blob_appendf(&sql,
1278
+ blob_append_sql(&sql,
12771279
"AND (EXISTS(SELECT 1 FROM tagxref"
12781280
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
12791281
12801282
if( zBrName ){
12811283
url_add_parameter(&url, "r", zBrName);
@@ -1283,40 +1285,42 @@
12831285
** are not part of the branch which are parents or children of the
12841286
** branch to be included in the report. This related check-ins are
12851287
** useful in helping to visualize what has happened on a quiescent
12861288
** branch that is infrequently merged with a much more activate branch.
12871289
*/
1288
- blob_appendf(&sql,
1290
+ blob_append_sql(&sql,
12891291
" OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
12901292
" WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
12911293
tagid
12921294
);
12931295
if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1294
- blob_appendf(&sql,
1296
+ blob_append_sql(&sql,
12951297
" AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
12961298
" WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
12971299
TAG_HIDDEN
12981300
);
12991301
}
13001302
if( P("mionly")==0 ){
1301
- blob_appendf(&sql,
1303
+ blob_append_sql(&sql,
13021304
" OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
13031305
" WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
13041306
tagid
13051307
);
13061308
if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1307
- blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1308
- " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1309
- TAG_HIDDEN);
1309
+ blob_append_sql(&sql,
1310
+ " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1311
+ " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1312
+ TAG_HIDDEN
1313
+ );
13101314
}
13111315
}else{
13121316
url_add_parameter(&url, "mionly", "1");
13131317
}
13141318
}else{
13151319
url_add_parameter(&url, "t", zTagName);
13161320
}
1317
- blob_appendf(&sql, ")");
1321
+ blob_append_sql(&sql, ")");
13181322
}
13191323
if( (zType[0]=='w' && !g.perm.RdWiki)
13201324
|| (zType[0]=='t' && !g.perm.RdTkt)
13211325
|| (zType[0]=='e' && !g.perm.RdWiki)
13221326
|| (zType[0]=='c' && !g.perm.Read)
@@ -1325,27 +1329,27 @@
13251329
zType = "all";
13261330
}
13271331
if( zType[0]=='a' ){
13281332
if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
13291333
char cSep = '(';
1330
- blob_appendf(&sql, " AND event.type IN ");
1334
+ blob_append_sql(&sql, " AND event.type IN ");
13311335
if( g.perm.Read ){
1332
- blob_appendf(&sql, "%c'ci','g'", cSep);
1336
+ blob_append_sql(&sql, "%c'ci','g'", cSep);
13331337
cSep = ',';
13341338
}
13351339
if( g.perm.RdWiki ){
1336
- blob_appendf(&sql, "%c'w','e'", cSep);
1340
+ blob_append_sql(&sql, "%c'w','e'", cSep);
13371341
cSep = ',';
13381342
}
13391343
if( g.perm.RdTkt ){
1340
- blob_appendf(&sql, "%c't'", cSep);
1344
+ blob_append_sql(&sql, "%c't'", cSep);
13411345
cSep = ',';
13421346
}
1343
- blob_appendf(&sql, ")");
1347
+ blob_append_sql(&sql, ")");
13441348
}
13451349
}else{ /* zType!="all" */
1346
- blob_appendf(&sql, " AND event.type=%Q", zType);
1350
+ blob_append_sql(&sql, " AND event.type=%Q", zType);
13471351
url_add_parameter(&url, "y", zType);
13481352
if( zType[0]=='c' ){
13491353
zEType = "checkin";
13501354
}else if( zType[0]=='w' ){
13511355
zEType = "wiki edit";
@@ -1356,64 +1360,64 @@
13561360
}else if( zType[0]=='g' ){
13571361
zEType = "tag";
13581362
}
13591363
}
13601364
if( zUser ){
1361
- blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1365
+ blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)",
13621366
zUser, zUser);
13631367
url_add_parameter(&url, "u", zUser);
13641368
zThisUser = zUser;
13651369
}
13661370
if( zSearch ){
1367
- blob_appendf(&sql,
1371
+ blob_append_sql(&sql,
13681372
" AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
13691373
zSearch, zSearch);
13701374
url_add_parameter(&url, "s", zSearch);
13711375
}
13721376
rBefore = symbolic_name_to_mtime(zBefore);
13731377
rAfter = symbolic_name_to_mtime(zAfter);
13741378
rCirca = symbolic_name_to_mtime(zCirca);
13751379
if( rAfter>0.0 ){
13761380
if( rBefore>0.0 ){
1377
- blob_appendf(&sql,
1381
+ blob_append_sql(&sql,
13781382
" AND event.mtime>=%.17g AND event.mtime<=%.17g"
13791383
" ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
13801384
url_add_parameter(&url, "a", zAfter);
13811385
url_add_parameter(&url, "b", zBefore);
13821386
nEntry = 1000000;
13831387
}else{
1384
- blob_appendf(&sql,
1388
+ blob_append_sql(&sql,
13851389
" AND event.mtime>=%.17g ORDER BY event.mtime ASC",
13861390
rAfter-ONE_SECOND);
13871391
url_add_parameter(&url, "a", zAfter);
13881392
}
13891393
}else if( rBefore>0.0 ){
1390
- blob_appendf(&sql,
1394
+ blob_append_sql(&sql,
13911395
" AND event.mtime<=%.17g ORDER BY event.mtime DESC",
13921396
rBefore+ONE_SECOND);
13931397
url_add_parameter(&url, "b", zBefore);
13941398
}else if( rCirca>0.0 ){
13951399
Blob sql2;
1396
- blob_init(&sql2, blob_str(&sql), -1);
1397
- blob_appendf(&sql2,
1400
+ blob_init(&sql2, blob_sql_text(&sql), -1);
1401
+ blob_append_sql(&sql2,
13981402
" AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
13991403
rCirca, (nEntry+1)/2
14001404
);
1401
- db_multi_exec("%s", blob_str(&sql2));
1405
+ db_multi_exec("%s", blob_sql_text(&sql2));
14021406
blob_reset(&sql2);
1403
- blob_appendf(&sql,
1407
+ blob_append_sql(&sql,
14041408
" AND event.mtime>=%f ORDER BY event.mtime ASC",
14051409
rCirca
14061410
);
14071411
nEntry -= (nEntry+1)/2;
14081412
if( useDividers ) timeline_add_dividers(rCirca, 0);
14091413
url_add_parameter(&url, "c", zCirca);
14101414
}else{
1411
- blob_appendf(&sql, " ORDER BY event.mtime DESC");
1415
+ blob_append_sql(&sql, " ORDER BY event.mtime DESC");
14121416
}
1413
- blob_appendf(&sql, " LIMIT %d", nEntry);
1414
- db_multi_exec("%s", blob_str(&sql));
1417
+ blob_append_sql(&sql, " LIMIT %d", nEntry);
1418
+ db_multi_exec("%s", blob_sql_text(&sql));
14151419
14161420
n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
14171421
if( zYearMonth ){
14181422
blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
14191423
}else if( zYearWeek ){
@@ -1506,11 +1510,11 @@
15061510
}
15071511
}
15081512
}
15091513
}
15101514
if( P("showsql") ){
1511
- @ <blockquote>%h(blob_str(&sql))</blockquote>
1515
+ @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
15121516
}
15131517
blob_zero(&sql);
15141518
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
15151519
@ <h2>%b(&desc)</h2>
15161520
blob_reset(&desc);
@@ -1655,11 +1659,10 @@
16551659
/*
16561660
** Return a pointer to a static string that forms the basis for
16571661
** a timeline query for display on a TTY.
16581662
*/
16591663
const char *timeline_query_for_tty(void){
1660
- static const char *zBase = 0;
16611664
static const char zBaseSql[] =
16621665
@ SELECT
16631666
@ blob.rid AS rid,
16641667
@ uuid,
16651668
@ datetime(event.mtime%s) AS mDateTime,
@@ -1675,20 +1678,17 @@
16751678
@ AS primPlinkCount,
16761679
@ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
16771680
@ event.mtime AS mtime,
16781681
@ tagxref.value AS branch
16791682
@ FROM tag CROSS JOIN event CROSS JOIN blob
1680
- @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
1683
+ @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
16811684
@ AND tagxref.tagtype>0
16821685
@ AND tagxref.rid=blob.rid
16831686
@ WHERE blob.rid=event.objid
16841687
@ AND tag.tagname='branch'
16851688
;
1686
- if( zBase==0 ){
1687
- zBase = mprintf(zBaseSql, timeline_utc());
1688
- }
1689
- return zBase;
1689
+ return mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
16901690
}
16911691
16921692
/*
16931693
** Return true if the input string is a date in the ISO 8601 format:
16941694
** YYYY-MM-DD.
@@ -1739,11 +1739,11 @@
17391739
** -R REPO_FILE Specifies the repository db to use. Default is
17401740
** the current checkout's repository.
17411741
*/
17421742
void timeline_cmd(void){
17431743
Stmt q;
1744
- int n, k, width;
1744
+ int n, k, width, i;
17451745
const char *zLimit;
17461746
const char *zWidth;
17471747
const char *zOffset;
17481748
const char *zType;
17491749
char *zOrigin;
@@ -1752,10 +1752,12 @@
17521752
int objid = 0;
17531753
Blob uuid;
17541754
int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
17551755
int verboseFlag = 0 ;
17561756
int iOffset;
1757
+ const char *zFilePattern = 0;
1758
+ Blob treeName;
17571759
17581760
verboseFlag = find_option("verbose","v", 0)!=0;
17591761
if( !verboseFlag){
17601762
verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
17611763
}
@@ -1783,37 +1785,39 @@
17831785
iOffset = zOffset ? atoi(zOffset) : 0;
17841786
17851787
/* We should be done with options.. */
17861788
verify_all_options();
17871789
1788
- if( g.argc>=4 ){
1789
- k = strlen(g.argv[2]);
1790
- if( strncmp(g.argv[2],"before",k)==0 ){
1791
- mode = 1;
1792
- }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
1793
- mode = 2;
1794
- }else if( strncmp(g.argv[2],"descendants",k)==0 ){
1795
- mode = 3;
1796
- }else if( strncmp(g.argv[2],"children",k)==0 ){
1797
- mode = 3;
1798
- }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
1799
- mode = 4;
1800
- }else if( strncmp(g.argv[2],"parents",k)==0 ){
1801
- mode = 4;
1802
- }else if(!zType && !zLimit){
1803
- usage("?WHEN? ?BASELINE|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
1804
- "?-W|--width WIDTH?");
1805
- }
1806
- if( '-' != *g.argv[3] ){
1807
- zOrigin = g.argv[3];
1808
- }else{
1809
- zOrigin = "now";
1810
- }
1811
- }else if( g.argc==3 ){
1812
- zOrigin = g.argv[2];
1813
- }else{
1814
- zOrigin = "now";
1790
+ zOrigin = "now";
1791
+ zFilePattern = 0;
1792
+ for(i=2; i<g.argc; i++){
1793
+ char *zArg = g.argv[i];
1794
+ k = strlen(zArg);
1795
+ if( mode==0 ){
1796
+ if( strncmp(zArg,"before",k)==0 ){
1797
+ mode = 1;
1798
+ }else if( strncmp(zArg,"after",k)==0 && k>1 ){
1799
+ mode = 2;
1800
+ }else if( strncmp(zArg,"descendants",k)==0 ){
1801
+ mode = 3;
1802
+ }else if( strncmp(zArg,"children",k)==0 ){
1803
+ mode = 3;
1804
+ }else if( strncmp(zArg,"ancestors",k)==0 && k>1 ){
1805
+ mode = 4;
1806
+ }else if( strncmp(zArg,"parents",k)==0 ){
1807
+ mode = 4;
1808
+ }
1809
+ if( mode ){
1810
+ if( i<g.argc-1 ) zOrigin = g.argv[++i];
1811
+ continue;
1812
+ }
1813
+ }
1814
+ if( zFilePattern==0 ){
1815
+ zFilePattern = zArg;
1816
+ }else{
1817
+ usage("?WHEN? ?CHECKIN|DATETIME? ?FILE? ?OPTIONS?");
1818
+ }
18151819
}
18161820
k = strlen(zOrigin);
18171821
blob_zero(&uuid);
18181822
blob_append(&uuid, zOrigin, -1);
18191823
if( fossil_strcmp(zOrigin, "now")==0 ){
@@ -1838,37 +1842,72 @@
18381842
if( mode==0 ){
18391843
if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
18401844
}
18411845
zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
18421846
}
1847
+
1848
+ if( zFilePattern ){
1849
+ if( zType==0 ){
1850
+ /* When zFilePattern is specified and type is not specified, only show
1851
+ * file checkins */
1852
+ zType="ci";
1853
+ }
1854
+ file_tree_name(zFilePattern, &treeName, 1);
1855
+ if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
1856
+ /* When zTreeName refers to g.zLocalRoot, it's like not specifying
1857
+ * zFilePattern. */
1858
+ zFilePattern = 0;
1859
+ }
1860
+ }
1861
+
18431862
if( mode==0 ) mode = 1;
18441863
blob_zero(&sql);
18451864
blob_append(&sql, timeline_query_for_tty(), -1);
1846
- blob_appendf(&sql, " AND event.mtime %s %s",
1865
+ blob_append_sql(&sql, " AND event.mtime %s %s",
18471866
(mode==1 || mode==4) ? "<=" : ">=",
1848
- zDate
1867
+ zDate /*safe-for-%s*/
18491868
);
18501869
18511870
if( mode==3 || mode==4 ){
18521871
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
18531872
if( mode==3 ){
18541873
compute_descendants(objid, n);
18551874
}else{
18561875
compute_ancestors(objid, n, 0);
18571876
}
1858
- blob_appendf(&sql, " AND blob.rid IN ok");
1877
+ blob_append_sql(&sql, "\n AND blob.rid IN ok");
18591878
}
18601879
if( zType && (zType[0]!='a') ){
1861
- blob_appendf(&sql, " AND event.type=%Q ", zType);
1880
+ blob_append_sql(&sql, "\n AND event.type=%Q ", zType);
1881
+ }
1882
+ if( zFilePattern ){
1883
+ blob_append(&sql,
1884
+ "\n AND EXISTS(SELECT 1 FROM mlink\n"
1885
+ " WHERE mlink.mid=event.objid\n"
1886
+ " AND mlink.fnid IN ", -1);
1887
+ if( filenames_are_case_sensitive() ){
1888
+ blob_append_sql(&sql,
1889
+ "(SELECT fnid FROM filename"
1890
+ " WHERE name=%Q"
1891
+ " OR name GLOB '%q/*')",
1892
+ blob_str(&treeName), blob_str(&treeName));
1893
+ }else{
1894
+ blob_append_sql(&sql,
1895
+ "(SELECT fnid FROM filename"
1896
+ " WHERE name=%Q COLLATE nocase"
1897
+ " OR lower(name) GLOB lower('%q/*'))",
1898
+ blob_str(&treeName), blob_str(&treeName));
1899
+ }
1900
+ blob_append(&sql, ")", -1);
18621901
}
1863
- blob_appendf(&sql, " ORDER BY event.mtime DESC");
1902
+ blob_append_sql(&sql, "\nORDER BY event.mtime DESC");
18641903
if( iOffset>0 ){
18651904
/* Don't handle LIMIT here, otherwise print_timeline()
18661905
* will not determine the end-marker correctly! */
1867
- blob_appendf(&sql, " LIMIT -1 OFFSET %d", iOffset);
1906
+ blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset);
18681907
}
1869
- db_prepare(&q, blob_str(&sql));
1908
+ db_prepare(&q, "%s", blob_sql_text(&sql));
18701909
blob_reset(&sql);
18711910
print_timeline(&q, n, width, verboseFlag);
18721911
db_finalize(&q);
18731912
}
18741913
@@ -2178,24 +2217,24 @@
21782217
stats_report_init_view();
21792218
stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
21802219
blob_appendf(&header, "Timeline Events (%s) by year%s",
21812220
stats_report_label_for_type(),
21822221
(includeMonth ? "/month" : ""));
2183
- blob_appendf(&sql,
2222
+ blob_append_sql(&sql,
21842223
"SELECT substr(date(mtime),1,%d) AS timeframe, "
21852224
"count(*) AS eventCount "
21862225
"FROM v_reports ",
21872226
includeMonth ? 7 : 4);
21882227
if(zUserName&&*zUserName){
2189
- blob_appendf(&sql, " WHERE user=%Q ", zUserName);
2228
+ blob_append_sql(&sql, " WHERE user=%Q ", zUserName);
21902229
blob_appendf(&header," for user %q", zUserName);
21912230
}
21922231
blob_append(&sql,
21932232
" GROUP BY timeframe"
21942233
" ORDER BY timeframe DESC",
21952234
-1);
2196
- db_prepare(&query, blob_str(&sql));
2235
+ db_prepare(&query, "%s", blob_sql_text(&sql));
21972236
blob_reset(&sql);
21982237
@ <h1>%b(&header)</h1>
21992238
@ <table class='statistics-report-table-events' border='0' cellpadding='2'
22002239
@ cellspacing='0' id='statsTable'>
22012240
@ <thead>
@@ -2321,23 +2360,19 @@
23212360
Stmt query = empty_Stmt;
23222361
int nRowNumber = 0; /* current TR number */
23232362
int nEventTotal = 0; /* Total event count */
23242363
int rowClass = 0; /* counter for alternating
23252364
row colors */
2326
- Blob sql = empty_blob; /* SQL */
23272365
int nMaxEvents = 1; /* max number of events for
23282366
all rows. */
23292367
stats_report_init_view();
23302368
stats_report_event_types_menu("byuser", NULL);
2331
- blob_append(&sql,
2369
+ db_prepare(&query,
23322370
"SELECT user, "
23332371
"COUNT(*) AS eventCount "
23342372
"FROM v_reports "
2335
- "GROUP BY user ORDER BY eventCount DESC",
2336
- -1);
2337
- db_prepare(&query, blob_str(&sql));
2338
- blob_reset(&sql);
2373
+ "GROUP BY user ORDER BY eventCount DESC");
23392374
@ <h1>Timeline Events
23402375
@ (%s(stats_report_label_for_type())) by User</h1>
23412376
@ <table class='statistics-report-table-events' border='0'
23422377
@ cellpadding='2' cellspacing='0' id='statsTable'>
23432378
@ <thead><tr>
@@ -2388,28 +2423,24 @@
23882423
Stmt query = empty_Stmt;
23892424
int nRowNumber = 0; /* current TR number */
23902425
int nEventTotal = 0; /* Total event count */
23912426
int rowClass = 0; /* counter for alternating
23922427
row colors */
2393
- Blob sql = empty_blob; /* SQL */
23942428
int nMaxEvents = 1; /* max number of events for
23952429
all rows. */
23962430
static const char *const daysOfWeek[] = {
23972431
"Monday", "Tuesday", "Wednesday", "Thursday",
23982432
"Friday", "Saturday", "Sunday"
23992433
};
24002434
24012435
stats_report_init_view();
24022436
stats_report_event_types_menu("byweekday", NULL);
2403
- blob_append(&sql,
2437
+ db_prepare(&query,
24042438
"SELECT cast(mtime %% 7 AS INTEGER) dow, "
24052439
"COUNT(*) AS eventCount "
24062440
"FROM v_reports "
2407
- "GROUP BY dow ORDER BY dow",
2408
- -1);
2409
- db_prepare(&query, blob_str(&sql));
2410
- blob_reset(&sql);
2441
+ "GROUP BY dow ORDER BY dow");
24112442
@ <h1>Timeline Events
24122443
@ (%s(stats_report_label_for_type())) by Day of the Week</h1>
24132444
@ <table class='statistics-report-table-events' border='0'
24142445
@ cellpadding='2' cellspacing='0' id='statsTable'>
24152446
@ <thead><tr>
@@ -2477,14 +2508,14 @@
24772508
}
24782509
blob_append(&sql,
24792510
"SELECT DISTINCT substr(date(mtime),1,4) AS y "
24802511
"FROM v_reports WHERE 1 ", -1);
24812512
if(zUserName&&*zUserName){
2482
- blob_appendf(&sql,"AND user=%Q ", zUserName);
2513
+ blob_append_sql(&sql,"AND user=%Q ", zUserName);
24832514
}
24842515
blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2485
- db_prepare(&qYears, blob_str(&sql));
2516
+ db_prepare(&qYears, "%s", blob_sql_text(&sql));
24862517
blob_reset(&sql);
24872518
cgi_printf("Select year: ");
24882519
while( SQLITE_ROW == db_step(&qYears) ){
24892520
const char *zT = db_column_text(&qYears, 0);
24902521
if( i++ ){
@@ -2510,22 +2541,22 @@
25102541
int total = 0;
25112542
Blob header = empty_blob;
25122543
blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
25132544
"of %h", stats_report_label_for_type(),
25142545
zYear);
2515
- blob_appendf(&sql,
2546
+ blob_append_sql(&sql,
25162547
"SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
25172548
"count(*) AS n "
25182549
"FROM v_reports "
25192550
"WHERE %Q=substr(date(mtime),1,4) "
25202551
"AND mtime < current_timestamp ",
25212552
zYear);
25222553
if(zUserName&&*zUserName){
2523
- blob_appendf(&sql, " AND user=%Q ", zUserName);
2554
+ blob_append_sql(&sql, " AND user=%Q ", zUserName);
25242555
blob_appendf(&header," for user %h", zUserName);
25252556
}
2526
- blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC");
2557
+ blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC");
25272558
cgi_printf("<h1>%h</h1>", blob_str(&header));
25282559
blob_reset(&header);
25292560
cgi_printf("<table class='statistics-report-table-events' "
25302561
"border='0' cellpadding='2' width='100%%' "
25312562
"cellspacing='0' id='statsTable'>");
@@ -2533,11 +2564,11 @@
25332564
"<th>Week</th>"
25342565
"<th>Events</th>"
25352566
"<th width='90%%'><!-- relative commits graph --></th>"
25362567
"</tr></thead>"
25372568
"<tbody>");
2538
- db_prepare(&stWeek, blob_str(&sql));
2569
+ db_prepare(&stWeek, "%s", blob_sql_text(&sql));
25392570
blob_reset(&sql);
25402571
while( SQLITE_ROW == db_step(&stWeek) ){
25412572
const int nCount = db_column_int(&stWeek, 1);
25422573
if(nCount>nMaxEvents){
25432574
nMaxEvents = nCount;
25442575
--- src/timeline.c
+++ src/timeline.c
@@ -393,14 +393,14 @@
393 }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
394 Blob truncated;
395 blob_zero(&truncated);
396 blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
397 blob_append(&truncated, "...", 3);
398 @ <span class="timelineComment">%w(blob_str(&truncated))</span>
399 blob_reset(&truncated);
400 }else{
401 @ <span class="timelineComment">%w(blob_str(&comment))</span>
402 }
403 blob_reset(&comment);
404
405 /* Generate the "user: USERNAME" at the end of the comment, together
406 ** with a hyperlink to another timeline for that user.
@@ -860,11 +860,11 @@
860 @ tagid INTEGER,
861 @ short TEXT,
862 @ sortby REAL
863 @ )
864 ;
865 db_multi_exec(zSql);
866 }
867
868 /*
869 ** Return a pointer to a constant string that forms the basis
870 ** for a timeline query for the WWW interface.
@@ -889,11 +889,11 @@
889 @ event.mtime AS mtime
890 @ FROM event CROSS JOIN blob
891 @ WHERE blob.rid=event.objid
892 ;
893 if( zBase==0 ){
894 zBase = mprintf(zBaseSql, timeline_utc());
895 }
896 return zBase;
897 }
898
899 /*
@@ -965,11 +965,11 @@
965 Stmt q;
966 Blob out;
967 const char *zSep = "";
968 db_prepare(&q,
969 "SELECT DISTINCT filename.name FROM mlink, filename"
970 " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid='%s')"
971 " AND filename.fnid=mlink.fnid",
972 zUuid
973 );
974 blob_zero(&out);
975 while( db_step(&q)==SQLITE_ROW ){
@@ -1129,13 +1129,15 @@
1129 if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
1130 tmFlags |= TIMELINE_FCHANGES;
1131 url_add_parameter(&url, "v", 0);
1132 }
1133 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1134 blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM tagxref"
1135 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1136 TAG_HIDDEN);
 
 
1137 }
1138 if( !useDividers ) url_add_parameter(&url, "nd", 0);
1139 if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
1140 /* If from= and to= are present, display all nodes on a path connecting
1141 ** the two */
@@ -1154,21 +1156,21 @@
1154 zFrom = P("me");
1155 zTo = P("you");
1156 }
1157 blob_append(&sql, " AND event.objid IN (0", -1);
1158 while( p ){
1159 blob_appendf(&sql, ",%d", p->rid);
1160 p = p->u.pTo;
1161 }
1162 blob_append(&sql, ")", -1);
1163 path_reset();
1164 blob_append(&desc, "All nodes on the path from ", -1);
1165 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
1166 blob_append(&desc, " to ", -1);
1167 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
1168 tmFlags |= TIMELINE_DISJOINT;
1169 db_multi_exec("%s", blob_str(&sql));
1170 }else if( (p_rid || d_rid) && g.perm.Read ){
1171 /* If p= or d= is present, ignore all other parameters other than n= */
1172 char *zUuid;
1173 int np, nd;
1174
@@ -1179,16 +1181,16 @@
1179 db_multi_exec(
1180 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
1181 );
1182 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
1183 p_rid ? p_rid : d_rid);
1184 blob_appendf(&sql, " AND event.objid IN ok");
1185 nd = 0;
1186 if( d_rid ){
1187 compute_descendants(d_rid, nEntry+1);
1188 nd = db_int(0, "SELECT count(*)-1 FROM ok");
1189 if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
1190 if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
1191 if( useDividers ) timeline_add_dividers(0, d_rid);
1192 db_multi_exec("DELETE FROM ok");
1193 }
1194 if( p_rid ){
@@ -1195,11 +1197,11 @@
1195 compute_ancestors(p_rid, nEntry+1, 0);
1196 np = db_int(0, "SELECT count(*)-1 FROM ok");
1197 if( np>0 ){
1198 if( nd>0 ) blob_appendf(&desc, " and ");
1199 blob_appendf(&desc, "%d ancestors", np);
1200 db_multi_exec("%s", blob_str(&sql));
1201 }
1202 if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
1203 }
1204 blob_appendf(&desc, " of %z[%S]</a>",
1205 href("%R/info/%s", zUuid), zUuid);
@@ -1235,12 +1237,12 @@
1235 "INSERT INTO ok VALUES(%d);"
1236 "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
1237 "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
1238 f_rid, f_rid, f_rid
1239 );
1240 blob_appendf(&sql, " AND event.objid IN ok");
1241 db_multi_exec("%s", blob_str(&sql));
1242 if( useDividers ) timeline_add_dividers(0, f_rid);
1243 blob_appendf(&desc, "Parents and children of check-in ");
1244 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
1245 blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
1246 tmFlags |= TIMELINE_DISJOINT;
@@ -1257,25 +1259,25 @@
1257 /* Otherwise, a timeline based on a span of time */
1258 int n;
1259 const char *zEType = "timeline item";
1260 char *zDate;
1261 if( zUses ){
1262 blob_appendf(&sql, " AND event.objid IN usesfile ");
1263 }
1264 if( renameOnly ){
1265 blob_appendf(&sql, " AND event.objid IN rnfile ");
1266 }
1267 if( zYearMonth ){
1268 blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1269 zYearMonth);
1270 }
1271 else if( zYearWeek ){
1272 blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1273 zYearWeek);
1274 }
1275 if( tagid>0 ){
1276 blob_appendf(&sql,
1277 "AND (EXISTS(SELECT 1 FROM tagxref"
1278 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1279
1280 if( zBrName ){
1281 url_add_parameter(&url, "r", zBrName);
@@ -1283,40 +1285,42 @@
1283 ** are not part of the branch which are parents or children of the
1284 ** branch to be included in the report. This related check-ins are
1285 ** useful in helping to visualize what has happened on a quiescent
1286 ** branch that is infrequently merged with a much more activate branch.
1287 */
1288 blob_appendf(&sql,
1289 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
1290 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1291 tagid
1292 );
1293 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1294 blob_appendf(&sql,
1295 " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
1296 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1297 TAG_HIDDEN
1298 );
1299 }
1300 if( P("mionly")==0 ){
1301 blob_appendf(&sql,
1302 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
1303 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1304 tagid
1305 );
1306 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1307 blob_appendf(&sql, " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1308 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1309 TAG_HIDDEN);
 
 
1310 }
1311 }else{
1312 url_add_parameter(&url, "mionly", "1");
1313 }
1314 }else{
1315 url_add_parameter(&url, "t", zTagName);
1316 }
1317 blob_appendf(&sql, ")");
1318 }
1319 if( (zType[0]=='w' && !g.perm.RdWiki)
1320 || (zType[0]=='t' && !g.perm.RdTkt)
1321 || (zType[0]=='e' && !g.perm.RdWiki)
1322 || (zType[0]=='c' && !g.perm.Read)
@@ -1325,27 +1329,27 @@
1325 zType = "all";
1326 }
1327 if( zType[0]=='a' ){
1328 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
1329 char cSep = '(';
1330 blob_appendf(&sql, " AND event.type IN ");
1331 if( g.perm.Read ){
1332 blob_appendf(&sql, "%c'ci','g'", cSep);
1333 cSep = ',';
1334 }
1335 if( g.perm.RdWiki ){
1336 blob_appendf(&sql, "%c'w','e'", cSep);
1337 cSep = ',';
1338 }
1339 if( g.perm.RdTkt ){
1340 blob_appendf(&sql, "%c't'", cSep);
1341 cSep = ',';
1342 }
1343 blob_appendf(&sql, ")");
1344 }
1345 }else{ /* zType!="all" */
1346 blob_appendf(&sql, " AND event.type=%Q", zType);
1347 url_add_parameter(&url, "y", zType);
1348 if( zType[0]=='c' ){
1349 zEType = "checkin";
1350 }else if( zType[0]=='w' ){
1351 zEType = "wiki edit";
@@ -1356,64 +1360,64 @@
1356 }else if( zType[0]=='g' ){
1357 zEType = "tag";
1358 }
1359 }
1360 if( zUser ){
1361 blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1362 zUser, zUser);
1363 url_add_parameter(&url, "u", zUser);
1364 zThisUser = zUser;
1365 }
1366 if( zSearch ){
1367 blob_appendf(&sql,
1368 " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
1369 zSearch, zSearch);
1370 url_add_parameter(&url, "s", zSearch);
1371 }
1372 rBefore = symbolic_name_to_mtime(zBefore);
1373 rAfter = symbolic_name_to_mtime(zAfter);
1374 rCirca = symbolic_name_to_mtime(zCirca);
1375 if( rAfter>0.0 ){
1376 if( rBefore>0.0 ){
1377 blob_appendf(&sql,
1378 " AND event.mtime>=%.17g AND event.mtime<=%.17g"
1379 " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
1380 url_add_parameter(&url, "a", zAfter);
1381 url_add_parameter(&url, "b", zBefore);
1382 nEntry = 1000000;
1383 }else{
1384 blob_appendf(&sql,
1385 " AND event.mtime>=%.17g ORDER BY event.mtime ASC",
1386 rAfter-ONE_SECOND);
1387 url_add_parameter(&url, "a", zAfter);
1388 }
1389 }else if( rBefore>0.0 ){
1390 blob_appendf(&sql,
1391 " AND event.mtime<=%.17g ORDER BY event.mtime DESC",
1392 rBefore+ONE_SECOND);
1393 url_add_parameter(&url, "b", zBefore);
1394 }else if( rCirca>0.0 ){
1395 Blob sql2;
1396 blob_init(&sql2, blob_str(&sql), -1);
1397 blob_appendf(&sql2,
1398 " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
1399 rCirca, (nEntry+1)/2
1400 );
1401 db_multi_exec("%s", blob_str(&sql2));
1402 blob_reset(&sql2);
1403 blob_appendf(&sql,
1404 " AND event.mtime>=%f ORDER BY event.mtime ASC",
1405 rCirca
1406 );
1407 nEntry -= (nEntry+1)/2;
1408 if( useDividers ) timeline_add_dividers(rCirca, 0);
1409 url_add_parameter(&url, "c", zCirca);
1410 }else{
1411 blob_appendf(&sql, " ORDER BY event.mtime DESC");
1412 }
1413 blob_appendf(&sql, " LIMIT %d", nEntry);
1414 db_multi_exec("%s", blob_str(&sql));
1415
1416 n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
1417 if( zYearMonth ){
1418 blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
1419 }else if( zYearWeek ){
@@ -1506,11 +1510,11 @@
1506 }
1507 }
1508 }
1509 }
1510 if( P("showsql") ){
1511 @ <blockquote>%h(blob_str(&sql))</blockquote>
1512 }
1513 blob_zero(&sql);
1514 db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
1515 @ <h2>%b(&desc)</h2>
1516 blob_reset(&desc);
@@ -1655,11 +1659,10 @@
1655 /*
1656 ** Return a pointer to a static string that forms the basis for
1657 ** a timeline query for display on a TTY.
1658 */
1659 const char *timeline_query_for_tty(void){
1660 static const char *zBase = 0;
1661 static const char zBaseSql[] =
1662 @ SELECT
1663 @ blob.rid AS rid,
1664 @ uuid,
1665 @ datetime(event.mtime%s) AS mDateTime,
@@ -1675,20 +1678,17 @@
1675 @ AS primPlinkCount,
1676 @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
1677 @ event.mtime AS mtime,
1678 @ tagxref.value AS branch
1679 @ FROM tag CROSS JOIN event CROSS JOIN blob
1680 @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
1681 @ AND tagxref.tagtype>0
1682 @ AND tagxref.rid=blob.rid
1683 @ WHERE blob.rid=event.objid
1684 @ AND tag.tagname='branch'
1685 ;
1686 if( zBase==0 ){
1687 zBase = mprintf(zBaseSql, timeline_utc());
1688 }
1689 return zBase;
1690 }
1691
1692 /*
1693 ** Return true if the input string is a date in the ISO 8601 format:
1694 ** YYYY-MM-DD.
@@ -1739,11 +1739,11 @@
1739 ** -R REPO_FILE Specifies the repository db to use. Default is
1740 ** the current checkout's repository.
1741 */
1742 void timeline_cmd(void){
1743 Stmt q;
1744 int n, k, width;
1745 const char *zLimit;
1746 const char *zWidth;
1747 const char *zOffset;
1748 const char *zType;
1749 char *zOrigin;
@@ -1752,10 +1752,12 @@
1752 int objid = 0;
1753 Blob uuid;
1754 int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
1755 int verboseFlag = 0 ;
1756 int iOffset;
 
 
1757
1758 verboseFlag = find_option("verbose","v", 0)!=0;
1759 if( !verboseFlag){
1760 verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
1761 }
@@ -1783,37 +1785,39 @@
1783 iOffset = zOffset ? atoi(zOffset) : 0;
1784
1785 /* We should be done with options.. */
1786 verify_all_options();
1787
1788 if( g.argc>=4 ){
1789 k = strlen(g.argv[2]);
1790 if( strncmp(g.argv[2],"before",k)==0 ){
1791 mode = 1;
1792 }else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
1793 mode = 2;
1794 }else if( strncmp(g.argv[2],"descendants",k)==0 ){
1795 mode = 3;
1796 }else if( strncmp(g.argv[2],"children",k)==0 ){
1797 mode = 3;
1798 }else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
1799 mode = 4;
1800 }else if( strncmp(g.argv[2],"parents",k)==0 ){
1801 mode = 4;
1802 }else if(!zType && !zLimit){
1803 usage("?WHEN? ?BASELINE|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
1804 "?-W|--width WIDTH?");
1805 }
1806 if( '-' != *g.argv[3] ){
1807 zOrigin = g.argv[3];
1808 }else{
1809 zOrigin = "now";
1810 }
1811 }else if( g.argc==3 ){
1812 zOrigin = g.argv[2];
1813 }else{
1814 zOrigin = "now";
 
 
1815 }
1816 k = strlen(zOrigin);
1817 blob_zero(&uuid);
1818 blob_append(&uuid, zOrigin, -1);
1819 if( fossil_strcmp(zOrigin, "now")==0 ){
@@ -1838,37 +1842,72 @@
1838 if( mode==0 ){
1839 if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
1840 }
1841 zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
1842 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1843 if( mode==0 ) mode = 1;
1844 blob_zero(&sql);
1845 blob_append(&sql, timeline_query_for_tty(), -1);
1846 blob_appendf(&sql, " AND event.mtime %s %s",
1847 (mode==1 || mode==4) ? "<=" : ">=",
1848 zDate
1849 );
1850
1851 if( mode==3 || mode==4 ){
1852 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
1853 if( mode==3 ){
1854 compute_descendants(objid, n);
1855 }else{
1856 compute_ancestors(objid, n, 0);
1857 }
1858 blob_appendf(&sql, " AND blob.rid IN ok");
1859 }
1860 if( zType && (zType[0]!='a') ){
1861 blob_appendf(&sql, " AND event.type=%Q ", zType);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1862 }
1863 blob_appendf(&sql, " ORDER BY event.mtime DESC");
1864 if( iOffset>0 ){
1865 /* Don't handle LIMIT here, otherwise print_timeline()
1866 * will not determine the end-marker correctly! */
1867 blob_appendf(&sql, " LIMIT -1 OFFSET %d", iOffset);
1868 }
1869 db_prepare(&q, blob_str(&sql));
1870 blob_reset(&sql);
1871 print_timeline(&q, n, width, verboseFlag);
1872 db_finalize(&q);
1873 }
1874
@@ -2178,24 +2217,24 @@
2178 stats_report_init_view();
2179 stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
2180 blob_appendf(&header, "Timeline Events (%s) by year%s",
2181 stats_report_label_for_type(),
2182 (includeMonth ? "/month" : ""));
2183 blob_appendf(&sql,
2184 "SELECT substr(date(mtime),1,%d) AS timeframe, "
2185 "count(*) AS eventCount "
2186 "FROM v_reports ",
2187 includeMonth ? 7 : 4);
2188 if(zUserName&&*zUserName){
2189 blob_appendf(&sql, " WHERE user=%Q ", zUserName);
2190 blob_appendf(&header," for user %q", zUserName);
2191 }
2192 blob_append(&sql,
2193 " GROUP BY timeframe"
2194 " ORDER BY timeframe DESC",
2195 -1);
2196 db_prepare(&query, blob_str(&sql));
2197 blob_reset(&sql);
2198 @ <h1>%b(&header)</h1>
2199 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
2200 @ cellspacing='0' id='statsTable'>
2201 @ <thead>
@@ -2321,23 +2360,19 @@
2321 Stmt query = empty_Stmt;
2322 int nRowNumber = 0; /* current TR number */
2323 int nEventTotal = 0; /* Total event count */
2324 int rowClass = 0; /* counter for alternating
2325 row colors */
2326 Blob sql = empty_blob; /* SQL */
2327 int nMaxEvents = 1; /* max number of events for
2328 all rows. */
2329 stats_report_init_view();
2330 stats_report_event_types_menu("byuser", NULL);
2331 blob_append(&sql,
2332 "SELECT user, "
2333 "COUNT(*) AS eventCount "
2334 "FROM v_reports "
2335 "GROUP BY user ORDER BY eventCount DESC",
2336 -1);
2337 db_prepare(&query, blob_str(&sql));
2338 blob_reset(&sql);
2339 @ <h1>Timeline Events
2340 @ (%s(stats_report_label_for_type())) by User</h1>
2341 @ <table class='statistics-report-table-events' border='0'
2342 @ cellpadding='2' cellspacing='0' id='statsTable'>
2343 @ <thead><tr>
@@ -2388,28 +2423,24 @@
2388 Stmt query = empty_Stmt;
2389 int nRowNumber = 0; /* current TR number */
2390 int nEventTotal = 0; /* Total event count */
2391 int rowClass = 0; /* counter for alternating
2392 row colors */
2393 Blob sql = empty_blob; /* SQL */
2394 int nMaxEvents = 1; /* max number of events for
2395 all rows. */
2396 static const char *const daysOfWeek[] = {
2397 "Monday", "Tuesday", "Wednesday", "Thursday",
2398 "Friday", "Saturday", "Sunday"
2399 };
2400
2401 stats_report_init_view();
2402 stats_report_event_types_menu("byweekday", NULL);
2403 blob_append(&sql,
2404 "SELECT cast(mtime %% 7 AS INTEGER) dow, "
2405 "COUNT(*) AS eventCount "
2406 "FROM v_reports "
2407 "GROUP BY dow ORDER BY dow",
2408 -1);
2409 db_prepare(&query, blob_str(&sql));
2410 blob_reset(&sql);
2411 @ <h1>Timeline Events
2412 @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
2413 @ <table class='statistics-report-table-events' border='0'
2414 @ cellpadding='2' cellspacing='0' id='statsTable'>
2415 @ <thead><tr>
@@ -2477,14 +2508,14 @@
2477 }
2478 blob_append(&sql,
2479 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2480 "FROM v_reports WHERE 1 ", -1);
2481 if(zUserName&&*zUserName){
2482 blob_appendf(&sql,"AND user=%Q ", zUserName);
2483 }
2484 blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2485 db_prepare(&qYears, blob_str(&sql));
2486 blob_reset(&sql);
2487 cgi_printf("Select year: ");
2488 while( SQLITE_ROW == db_step(&qYears) ){
2489 const char *zT = db_column_text(&qYears, 0);
2490 if( i++ ){
@@ -2510,22 +2541,22 @@
2510 int total = 0;
2511 Blob header = empty_blob;
2512 blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
2513 "of %h", stats_report_label_for_type(),
2514 zYear);
2515 blob_appendf(&sql,
2516 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2517 "count(*) AS n "
2518 "FROM v_reports "
2519 "WHERE %Q=substr(date(mtime),1,4) "
2520 "AND mtime < current_timestamp ",
2521 zYear);
2522 if(zUserName&&*zUserName){
2523 blob_appendf(&sql, " AND user=%Q ", zUserName);
2524 blob_appendf(&header," for user %h", zUserName);
2525 }
2526 blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC");
2527 cgi_printf("<h1>%h</h1>", blob_str(&header));
2528 blob_reset(&header);
2529 cgi_printf("<table class='statistics-report-table-events' "
2530 "border='0' cellpadding='2' width='100%%' "
2531 "cellspacing='0' id='statsTable'>");
@@ -2533,11 +2564,11 @@
2533 "<th>Week</th>"
2534 "<th>Events</th>"
2535 "<th width='90%%'><!-- relative commits graph --></th>"
2536 "</tr></thead>"
2537 "<tbody>");
2538 db_prepare(&stWeek, blob_str(&sql));
2539 blob_reset(&sql);
2540 while( SQLITE_ROW == db_step(&stWeek) ){
2541 const int nCount = db_column_int(&stWeek, 1);
2542 if(nCount>nMaxEvents){
2543 nMaxEvents = nCount;
2544
--- src/timeline.c
+++ src/timeline.c
@@ -393,14 +393,14 @@
393 }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
394 Blob truncated;
395 blob_zero(&truncated);
396 blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
397 blob_append(&truncated, "...", 3);
398 @ <span class="timelineComment">%W(blob_str(&truncated))</span>
399 blob_reset(&truncated);
400 }else{
401 @ <span class="timelineComment">%W(blob_str(&comment))</span>
402 }
403 blob_reset(&comment);
404
405 /* Generate the "user: USERNAME" at the end of the comment, together
406 ** with a hyperlink to another timeline for that user.
@@ -860,11 +860,11 @@
860 @ tagid INTEGER,
861 @ short TEXT,
862 @ sortby REAL
863 @ )
864 ;
865 db_multi_exec("%s", zSql/*safe-for-%s*/);
866 }
867
868 /*
869 ** Return a pointer to a constant string that forms the basis
870 ** for a timeline query for the WWW interface.
@@ -889,11 +889,11 @@
889 @ event.mtime AS mtime
890 @ FROM event CROSS JOIN blob
891 @ WHERE blob.rid=event.objid
892 ;
893 if( zBase==0 ){
894 zBase = mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
895 }
896 return zBase;
897 }
898
899 /*
@@ -965,11 +965,11 @@
965 Stmt q;
966 Blob out;
967 const char *zSep = "";
968 db_prepare(&q,
969 "SELECT DISTINCT filename.name FROM mlink, filename"
970 " WHERE mlink.fid=(SELECT rid FROM blob WHERE uuid=%Q)"
971 " AND filename.fnid=mlink.fnid",
972 zUuid
973 );
974 blob_zero(&out);
975 while( db_step(&q)==SQLITE_ROW ){
@@ -1129,13 +1129,15 @@
1129 if( P("fc")!=0 || P("v")!=0 || P("detail")!=0 ){
1130 tmFlags |= TIMELINE_FCHANGES;
1131 url_add_parameter(&url, "v", 0);
1132 }
1133 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1134 blob_append_sql(&sql,
1135 " AND NOT EXISTS(SELECT 1 FROM tagxref"
1136 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)",
1137 TAG_HIDDEN
1138 );
1139 }
1140 if( !useDividers ) url_add_parameter(&url, "nd", 0);
1141 if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
1142 /* If from= and to= are present, display all nodes on a path connecting
1143 ** the two */
@@ -1154,21 +1156,21 @@
1156 zFrom = P("me");
1157 zTo = P("you");
1158 }
1159 blob_append(&sql, " AND event.objid IN (0", -1);
1160 while( p ){
1161 blob_append_sql(&sql, ",%d", p->rid);
1162 p = p->u.pTo;
1163 }
1164 blob_append(&sql, ")", -1);
1165 path_reset();
1166 blob_append(&desc, "All nodes on the path from ", -1);
1167 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
1168 blob_append(&desc, " to ", -1);
1169 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
1170 tmFlags |= TIMELINE_DISJOINT;
1171 db_multi_exec("%s", blob_sql_text(&sql));
1172 }else if( (p_rid || d_rid) && g.perm.Read ){
1173 /* If p= or d= is present, ignore all other parameters other than n= */
1174 char *zUuid;
1175 int np, nd;
1176
@@ -1179,16 +1181,16 @@
1181 db_multi_exec(
1182 "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
1183 );
1184 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
1185 p_rid ? p_rid : d_rid);
1186 blob_append_sql(&sql, " AND event.objid IN ok");
1187 nd = 0;
1188 if( d_rid ){
1189 compute_descendants(d_rid, nEntry+1);
1190 nd = db_int(0, "SELECT count(*)-1 FROM ok");
1191 if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
1192 if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
1193 if( useDividers ) timeline_add_dividers(0, d_rid);
1194 db_multi_exec("DELETE FROM ok");
1195 }
1196 if( p_rid ){
@@ -1195,11 +1197,11 @@
1197 compute_ancestors(p_rid, nEntry+1, 0);
1198 np = db_int(0, "SELECT count(*)-1 FROM ok");
1199 if( np>0 ){
1200 if( nd>0 ) blob_appendf(&desc, " and ");
1201 blob_appendf(&desc, "%d ancestors", np);
1202 db_multi_exec("%s", blob_sql_text(&sql));
1203 }
1204 if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
1205 }
1206 blob_appendf(&desc, " of %z[%S]</a>",
1207 href("%R/info/%s", zUuid), zUuid);
@@ -1235,12 +1237,12 @@
1237 "INSERT INTO ok VALUES(%d);"
1238 "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
1239 "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
1240 f_rid, f_rid, f_rid
1241 );
1242 blob_append_sql(&sql, " AND event.objid IN ok");
1243 db_multi_exec("%s", blob_sql_text(&sql));
1244 if( useDividers ) timeline_add_dividers(0, f_rid);
1245 blob_appendf(&desc, "Parents and children of check-in ");
1246 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
1247 blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
1248 tmFlags |= TIMELINE_DISJOINT;
@@ -1257,25 +1259,25 @@
1259 /* Otherwise, a timeline based on a span of time */
1260 int n;
1261 const char *zEType = "timeline item";
1262 char *zDate;
1263 if( zUses ){
1264 blob_append_sql(&sql, " AND event.objid IN usesfile ");
1265 }
1266 if( renameOnly ){
1267 blob_append_sql(&sql, " AND event.objid IN rnfile ");
1268 }
1269 if( zYearMonth ){
1270 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1271 zYearMonth);
1272 }
1273 else if( zYearWeek ){
1274 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1275 zYearWeek);
1276 }
1277 if( tagid>0 ){
1278 blob_append_sql(&sql,
1279 "AND (EXISTS(SELECT 1 FROM tagxref"
1280 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1281
1282 if( zBrName ){
1283 url_add_parameter(&url, "r", zBrName);
@@ -1283,40 +1285,42 @@
1285 ** are not part of the branch which are parents or children of the
1286 ** branch to be included in the report. This related check-ins are
1287 ** useful in helping to visualize what has happened on a quiescent
1288 ** branch that is infrequently merged with a much more activate branch.
1289 */
1290 blob_append_sql(&sql,
1291 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid"
1292 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1293 tagid
1294 );
1295 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1296 blob_append_sql(&sql,
1297 " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid"
1298 " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)",
1299 TAG_HIDDEN
1300 );
1301 }
1302 if( P("mionly")==0 ){
1303 blob_append_sql(&sql,
1304 " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid"
1305 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1306 tagid
1307 );
1308 if( (tmFlags & TIMELINE_UNHIDE)==0 ){
1309 blob_append_sql(&sql,
1310 " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid"
1311 " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)",
1312 TAG_HIDDEN
1313 );
1314 }
1315 }else{
1316 url_add_parameter(&url, "mionly", "1");
1317 }
1318 }else{
1319 url_add_parameter(&url, "t", zTagName);
1320 }
1321 blob_append_sql(&sql, ")");
1322 }
1323 if( (zType[0]=='w' && !g.perm.RdWiki)
1324 || (zType[0]=='t' && !g.perm.RdTkt)
1325 || (zType[0]=='e' && !g.perm.RdWiki)
1326 || (zType[0]=='c' && !g.perm.Read)
@@ -1325,27 +1329,27 @@
1329 zType = "all";
1330 }
1331 if( zType[0]=='a' ){
1332 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
1333 char cSep = '(';
1334 blob_append_sql(&sql, " AND event.type IN ");
1335 if( g.perm.Read ){
1336 blob_append_sql(&sql, "%c'ci','g'", cSep);
1337 cSep = ',';
1338 }
1339 if( g.perm.RdWiki ){
1340 blob_append_sql(&sql, "%c'w','e'", cSep);
1341 cSep = ',';
1342 }
1343 if( g.perm.RdTkt ){
1344 blob_append_sql(&sql, "%c't'", cSep);
1345 cSep = ',';
1346 }
1347 blob_append_sql(&sql, ")");
1348 }
1349 }else{ /* zType!="all" */
1350 blob_append_sql(&sql, " AND event.type=%Q", zType);
1351 url_add_parameter(&url, "y", zType);
1352 if( zType[0]=='c' ){
1353 zEType = "checkin";
1354 }else if( zType[0]=='w' ){
1355 zEType = "wiki edit";
@@ -1356,64 +1360,64 @@
1360 }else if( zType[0]=='g' ){
1361 zEType = "tag";
1362 }
1363 }
1364 if( zUser ){
1365 blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1366 zUser, zUser);
1367 url_add_parameter(&url, "u", zUser);
1368 zThisUser = zUser;
1369 }
1370 if( zSearch ){
1371 blob_append_sql(&sql,
1372 " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
1373 zSearch, zSearch);
1374 url_add_parameter(&url, "s", zSearch);
1375 }
1376 rBefore = symbolic_name_to_mtime(zBefore);
1377 rAfter = symbolic_name_to_mtime(zAfter);
1378 rCirca = symbolic_name_to_mtime(zCirca);
1379 if( rAfter>0.0 ){
1380 if( rBefore>0.0 ){
1381 blob_append_sql(&sql,
1382 " AND event.mtime>=%.17g AND event.mtime<=%.17g"
1383 " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
1384 url_add_parameter(&url, "a", zAfter);
1385 url_add_parameter(&url, "b", zBefore);
1386 nEntry = 1000000;
1387 }else{
1388 blob_append_sql(&sql,
1389 " AND event.mtime>=%.17g ORDER BY event.mtime ASC",
1390 rAfter-ONE_SECOND);
1391 url_add_parameter(&url, "a", zAfter);
1392 }
1393 }else if( rBefore>0.0 ){
1394 blob_append_sql(&sql,
1395 " AND event.mtime<=%.17g ORDER BY event.mtime DESC",
1396 rBefore+ONE_SECOND);
1397 url_add_parameter(&url, "b", zBefore);
1398 }else if( rCirca>0.0 ){
1399 Blob sql2;
1400 blob_init(&sql2, blob_sql_text(&sql), -1);
1401 blob_append_sql(&sql2,
1402 " AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
1403 rCirca, (nEntry+1)/2
1404 );
1405 db_multi_exec("%s", blob_sql_text(&sql2));
1406 blob_reset(&sql2);
1407 blob_append_sql(&sql,
1408 " AND event.mtime>=%f ORDER BY event.mtime ASC",
1409 rCirca
1410 );
1411 nEntry -= (nEntry+1)/2;
1412 if( useDividers ) timeline_add_dividers(rCirca, 0);
1413 url_add_parameter(&url, "c", zCirca);
1414 }else{
1415 blob_append_sql(&sql, " ORDER BY event.mtime DESC");
1416 }
1417 blob_append_sql(&sql, " LIMIT %d", nEntry);
1418 db_multi_exec("%s", blob_sql_text(&sql));
1419
1420 n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
1421 if( zYearMonth ){
1422 blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
1423 }else if( zYearWeek ){
@@ -1506,11 +1510,11 @@
1510 }
1511 }
1512 }
1513 }
1514 if( P("showsql") ){
1515 @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
1516 }
1517 blob_zero(&sql);
1518 db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
1519 @ <h2>%b(&desc)</h2>
1520 blob_reset(&desc);
@@ -1655,11 +1659,10 @@
1659 /*
1660 ** Return a pointer to a static string that forms the basis for
1661 ** a timeline query for display on a TTY.
1662 */
1663 const char *timeline_query_for_tty(void){
 
1664 static const char zBaseSql[] =
1665 @ SELECT
1666 @ blob.rid AS rid,
1667 @ uuid,
1668 @ datetime(event.mtime%s) AS mDateTime,
@@ -1675,20 +1678,17 @@
1678 @ AS primPlinkCount,
1679 @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount,
1680 @ event.mtime AS mtime,
1681 @ tagxref.value AS branch
1682 @ FROM tag CROSS JOIN event CROSS JOIN blob
1683 @ LEFT JOIN tagxref ON tagxref.tagid=tag.tagid
1684 @ AND tagxref.tagtype>0
1685 @ AND tagxref.rid=blob.rid
1686 @ WHERE blob.rid=event.objid
1687 @ AND tag.tagname='branch'
1688 ;
1689 return mprintf(zBaseSql /*works-like: "%s"*/, timeline_utc());
 
 
 
1690 }
1691
1692 /*
1693 ** Return true if the input string is a date in the ISO 8601 format:
1694 ** YYYY-MM-DD.
@@ -1739,11 +1739,11 @@
1739 ** -R REPO_FILE Specifies the repository db to use. Default is
1740 ** the current checkout's repository.
1741 */
1742 void timeline_cmd(void){
1743 Stmt q;
1744 int n, k, width, i;
1745 const char *zLimit;
1746 const char *zWidth;
1747 const char *zOffset;
1748 const char *zType;
1749 char *zOrigin;
@@ -1752,10 +1752,12 @@
1752 int objid = 0;
1753 Blob uuid;
1754 int mode = 0 ; /* 0:none 1: before 2:after 3:children 4:parents */
1755 int verboseFlag = 0 ;
1756 int iOffset;
1757 const char *zFilePattern = 0;
1758 Blob treeName;
1759
1760 verboseFlag = find_option("verbose","v", 0)!=0;
1761 if( !verboseFlag){
1762 verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
1763 }
@@ -1783,37 +1785,39 @@
1785 iOffset = zOffset ? atoi(zOffset) : 0;
1786
1787 /* We should be done with options.. */
1788 verify_all_options();
1789
1790 zOrigin = "now";
1791 zFilePattern = 0;
1792 for(i=2; i<g.argc; i++){
1793 char *zArg = g.argv[i];
1794 k = strlen(zArg);
1795 if( mode==0 ){
1796 if( strncmp(zArg,"before",k)==0 ){
1797 mode = 1;
1798 }else if( strncmp(zArg,"after",k)==0 && k>1 ){
1799 mode = 2;
1800 }else if( strncmp(zArg,"descendants",k)==0 ){
1801 mode = 3;
1802 }else if( strncmp(zArg,"children",k)==0 ){
1803 mode = 3;
1804 }else if( strncmp(zArg,"ancestors",k)==0 && k>1 ){
1805 mode = 4;
1806 }else if( strncmp(zArg,"parents",k)==0 ){
1807 mode = 4;
1808 }
1809 if( mode ){
1810 if( i<g.argc-1 ) zOrigin = g.argv[++i];
1811 continue;
1812 }
1813 }
1814 if( zFilePattern==0 ){
1815 zFilePattern = zArg;
1816 }else{
1817 usage("?WHEN? ?CHECKIN|DATETIME? ?FILE? ?OPTIONS?");
1818 }
1819 }
1820 k = strlen(zOrigin);
1821 blob_zero(&uuid);
1822 blob_append(&uuid, zOrigin, -1);
1823 if( fossil_strcmp(zOrigin, "now")==0 ){
@@ -1838,37 +1842,72 @@
1842 if( mode==0 ){
1843 if( isIsoDate(zOrigin) ) zShift = ",'+1 day'";
1844 }
1845 zDate = mprintf("(SELECT julianday(%Q%s, 'utc'))", zOrigin, zShift);
1846 }
1847
1848 if( zFilePattern ){
1849 if( zType==0 ){
1850 /* When zFilePattern is specified and type is not specified, only show
1851 * file checkins */
1852 zType="ci";
1853 }
1854 file_tree_name(zFilePattern, &treeName, 1);
1855 if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
1856 /* When zTreeName refers to g.zLocalRoot, it's like not specifying
1857 * zFilePattern. */
1858 zFilePattern = 0;
1859 }
1860 }
1861
1862 if( mode==0 ) mode = 1;
1863 blob_zero(&sql);
1864 blob_append(&sql, timeline_query_for_tty(), -1);
1865 blob_append_sql(&sql, " AND event.mtime %s %s",
1866 (mode==1 || mode==4) ? "<=" : ">=",
1867 zDate /*safe-for-%s*/
1868 );
1869
1870 if( mode==3 || mode==4 ){
1871 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
1872 if( mode==3 ){
1873 compute_descendants(objid, n);
1874 }else{
1875 compute_ancestors(objid, n, 0);
1876 }
1877 blob_append_sql(&sql, "\n AND blob.rid IN ok");
1878 }
1879 if( zType && (zType[0]!='a') ){
1880 blob_append_sql(&sql, "\n AND event.type=%Q ", zType);
1881 }
1882 if( zFilePattern ){
1883 blob_append(&sql,
1884 "\n AND EXISTS(SELECT 1 FROM mlink\n"
1885 " WHERE mlink.mid=event.objid\n"
1886 " AND mlink.fnid IN ", -1);
1887 if( filenames_are_case_sensitive() ){
1888 blob_append_sql(&sql,
1889 "(SELECT fnid FROM filename"
1890 " WHERE name=%Q"
1891 " OR name GLOB '%q/*')",
1892 blob_str(&treeName), blob_str(&treeName));
1893 }else{
1894 blob_append_sql(&sql,
1895 "(SELECT fnid FROM filename"
1896 " WHERE name=%Q COLLATE nocase"
1897 " OR lower(name) GLOB lower('%q/*'))",
1898 blob_str(&treeName), blob_str(&treeName));
1899 }
1900 blob_append(&sql, ")", -1);
1901 }
1902 blob_append_sql(&sql, "\nORDER BY event.mtime DESC");
1903 if( iOffset>0 ){
1904 /* Don't handle LIMIT here, otherwise print_timeline()
1905 * will not determine the end-marker correctly! */
1906 blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset);
1907 }
1908 db_prepare(&q, "%s", blob_sql_text(&sql));
1909 blob_reset(&sql);
1910 print_timeline(&q, n, width, verboseFlag);
1911 db_finalize(&q);
1912 }
1913
@@ -2178,24 +2217,24 @@
2217 stats_report_init_view();
2218 stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
2219 blob_appendf(&header, "Timeline Events (%s) by year%s",
2220 stats_report_label_for_type(),
2221 (includeMonth ? "/month" : ""));
2222 blob_append_sql(&sql,
2223 "SELECT substr(date(mtime),1,%d) AS timeframe, "
2224 "count(*) AS eventCount "
2225 "FROM v_reports ",
2226 includeMonth ? 7 : 4);
2227 if(zUserName&&*zUserName){
2228 blob_append_sql(&sql, " WHERE user=%Q ", zUserName);
2229 blob_appendf(&header," for user %q", zUserName);
2230 }
2231 blob_append(&sql,
2232 " GROUP BY timeframe"
2233 " ORDER BY timeframe DESC",
2234 -1);
2235 db_prepare(&query, "%s", blob_sql_text(&sql));
2236 blob_reset(&sql);
2237 @ <h1>%b(&header)</h1>
2238 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
2239 @ cellspacing='0' id='statsTable'>
2240 @ <thead>
@@ -2321,23 +2360,19 @@
2360 Stmt query = empty_Stmt;
2361 int nRowNumber = 0; /* current TR number */
2362 int nEventTotal = 0; /* Total event count */
2363 int rowClass = 0; /* counter for alternating
2364 row colors */
 
2365 int nMaxEvents = 1; /* max number of events for
2366 all rows. */
2367 stats_report_init_view();
2368 stats_report_event_types_menu("byuser", NULL);
2369 db_prepare(&query,
2370 "SELECT user, "
2371 "COUNT(*) AS eventCount "
2372 "FROM v_reports "
2373 "GROUP BY user ORDER BY eventCount DESC");
 
 
 
2374 @ <h1>Timeline Events
2375 @ (%s(stats_report_label_for_type())) by User</h1>
2376 @ <table class='statistics-report-table-events' border='0'
2377 @ cellpadding='2' cellspacing='0' id='statsTable'>
2378 @ <thead><tr>
@@ -2388,28 +2423,24 @@
2423 Stmt query = empty_Stmt;
2424 int nRowNumber = 0; /* current TR number */
2425 int nEventTotal = 0; /* Total event count */
2426 int rowClass = 0; /* counter for alternating
2427 row colors */
 
2428 int nMaxEvents = 1; /* max number of events for
2429 all rows. */
2430 static const char *const daysOfWeek[] = {
2431 "Monday", "Tuesday", "Wednesday", "Thursday",
2432 "Friday", "Saturday", "Sunday"
2433 };
2434
2435 stats_report_init_view();
2436 stats_report_event_types_menu("byweekday", NULL);
2437 db_prepare(&query,
2438 "SELECT cast(mtime %% 7 AS INTEGER) dow, "
2439 "COUNT(*) AS eventCount "
2440 "FROM v_reports "
2441 "GROUP BY dow ORDER BY dow");
 
 
 
2442 @ <h1>Timeline Events
2443 @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
2444 @ <table class='statistics-report-table-events' border='0'
2445 @ cellpadding='2' cellspacing='0' id='statsTable'>
2446 @ <thead><tr>
@@ -2477,14 +2508,14 @@
2508 }
2509 blob_append(&sql,
2510 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2511 "FROM v_reports WHERE 1 ", -1);
2512 if(zUserName&&*zUserName){
2513 blob_append_sql(&sql,"AND user=%Q ", zUserName);
2514 }
2515 blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2516 db_prepare(&qYears, "%s", blob_sql_text(&sql));
2517 blob_reset(&sql);
2518 cgi_printf("Select year: ");
2519 while( SQLITE_ROW == db_step(&qYears) ){
2520 const char *zT = db_column_text(&qYears, 0);
2521 if( i++ ){
@@ -2510,22 +2541,22 @@
2541 int total = 0;
2542 Blob header = empty_blob;
2543 blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
2544 "of %h", stats_report_label_for_type(),
2545 zYear);
2546 blob_append_sql(&sql,
2547 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2548 "count(*) AS n "
2549 "FROM v_reports "
2550 "WHERE %Q=substr(date(mtime),1,4) "
2551 "AND mtime < current_timestamp ",
2552 zYear);
2553 if(zUserName&&*zUserName){
2554 blob_append_sql(&sql, " AND user=%Q ", zUserName);
2555 blob_appendf(&header," for user %h", zUserName);
2556 }
2557 blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC");
2558 cgi_printf("<h1>%h</h1>", blob_str(&header));
2559 blob_reset(&header);
2560 cgi_printf("<table class='statistics-report-table-events' "
2561 "border='0' cellpadding='2' width='100%%' "
2562 "cellspacing='0' id='statsTable'>");
@@ -2533,11 +2564,11 @@
2564 "<th>Week</th>"
2565 "<th>Events</th>"
2566 "<th width='90%%'><!-- relative commits graph --></th>"
2567 "</tr></thead>"
2568 "<tbody>");
2569 db_prepare(&stWeek, "%s", blob_sql_text(&sql));
2570 blob_reset(&sql);
2571 while( SQLITE_ROW == db_step(&stWeek) ){
2572 const int nCount = db_column_int(&stWeek, 1);
2573 if(nCount>nMaxEvents){
2574 nMaxEvents = nCount;
2575
+21 -23
--- src/tkt.c
+++ src/tkt.c
@@ -203,13 +203,13 @@
203203
tktid = db_last_insert_rowid();
204204
}
205205
blob_zero(&sql1);
206206
blob_zero(&sql2);
207207
blob_zero(&sql3);
208
- blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
208
+ blob_append_sql(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
209209
if( haveTicketCTime ){
210
- blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
210
+ blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
211211
}
212212
aUsed = fossil_malloc( nField );
213213
memset(aUsed, 0, nField);
214214
for(i=0; i<p->nField; i++){
215215
const char *zName = p->aField[i].zName;
@@ -218,55 +218,56 @@
218218
if( j<0 ) continue;
219219
aUsed[j] = 1;
220220
if( aField[j].mUsed & USEDBY_TICKET ){
221221
if( zName[0]=='+' ){
222222
zName++;
223
- blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
223
+ blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
224224
zName, zName, p->aField[i].zValue);
225225
}else{
226
- blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
226
+ blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue);
227227
}
228228
}
229229
if( aField[j].mUsed & USEDBY_TICKETCHNG ){
230
- blob_appendf(&sql2, ",%s", zName);
231
- blob_appendf(&sql3, ",%Q", p->aField[i].zValue);
230
+ blob_append_sql(&sql2, ",\"%w\"", zName);
231
+ blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
232232
}
233233
if( rid>0 ){
234234
wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
235235
}
236236
}
237
- blob_appendf(&sql1, " WHERE tkt_id=%d", tktid);
238
- db_prepare(&q, "%s", blob_str(&sql1));
237
+ blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
238
+ db_prepare(&q, "%s", blob_sql_text(&sql1));
239239
db_bind_double(&q, ":mtime", p->rDate);
240240
db_step(&q);
241241
db_finalize(&q);
242242
blob_reset(&sql1);
243243
if( blob_size(&sql2)>0 || haveTicketChngRid ){
244244
int fromTkt = 0;
245245
if( haveTicketChngRid ){
246246
blob_append(&sql2, ",tkt_rid", -1);
247
- blob_appendf(&sql3, ",%d", rid);
247
+ blob_append_sql(&sql3, ",%d", rid);
248248
}
249249
for(i=0; i<nField; i++){
250250
if( aUsed[i]==0
251251
&& (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
252252
){
253253
const char *z = aField[i].zName;
254254
if( z[0]=='+' ) z++;
255255
fromTkt = 1;
256
- blob_appendf(&sql2, ",%s", z);
257
- blob_appendf(&sql3, ",%s", z);
256
+ blob_append_sql(&sql2, ",\"%w\"", z);
257
+ blob_append_sql(&sql3, ",\"%w\"", z);
258258
}
259259
}
260260
if( fromTkt ){
261261
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
262262
"SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
263
- blob_str(&sql2), tktid, blob_str(&sql3), tktid);
263
+ blob_sql_text(&sql2), tktid,
264
+ blob_sql_text(&sql3), tktid);
264265
}else{
265266
db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
266267
"VALUES(%d,:mtime%s)",
267
- blob_str(&sql2), tktid, blob_str(&sql3));
268
+ blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
268269
}
269270
db_bind_double(&q, ":mtime", p->rDate);
270271
db_step(&q);
271272
db_finalize(&q);
272273
}
@@ -368,11 +369,11 @@
368369
zSql = ticket_table_schema();
369370
if( separateConnection ){
370371
db_end_transaction(0);
371372
db_init_database(g.zRepositoryName, zSql, 0);
372373
}else{
373
- db_multi_exec("%s", zSql);
374
+ db_multi_exec("%s", zSql/*safe-for-%s*/);
374375
}
375376
}
376377
377378
/*
378379
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
@@ -551,11 +552,11 @@
551552
fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
552553
}
553554
if( needMod ){
554555
moderation_table_create();
555556
db_multi_exec(
556
- "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
557
+ "INSERT INTO modreq(objid, tktid) VALUES(%d,%Q)",
557558
rid, zTktId
558559
);
559560
}else{
560561
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
561562
db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
@@ -855,12 +856,11 @@
855856
if( zType[0]=='c' ){
856857
zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
857858
}else{
858859
zTitle = mprintf("Timeline Of Ticket %h", zUuid);
859860
}
860
- style_header(zTitle);
861
- free(zTitle);
861
+ style_header("%z", zTitle);
862862
863863
sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
864864
canonical16(zGlobPattern, strlen(zGlobPattern));
865865
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
866866
if( tagid==0 ){
@@ -889,12 +889,11 @@
889889
" WHERE target=%Q) "
890890
"ORDER BY mtime DESC",
891891
timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
892892
);
893893
}
894
- db_prepare(&q, zSQL);
895
- free(zSQL);
894
+ db_prepare(&q, "%z", zSQL/*safe-for-%s*/);
896895
www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
897896
0, 0, 0);
898897
db_finalize(&q);
899898
style_footer();
900899
}
@@ -927,12 +926,11 @@
927926
"%R/tkthistory/%s", zUuid);
928927
}else{
929928
style_submenu_element("Plaintext", "Plaintext",
930929
"%R/tkthistory/%s?plaintext", zUuid);
931930
}
932
- style_header(zTitle);
933
- free(zTitle);
931
+ style_header("%z", zTitle);
934932
935933
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
936934
if( tagid==0 ){
937935
@ No such ticket: %h(zUuid)
938936
style_footer();
@@ -1213,11 +1211,11 @@
12131211
}
12141212
if( g.argc==3 ){
12151213
usage("set|change|history TICKETUUID");
12161214
}
12171215
zTktUuid = db_text(0,
1218
- "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3]
1216
+ "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%q*'", g.argv[3]
12191217
);
12201218
if( !zTktUuid ){
12211219
fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
12221220
}
12231221
i=4;
@@ -1292,11 +1290,11 @@
12921290
}else{
12931291
fossil_print(" Change ");
12941292
}
12951293
fossil_print("%h: ",z);
12961294
if( blob_size(&val)>50 || contains_newline(&val)) {
1297
- fossil_print("\n ",blob_str(&val));
1295
+ fossil_print("\n ");
12981296
comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
12991297
}else{
13001298
fossil_print("%s\n",blob_str(&val));
13011299
}
13021300
blob_reset(&val);
13031301
--- src/tkt.c
+++ src/tkt.c
@@ -203,13 +203,13 @@
203 tktid = db_last_insert_rowid();
204 }
205 blob_zero(&sql1);
206 blob_zero(&sql2);
207 blob_zero(&sql3);
208 blob_appendf(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
209 if( haveTicketCTime ){
210 blob_appendf(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
211 }
212 aUsed = fossil_malloc( nField );
213 memset(aUsed, 0, nField);
214 for(i=0; i<p->nField; i++){
215 const char *zName = p->aField[i].zName;
@@ -218,55 +218,56 @@
218 if( j<0 ) continue;
219 aUsed[j] = 1;
220 if( aField[j].mUsed & USEDBY_TICKET ){
221 if( zName[0]=='+' ){
222 zName++;
223 blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
224 zName, zName, p->aField[i].zValue);
225 }else{
226 blob_appendf(&sql1,", %s=%Q", zName, p->aField[i].zValue);
227 }
228 }
229 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
230 blob_appendf(&sql2, ",%s", zName);
231 blob_appendf(&sql3, ",%Q", p->aField[i].zValue);
232 }
233 if( rid>0 ){
234 wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
235 }
236 }
237 blob_appendf(&sql1, " WHERE tkt_id=%d", tktid);
238 db_prepare(&q, "%s", blob_str(&sql1));
239 db_bind_double(&q, ":mtime", p->rDate);
240 db_step(&q);
241 db_finalize(&q);
242 blob_reset(&sql1);
243 if( blob_size(&sql2)>0 || haveTicketChngRid ){
244 int fromTkt = 0;
245 if( haveTicketChngRid ){
246 blob_append(&sql2, ",tkt_rid", -1);
247 blob_appendf(&sql3, ",%d", rid);
248 }
249 for(i=0; i<nField; i++){
250 if( aUsed[i]==0
251 && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
252 ){
253 const char *z = aField[i].zName;
254 if( z[0]=='+' ) z++;
255 fromTkt = 1;
256 blob_appendf(&sql2, ",%s", z);
257 blob_appendf(&sql3, ",%s", z);
258 }
259 }
260 if( fromTkt ){
261 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
262 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
263 blob_str(&sql2), tktid, blob_str(&sql3), tktid);
 
264 }else{
265 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
266 "VALUES(%d,:mtime%s)",
267 blob_str(&sql2), tktid, blob_str(&sql3));
268 }
269 db_bind_double(&q, ":mtime", p->rDate);
270 db_step(&q);
271 db_finalize(&q);
272 }
@@ -368,11 +369,11 @@
368 zSql = ticket_table_schema();
369 if( separateConnection ){
370 db_end_transaction(0);
371 db_init_database(g.zRepositoryName, zSql, 0);
372 }else{
373 db_multi_exec("%s", zSql);
374 }
375 }
376
377 /*
378 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
@@ -551,11 +552,11 @@
551 fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
552 }
553 if( needMod ){
554 moderation_table_create();
555 db_multi_exec(
556 "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
557 rid, zTktId
558 );
559 }else{
560 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
561 db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
@@ -855,12 +856,11 @@
855 if( zType[0]=='c' ){
856 zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
857 }else{
858 zTitle = mprintf("Timeline Of Ticket %h", zUuid);
859 }
860 style_header(zTitle);
861 free(zTitle);
862
863 sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
864 canonical16(zGlobPattern, strlen(zGlobPattern));
865 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
866 if( tagid==0 ){
@@ -889,12 +889,11 @@
889 " WHERE target=%Q) "
890 "ORDER BY mtime DESC",
891 timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
892 );
893 }
894 db_prepare(&q, zSQL);
895 free(zSQL);
896 www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
897 0, 0, 0);
898 db_finalize(&q);
899 style_footer();
900 }
@@ -927,12 +926,11 @@
927 "%R/tkthistory/%s", zUuid);
928 }else{
929 style_submenu_element("Plaintext", "Plaintext",
930 "%R/tkthistory/%s?plaintext", zUuid);
931 }
932 style_header(zTitle);
933 free(zTitle);
934
935 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
936 if( tagid==0 ){
937 @ No such ticket: %h(zUuid)
938 style_footer();
@@ -1213,11 +1211,11 @@
1213 }
1214 if( g.argc==3 ){
1215 usage("set|change|history TICKETUUID");
1216 }
1217 zTktUuid = db_text(0,
1218 "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", g.argv[3]
1219 );
1220 if( !zTktUuid ){
1221 fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
1222 }
1223 i=4;
@@ -1292,11 +1290,11 @@
1292 }else{
1293 fossil_print(" Change ");
1294 }
1295 fossil_print("%h: ",z);
1296 if( blob_size(&val)>50 || contains_newline(&val)) {
1297 fossil_print("\n ",blob_str(&val));
1298 comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
1299 }else{
1300 fossil_print("%s\n",blob_str(&val));
1301 }
1302 blob_reset(&val);
1303
--- src/tkt.c
+++ src/tkt.c
@@ -203,13 +203,13 @@
203 tktid = db_last_insert_rowid();
204 }
205 blob_zero(&sql1);
206 blob_zero(&sql2);
207 blob_zero(&sql3);
208 blob_append_sql(&sql1, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
209 if( haveTicketCTime ){
210 blob_append_sql(&sql1, ", tkt_ctime=coalesce(tkt_ctime,:mtime)");
211 }
212 aUsed = fossil_malloc( nField );
213 memset(aUsed, 0, nField);
214 for(i=0; i<p->nField; i++){
215 const char *zName = p->aField[i].zName;
@@ -218,55 +218,56 @@
218 if( j<0 ) continue;
219 aUsed[j] = 1;
220 if( aField[j].mUsed & USEDBY_TICKET ){
221 if( zName[0]=='+' ){
222 zName++;
223 blob_append_sql(&sql1,", \"%w\"=coalesce(\"%w\",'') || %Q",
224 zName, zName, p->aField[i].zValue);
225 }else{
226 blob_append_sql(&sql1,", \"%w\"=%Q", zName, p->aField[i].zValue);
227 }
228 }
229 if( aField[j].mUsed & USEDBY_TICKETCHNG ){
230 blob_append_sql(&sql2, ",\"%w\"", zName);
231 blob_append_sql(&sql3, ",%Q", p->aField[i].zValue);
232 }
233 if( rid>0 ){
234 wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0);
235 }
236 }
237 blob_append_sql(&sql1, " WHERE tkt_id=%d", tktid);
238 db_prepare(&q, "%s", blob_sql_text(&sql1));
239 db_bind_double(&q, ":mtime", p->rDate);
240 db_step(&q);
241 db_finalize(&q);
242 blob_reset(&sql1);
243 if( blob_size(&sql2)>0 || haveTicketChngRid ){
244 int fromTkt = 0;
245 if( haveTicketChngRid ){
246 blob_append(&sql2, ",tkt_rid", -1);
247 blob_append_sql(&sql3, ",%d", rid);
248 }
249 for(i=0; i<nField; i++){
250 if( aUsed[i]==0
251 && (aField[i].mUsed & USEDBY_BOTH)==USEDBY_BOTH
252 ){
253 const char *z = aField[i].zName;
254 if( z[0]=='+' ) z++;
255 fromTkt = 1;
256 blob_append_sql(&sql2, ",\"%w\"", z);
257 blob_append_sql(&sql3, ",\"%w\"", z);
258 }
259 }
260 if( fromTkt ){
261 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
262 "SELECT %d,:mtime%s FROM ticket WHERE tkt_id=%d",
263 blob_sql_text(&sql2), tktid,
264 blob_sql_text(&sql3), tktid);
265 }else{
266 db_prepare(&q, "INSERT INTO ticketchng(tkt_id,tkt_mtime%s)"
267 "VALUES(%d,:mtime%s)",
268 blob_sql_text(&sql2), tktid, blob_sql_text(&sql3));
269 }
270 db_bind_double(&q, ":mtime", p->rDate);
271 db_step(&q);
272 db_finalize(&q);
273 }
@@ -368,11 +369,11 @@
369 zSql = ticket_table_schema();
370 if( separateConnection ){
371 db_end_transaction(0);
372 db_init_database(g.zRepositoryName, zSql, 0);
373 }else{
374 db_multi_exec("%s", zSql/*safe-for-%s*/);
375 }
376 }
377
378 /*
379 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
@@ -551,11 +552,11 @@
552 fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
553 }
554 if( needMod ){
555 moderation_table_create();
556 db_multi_exec(
557 "INSERT INTO modreq(objid, tktid) VALUES(%d,%Q)",
558 rid, zTktId
559 );
560 }else{
561 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d);", rid);
562 db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", rid);
@@ -855,12 +856,11 @@
856 if( zType[0]=='c' ){
857 zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
858 }else{
859 zTitle = mprintf("Timeline Of Ticket %h", zUuid);
860 }
861 style_header("%z", zTitle);
 
862
863 sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
864 canonical16(zGlobPattern, strlen(zGlobPattern));
865 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
866 if( tagid==0 ){
@@ -889,12 +889,11 @@
889 " WHERE target=%Q) "
890 "ORDER BY mtime DESC",
891 timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
892 );
893 }
894 db_prepare(&q, "%z", zSQL/*safe-for-%s*/);
 
895 www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
896 0, 0, 0);
897 db_finalize(&q);
898 style_footer();
899 }
@@ -927,12 +926,11 @@
926 "%R/tkthistory/%s", zUuid);
927 }else{
928 style_submenu_element("Plaintext", "Plaintext",
929 "%R/tkthistory/%s?plaintext", zUuid);
930 }
931 style_header("%z", zTitle);
 
932
933 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
934 if( tagid==0 ){
935 @ No such ticket: %h(zUuid)
936 style_footer();
@@ -1213,11 +1211,11 @@
1211 }
1212 if( g.argc==3 ){
1213 usage("set|change|history TICKETUUID");
1214 }
1215 zTktUuid = db_text(0,
1216 "SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%q*'", g.argv[3]
1217 );
1218 if( !zTktUuid ){
1219 fossil_fatal("unknown ticket: '%s'!",g.argv[3]);
1220 }
1221 i=4;
@@ -1292,11 +1290,11 @@
1290 }else{
1291 fossil_print(" Change ");
1292 }
1293 fossil_print("%h: ",z);
1294 if( blob_size(&val)>50 || contains_newline(&val)) {
1295 fossil_print("\n ");
1296 comment_print(blob_str(&val),0,4,-1,g.comFmtFlags);
1297 }else{
1298 fossil_print("%s\n",blob_str(&val));
1299 }
1300 blob_reset(&val);
1301
+7 -7
--- src/translate.c
+++ src/translate.c
@@ -13,11 +13,11 @@
1313
** [email protected]
1414
** http://www.hwaci.com/drh/
1515
**
1616
*******************************************************************************
1717
**
18
-** SYNOPSIS:
18
+** SYNOPSIS:
1919
**
2020
** Input lines that begin with the "@" character are translated into
2121
** either cgi_printf() statements or string literals and the
2222
** translated code is written on standard output.
2323
**
@@ -34,22 +34,22 @@
3434
** punctuation.
3535
**
3636
** Enhancement #1:
3737
**
3838
** If the last non-whitespace character prior to the first "@" of a
39
-** @-block is "=" or "," then the @-block is a string literal initializer
39
+** @-block is "=" or "," then the @-block is a string literal initializer
4040
** rather than text that is to be output via cgi_printf(). Render it
4141
** as such.
4242
**
4343
** Enhancement #2:
4444
**
45
-** Comments of the form: "/* @-comment: CC" cause CC to become a
45
+** Comments of the form: "/* @-comment: CC" cause CC to become a
4646
** comment character for the @-substitution. Typical values for CC are
4747
** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
4848
** Lines of subsequent @-blocks that begin with CC are omitted from the
4949
** output.
50
-**
50
+**
5151
*/
5252
#include <stdio.h>
5353
#include <ctype.h>
5454
#include <stdlib.h>
5555
#include <string.h>
@@ -122,11 +122,11 @@
122122
indent = i - 2;
123123
if( indent<0 ) indent = 0;
124124
omitline = 0;
125125
for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
126126
if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
127
- omitline = 1; break;
127
+ omitline = 1; break;
128128
}
129129
if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
130130
zOut[j++] = zLine[i];
131131
}
132132
while( j>0 && isspace(zOut[j-1]) ){ j--; }
@@ -137,11 +137,11 @@
137137
fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
138138
}
139139
}else{
140140
/* Otherwise (if the last non-whitespace was not '=') then generate
141141
** a cgi_printf() statement whose format is the text following the '@'.
142
- ** Substrings of the form "%C(...)" (where C is any sequence of
142
+ ** Substrings of the form "%C(...)" (where C is any sequence of
143143
** characters other than \000 and '(') will put "%C" in the
144144
** format and add the "(...)" as an argument to the cgi_printf call.
145145
*/
146146
int indent;
147147
int nC;
@@ -174,11 +174,11 @@
174174
fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
175175
inPrint = 1;
176176
}else{
177177
fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
178178
}
179
- }
179
+ }
180180
}
181181
}
182182
183183
int main(int argc, char **argv){
184184
if( argc==2 ){
185185
--- src/translate.c
+++ src/translate.c
@@ -13,11 +13,11 @@
13 ** [email protected]
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** SYNOPSIS:
19 **
20 ** Input lines that begin with the "@" character are translated into
21 ** either cgi_printf() statements or string literals and the
22 ** translated code is written on standard output.
23 **
@@ -34,22 +34,22 @@
34 ** punctuation.
35 **
36 ** Enhancement #1:
37 **
38 ** If the last non-whitespace character prior to the first "@" of a
39 ** @-block is "=" or "," then the @-block is a string literal initializer
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "/* @-comment: CC" cause CC to become a
46 ** comment character for the @-substitution. Typical values for CC are
47 ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48 ** Lines of subsequent @-blocks that begin with CC are omitted from the
49 ** output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55 #include <string.h>
@@ -122,11 +122,11 @@
122 indent = i - 2;
123 if( indent<0 ) indent = 0;
124 omitline = 0;
125 for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
126 if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
127 omitline = 1; break;
128 }
129 if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
130 zOut[j++] = zLine[i];
131 }
132 while( j>0 && isspace(zOut[j-1]) ){ j--; }
@@ -137,11 +137,11 @@
137 fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
138 }
139 }else{
140 /* Otherwise (if the last non-whitespace was not '=') then generate
141 ** a cgi_printf() statement whose format is the text following the '@'.
142 ** Substrings of the form "%C(...)" (where C is any sequence of
143 ** characters other than \000 and '(') will put "%C" in the
144 ** format and add the "(...)" as an argument to the cgi_printf call.
145 */
146 int indent;
147 int nC;
@@ -174,11 +174,11 @@
174 fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
175 inPrint = 1;
176 }else{
177 fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
178 }
179 }
180 }
181 }
182
183 int main(int argc, char **argv){
184 if( argc==2 ){
185
--- src/translate.c
+++ src/translate.c
@@ -13,11 +13,11 @@
13 ** [email protected]
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** SYNOPSIS:
19 **
20 ** Input lines that begin with the "@" character are translated into
21 ** either cgi_printf() statements or string literals and the
22 ** translated code is written on standard output.
23 **
@@ -34,22 +34,22 @@
34 ** punctuation.
35 **
36 ** Enhancement #1:
37 **
38 ** If the last non-whitespace character prior to the first "@" of a
39 ** @-block is "=" or "," then the @-block is a string literal initializer
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "/* @-comment: CC" cause CC to become a
46 ** comment character for the @-substitution. Typical values for CC are
47 ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48 ** Lines of subsequent @-blocks that begin with CC are omitted from the
49 ** output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55 #include <string.h>
@@ -122,11 +122,11 @@
122 indent = i - 2;
123 if( indent<0 ) indent = 0;
124 omitline = 0;
125 for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
126 if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
127 omitline = 1; break;
128 }
129 if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
130 zOut[j++] = zLine[i];
131 }
132 while( j>0 && isspace(zOut[j-1]) ){ j--; }
@@ -137,11 +137,11 @@
137 fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
138 }
139 }else{
140 /* Otherwise (if the last non-whitespace was not '=') then generate
141 ** a cgi_printf() statement whose format is the text following the '@'.
142 ** Substrings of the form "%C(...)" (where C is any sequence of
143 ** characters other than \000 and '(') will put "%C" in the
144 ** format and add the "(...)" as an argument to the cgi_printf call.
145 */
146 int indent;
147 int nC;
@@ -174,11 +174,11 @@
174 fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
175 inPrint = 1;
176 }else{
177 fprintf(out,"\n%*s\"%s\\n\"",indent+5, "", zOut);
178 }
179 }
180 }
181 }
182
183 int main(int argc, char **argv){
184 if( argc==2 ){
185
+9 -8
--- src/undo.c
+++ src/undo.c
@@ -143,11 +143,12 @@
143143
"INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144144
"DELETE FROM undo_vmerge;"
145145
"INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146146
"DROP TABLE undo_vmerge_2;"
147147
);
148
- if(db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='undo_stash'", zDb) ){
148
+ if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
149
+ " WHERE name='undo_stash'", zDb) ){
149150
if( redoFlag ){
150151
db_multi_exec(
151152
"DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
152153
"DELETE FROM stashfile"
153154
" WHERE stashid NOT IN (SELECT stashid FROM stash);"
@@ -174,11 +175,11 @@
174175
@ DROP TABLE IF EXISTS undo_vfile;
175176
@ DROP TABLE IF EXISTS undo_vmerge;
176177
@ DROP TABLE IF EXISTS undo_stash;
177178
@ DROP TABLE IF EXISTS undo_stashfile;
178179
;
179
- db_multi_exec(zSql);
180
+ db_multi_exec(zSql /*works-like:""*/);
180181
db_lset_int("undo_available", 0);
181182
db_lset_int("undo_checkout", 0);
182183
}
183184
184185
/*
@@ -219,24 +220,24 @@
219220
*/
220221
void undo_begin(void){
221222
int cid;
222223
const char *zDb = db_name("localdb");
223224
static const char zSql[] =
224
- @ CREATE TABLE %s.undo(
225
+ @ CREATE TABLE "%w".undo(
225226
@ pathname TEXT UNIQUE, -- Name of the file
226227
@ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
227228
@ existsflag BOOLEAN, -- True if the file exists
228229
@ isExe BOOLEAN, -- True if the file is executable
229230
@ isLink BOOLEAN, -- True if the file is symlink
230231
@ content BLOB -- Saved content
231232
@ );
232
- @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
233
- @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
233
+ @ CREATE TABLE "%w".undo_vfile AS SELECT * FROM vfile;
234
+ @ CREATE TABLE "%w".undo_vmerge AS SELECT * FROM vmerge;
234235
;
235236
if( undoDisable ) return;
236237
undo_reset();
237
- db_multi_exec(zSql, zDb, zDb, zDb);
238
+ db_multi_exec(zSql/*works-like:"%w,%w,%w"*/, zDb, zDb, zDb);
238239
cid = db_lget_int("checkout", 0);
239240
db_lset_int("undo_checkout", cid);
240241
db_lset_int("undo_available", 1);
241242
db_lset("undo_cmdline", undoCmd);
242243
undoActive = 1;
@@ -301,18 +302,18 @@
301302
** Make the current state of stashid undoable.
302303
*/
303304
void undo_save_stash(int stashid){
304305
const char *zDb = db_name("localdb");
305306
db_multi_exec(
306
- "CREATE TABLE IF NOT EXISTS %s.undo_stash"
307
+ "CREATE TABLE IF NOT EXISTS \"%w\".undo_stash"
307308
" AS SELECT * FROM stash WHERE 0;"
308309
"INSERT INTO undo_stash"
309310
" SELECT * FROM stash WHERE stashid=%d;",
310311
zDb, stashid
311312
);
312313
db_multi_exec(
313
- "CREATE TABLE IF NOT EXISTS %s.undo_stashfile"
314
+ "CREATE TABLE IF NOT EXISTS \"%w\".undo_stashfile"
314315
" AS SELECT * FROM stashfile WHERE 0;"
315316
"INSERT INTO undo_stashfile"
316317
" SELECT * FROM stashfile WHERE stashid=%d;",
317318
zDb, stashid
318319
);
319320
--- src/undo.c
+++ src/undo.c
@@ -143,11 +143,12 @@
143 "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144 "DELETE FROM undo_vmerge;"
145 "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146 "DROP TABLE undo_vmerge_2;"
147 );
148 if(db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='undo_stash'", zDb) ){
 
149 if( redoFlag ){
150 db_multi_exec(
151 "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
152 "DELETE FROM stashfile"
153 " WHERE stashid NOT IN (SELECT stashid FROM stash);"
@@ -174,11 +175,11 @@
174 @ DROP TABLE IF EXISTS undo_vfile;
175 @ DROP TABLE IF EXISTS undo_vmerge;
176 @ DROP TABLE IF EXISTS undo_stash;
177 @ DROP TABLE IF EXISTS undo_stashfile;
178 ;
179 db_multi_exec(zSql);
180 db_lset_int("undo_available", 0);
181 db_lset_int("undo_checkout", 0);
182 }
183
184 /*
@@ -219,24 +220,24 @@
219 */
220 void undo_begin(void){
221 int cid;
222 const char *zDb = db_name("localdb");
223 static const char zSql[] =
224 @ CREATE TABLE %s.undo(
225 @ pathname TEXT UNIQUE, -- Name of the file
226 @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
227 @ existsflag BOOLEAN, -- True if the file exists
228 @ isExe BOOLEAN, -- True if the file is executable
229 @ isLink BOOLEAN, -- True if the file is symlink
230 @ content BLOB -- Saved content
231 @ );
232 @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
233 @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
234 ;
235 if( undoDisable ) return;
236 undo_reset();
237 db_multi_exec(zSql, zDb, zDb, zDb);
238 cid = db_lget_int("checkout", 0);
239 db_lset_int("undo_checkout", cid);
240 db_lset_int("undo_available", 1);
241 db_lset("undo_cmdline", undoCmd);
242 undoActive = 1;
@@ -301,18 +302,18 @@
301 ** Make the current state of stashid undoable.
302 */
303 void undo_save_stash(int stashid){
304 const char *zDb = db_name("localdb");
305 db_multi_exec(
306 "CREATE TABLE IF NOT EXISTS %s.undo_stash"
307 " AS SELECT * FROM stash WHERE 0;"
308 "INSERT INTO undo_stash"
309 " SELECT * FROM stash WHERE stashid=%d;",
310 zDb, stashid
311 );
312 db_multi_exec(
313 "CREATE TABLE IF NOT EXISTS %s.undo_stashfile"
314 " AS SELECT * FROM stashfile WHERE 0;"
315 "INSERT INTO undo_stashfile"
316 " SELECT * FROM stashfile WHERE stashid=%d;",
317 zDb, stashid
318 );
319
--- src/undo.c
+++ src/undo.c
@@ -143,11 +143,12 @@
143 "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144 "DELETE FROM undo_vmerge;"
145 "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146 "DROP TABLE undo_vmerge_2;"
147 );
148 if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
149 " WHERE name='undo_stash'", zDb) ){
150 if( redoFlag ){
151 db_multi_exec(
152 "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
153 "DELETE FROM stashfile"
154 " WHERE stashid NOT IN (SELECT stashid FROM stash);"
@@ -174,11 +175,11 @@
175 @ DROP TABLE IF EXISTS undo_vfile;
176 @ DROP TABLE IF EXISTS undo_vmerge;
177 @ DROP TABLE IF EXISTS undo_stash;
178 @ DROP TABLE IF EXISTS undo_stashfile;
179 ;
180 db_multi_exec(zSql /*works-like:""*/);
181 db_lset_int("undo_available", 0);
182 db_lset_int("undo_checkout", 0);
183 }
184
185 /*
@@ -219,24 +220,24 @@
220 */
221 void undo_begin(void){
222 int cid;
223 const char *zDb = db_name("localdb");
224 static const char zSql[] =
225 @ CREATE TABLE "%w".undo(
226 @ pathname TEXT UNIQUE, -- Name of the file
227 @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
228 @ existsflag BOOLEAN, -- True if the file exists
229 @ isExe BOOLEAN, -- True if the file is executable
230 @ isLink BOOLEAN, -- True if the file is symlink
231 @ content BLOB -- Saved content
232 @ );
233 @ CREATE TABLE "%w".undo_vfile AS SELECT * FROM vfile;
234 @ CREATE TABLE "%w".undo_vmerge AS SELECT * FROM vmerge;
235 ;
236 if( undoDisable ) return;
237 undo_reset();
238 db_multi_exec(zSql/*works-like:"%w,%w,%w"*/, zDb, zDb, zDb);
239 cid = db_lget_int("checkout", 0);
240 db_lset_int("undo_checkout", cid);
241 db_lset_int("undo_available", 1);
242 db_lset("undo_cmdline", undoCmd);
243 undoActive = 1;
@@ -301,18 +302,18 @@
302 ** Make the current state of stashid undoable.
303 */
304 void undo_save_stash(int stashid){
305 const char *zDb = db_name("localdb");
306 db_multi_exec(
307 "CREATE TABLE IF NOT EXISTS \"%w\".undo_stash"
308 " AS SELECT * FROM stash WHERE 0;"
309 "INSERT INTO undo_stash"
310 " SELECT * FROM stash WHERE stashid=%d;",
311 zDb, stashid
312 );
313 db_multi_exec(
314 "CREATE TABLE IF NOT EXISTS \"%w\".undo_stashfile"
315 " AS SELECT * FROM stashfile WHERE 0;"
316 "INSERT INTO undo_stashfile"
317 " SELECT * FROM stashfile WHERE stashid=%d;",
318 zDb, stashid
319 );
320
+5 -3
--- src/update.c
+++ src/update.c
@@ -357,22 +357,24 @@
357357
zSep = "";
358358
for(i=3; i<g.argc; i++){
359359
file_tree_name(g.argv[i], &treename, 1);
360360
if( file_wd_isdir(g.argv[i])==1 ){
361361
if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
362
- blob_appendf(&sql, "%sfn NOT GLOB '%b/*' ", zSep, &treename);
362
+ blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ",
363
+ zSep /*safe-for-%s*/, blob_str(&treename));
363364
}else{
364365
blob_reset(&sql);
365366
break;
366367
}
367368
}else{
368
- blob_appendf(&sql, "%sfn<>%B ", zSep, &treename);
369
+ blob_append_sql(&sql, "%sfn<>%Q ",
370
+ zSep /*safe-for-%s*/, blob_str(&treename));
369371
}
370372
zSep = "AND ";
371373
blob_reset(&treename);
372374
}
373
- db_multi_exec(blob_str(&sql));
375
+ db_multi_exec("%s", blob_sql_text(&sql));
374376
blob_reset(&sql);
375377
}
376378
377379
/*
378380
** Alter the content of the checkout so that it conforms with the
379381
--- src/update.c
+++ src/update.c
@@ -357,22 +357,24 @@
357 zSep = "";
358 for(i=3; i<g.argc; i++){
359 file_tree_name(g.argv[i], &treename, 1);
360 if( file_wd_isdir(g.argv[i])==1 ){
361 if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
362 blob_appendf(&sql, "%sfn NOT GLOB '%b/*' ", zSep, &treename);
 
363 }else{
364 blob_reset(&sql);
365 break;
366 }
367 }else{
368 blob_appendf(&sql, "%sfn<>%B ", zSep, &treename);
 
369 }
370 zSep = "AND ";
371 blob_reset(&treename);
372 }
373 db_multi_exec(blob_str(&sql));
374 blob_reset(&sql);
375 }
376
377 /*
378 ** Alter the content of the checkout so that it conforms with the
379
--- src/update.c
+++ src/update.c
@@ -357,22 +357,24 @@
357 zSep = "";
358 for(i=3; i<g.argc; i++){
359 file_tree_name(g.argv[i], &treename, 1);
360 if( file_wd_isdir(g.argv[i])==1 ){
361 if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
362 blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ",
363 zSep /*safe-for-%s*/, blob_str(&treename));
364 }else{
365 blob_reset(&sql);
366 break;
367 }
368 }else{
369 blob_append_sql(&sql, "%sfn<>%Q ",
370 zSep /*safe-for-%s*/, blob_str(&treename));
371 }
372 zSep = "AND ";
373 blob_reset(&treename);
374 }
375 db_multi_exec("%s", blob_sql_text(&sql));
376 blob_reset(&sql);
377 }
378
379 /*
380 ** Alter the content of the checkout so that it conforms with the
381
+3 -3
--- src/user.c
+++ src/user.c
@@ -451,26 +451,26 @@
451451
cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
452452
return;
453453
}
454454
style_header("Access Log");
455455
blob_zero(&sql);
456
- blob_appendf(&sql,
456
+ blob_append_sql(&sql,
457457
"SELECT uname, ipaddr, datetime(mtime%s), success"
458458
" FROM accesslog", timeline_utc()
459459
);
460460
if( y==1 ){
461461
blob_append(&sql, " WHERE success", -1);
462462
}else if( y==2 ){
463463
blob_append(&sql, " WHERE NOT success", -1);
464464
}
465
- blob_appendf(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
465
+ blob_append_sql(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
466466
if( skip ){
467467
style_submenu_element("Newer", "Newer entries",
468468
"%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
469469
n, y);
470470
}
471
- rc = db_prepare_ignore_error(&q, blob_str(&sql));
471
+ rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
472472
@ <center><table border="1" cellpadding="5">
473473
@ <tr><th width="33%%">Date</th><th width="34%%">User</th>
474474
@ <th width="33%%">IP Address</th></tr>
475475
while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
476476
const char *zName = db_column_text(&q, 0);
477477
--- src/user.c
+++ src/user.c
@@ -451,26 +451,26 @@
451 cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
452 return;
453 }
454 style_header("Access Log");
455 blob_zero(&sql);
456 blob_appendf(&sql,
457 "SELECT uname, ipaddr, datetime(mtime%s), success"
458 " FROM accesslog", timeline_utc()
459 );
460 if( y==1 ){
461 blob_append(&sql, " WHERE success", -1);
462 }else if( y==2 ){
463 blob_append(&sql, " WHERE NOT success", -1);
464 }
465 blob_appendf(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
466 if( skip ){
467 style_submenu_element("Newer", "Newer entries",
468 "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
469 n, y);
470 }
471 rc = db_prepare_ignore_error(&q, blob_str(&sql));
472 @ <center><table border="1" cellpadding="5">
473 @ <tr><th width="33%%">Date</th><th width="34%%">User</th>
474 @ <th width="33%%">IP Address</th></tr>
475 while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
476 const char *zName = db_column_text(&q, 0);
477
--- src/user.c
+++ src/user.c
@@ -451,26 +451,26 @@
451 cgi_redirectf("%s/access_log?y=%d&n=%d", g.zTop, y, n);
452 return;
453 }
454 style_header("Access Log");
455 blob_zero(&sql);
456 blob_append_sql(&sql,
457 "SELECT uname, ipaddr, datetime(mtime%s), success"
458 " FROM accesslog", timeline_utc()
459 );
460 if( y==1 ){
461 blob_append(&sql, " WHERE success", -1);
462 }else if( y==2 ){
463 blob_append(&sql, " WHERE NOT success", -1);
464 }
465 blob_append_sql(&sql," ORDER BY rowid DESC LIMIT %d OFFSET %d", n+1, skip);
466 if( skip ){
467 style_submenu_element("Newer", "Newer entries",
468 "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
469 n, y);
470 }
471 rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
472 @ <center><table border="1" cellpadding="5">
473 @ <tr><th width="33%%">Date</th><th width="34%%">User</th>
474 @ <th width="33%%">IP Address</th></tr>
475 while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
476 const char *zName = db_column_text(&q, 0);
477
+9
--- src/util.c
+++ src/util.c
@@ -78,10 +78,19 @@
7878
free(zNewCmd);
7979
#else
8080
/* On unix, evaluate the command directly.
8181
*/
8282
if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);
83
+
84
+ /* Unix systems should never shell-out while processing an HTTP request,
85
+ ** either via CGI, SCGI, or direct HTTP. The following assert verifies
86
+ ** this. And the following assert proves that Fossil is not vulnerable
87
+ ** to the ShellShock or BashDoor bug.
88
+ */
89
+ assert( g.cgiOutput==0 );
90
+
91
+ /* The regular system() call works to get a shell on unix */
8392
rc = system(zOrigCmd);
8493
#endif
8594
return rc;
8695
}
8796
8897
--- src/util.c
+++ src/util.c
@@ -78,10 +78,19 @@
78 free(zNewCmd);
79 #else
80 /* On unix, evaluate the command directly.
81 */
82 if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);
 
 
 
 
 
 
 
 
 
83 rc = system(zOrigCmd);
84 #endif
85 return rc;
86 }
87
88
--- src/util.c
+++ src/util.c
@@ -78,10 +78,19 @@
78 free(zNewCmd);
79 #else
80 /* On unix, evaluate the command directly.
81 */
82 if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);
83
84 /* Unix systems should never shell-out while processing an HTTP request,
85 ** either via CGI, SCGI, or direct HTTP. The following assert verifies
86 ** this. And the following assert proves that Fossil is not vulnerable
87 ** to the ShellShock or BashDoor bug.
88 */
89 assert( g.cgiOutput==0 );
90
91 /* The regular system() call works to get a shell on unix */
92 rc = system(zOrigCmd);
93 #endif
94 return rc;
95 }
96
97
+9
--- src/util.c
+++ src/util.c
@@ -78,10 +78,19 @@
7878
free(zNewCmd);
7979
#else
8080
/* On unix, evaluate the command directly.
8181
*/
8282
if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);
83
+
84
+ /* Unix systems should never shell-out while processing an HTTP request,
85
+ ** either via CGI, SCGI, or direct HTTP. The following assert verifies
86
+ ** this. And the following assert proves that Fossil is not vulnerable
87
+ ** to the ShellShock or BashDoor bug.
88
+ */
89
+ assert( g.cgiOutput==0 );
90
+
91
+ /* The regular system() call works to get a shell on unix */
8392
rc = system(zOrigCmd);
8493
#endif
8594
return rc;
8695
}
8796
8897
--- src/util.c
+++ src/util.c
@@ -78,10 +78,19 @@
78 free(zNewCmd);
79 #else
80 /* On unix, evaluate the command directly.
81 */
82 if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);
 
 
 
 
 
 
 
 
 
83 rc = system(zOrigCmd);
84 #endif
85 return rc;
86 }
87
88
--- src/util.c
+++ src/util.c
@@ -78,10 +78,19 @@
78 free(zNewCmd);
79 #else
80 /* On unix, evaluate the command directly.
81 */
82 if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd);
83
84 /* Unix systems should never shell-out while processing an HTTP request,
85 ** either via CGI, SCGI, or direct HTTP. The following assert verifies
86 ** this. And the following assert proves that Fossil is not vulnerable
87 ** to the ShellShock or BashDoor bug.
88 */
89 assert( g.cgiOutput==0 );
90
91 /* The regular system() call works to get a shell on unix */
92 rc = system(zOrigCmd);
93 #endif
94 return rc;
95 }
96
97
+2 -2
--- src/vfile.c
+++ src/vfile.c
@@ -397,13 +397,13 @@
397397
"original",
398398
"output",
399399
};
400400
int i, j, n;
401401
402
- if( strglob("ci-comment-????????????.txt", zName) ) return 1;
402
+ if( sqlite3_strglob("ci-comment-????????????.txt", zName)==0 ) return 1;
403403
for(; zName[0]!=0; zName++){
404
- if( zName[0]=='/' && strglob("/ci-comment-????????????.txt", zName) ){
404
+ if( zName[0]=='/' && sqlite3_strglob("/ci-comment-????????????.txt", zName)==0 ){
405405
return 1;
406406
}
407407
if( zName[0]!='-' ) continue;
408408
for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
409409
n = (int)strlen(azTemp[i]);
410410
--- src/vfile.c
+++ src/vfile.c
@@ -397,13 +397,13 @@
397 "original",
398 "output",
399 };
400 int i, j, n;
401
402 if( strglob("ci-comment-????????????.txt", zName) ) return 1;
403 for(; zName[0]!=0; zName++){
404 if( zName[0]=='/' && strglob("/ci-comment-????????????.txt", zName) ){
405 return 1;
406 }
407 if( zName[0]!='-' ) continue;
408 for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
409 n = (int)strlen(azTemp[i]);
410
--- src/vfile.c
+++ src/vfile.c
@@ -397,13 +397,13 @@
397 "original",
398 "output",
399 };
400 int i, j, n;
401
402 if( sqlite3_strglob("ci-comment-????????????.txt", zName)==0 ) return 1;
403 for(; zName[0]!=0; zName++){
404 if( zName[0]=='/' && sqlite3_strglob("/ci-comment-????????????.txt", zName)==0 ){
405 return 1;
406 }
407 if( zName[0]!='-' ) continue;
408 for(i=0; i<sizeof(azTemp)/sizeof(azTemp[0]); i++){
409 n = (int)strlen(azTemp[i]);
410
+5 -14
--- src/wiki.c
+++ src/wiki.c
@@ -292,11 +292,11 @@
292292
style_submenu_element("History", "History", "%s/whistory?name=%T",
293293
g.zTop, zPageName);
294294
}
295295
}
296296
style_set_current_page("%T?name=%T", g.zPath, zPageName);
297
- style_header(zPageName);
297
+ style_header("%s", zPageName);
298298
blob_init(&wiki, zBody, -1);
299299
wiki_render_by_mimetype(&wiki, zMimetype);
300300
blob_reset(&wiki);
301301
attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
302302
manifest_destroy(pWiki);
@@ -649,11 +649,11 @@
649649
Blob wiki;
650650
Manifest *pWiki = 0;
651651
652652
blob_zero(&body);
653653
if( isSandbox ){
654
- blob_appendf(&body, db_get("sandbox",""));
654
+ blob_append(&body, db_get("sandbox",""), -1);
655655
appendRemark(&body, zMimetype);
656656
db_set("sandbox", blob_str(&body), 0);
657657
}else{
658658
login_verify_csrf_secret();
659659
pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
@@ -746,29 +746,23 @@
746746
**
747747
** Show the complete change history for a single wiki page.
748748
*/
749749
void whistory_page(void){
750750
Stmt q;
751
- char *zTitle;
752
- char *zSQL;
753751
const char *zPageName;
754752
login_check_credentials();
755753
if( !g.perm.Hyperlink ){ login_needed(); return; }
756754
zPageName = PD("name","");
757
- zTitle = mprintf("History Of %s", zPageName);
758
- style_header(zTitle);
759
- free(zTitle);
755
+ style_header("History Of %s", zPageName);
760756
761
- zSQL = mprintf("%s AND event.objid IN "
757
+ db_prepare(&q, "%s AND event.objid IN "
762758
" (SELECT rid FROM tagxref WHERE tagid="
763759
"(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
764760
" UNION SELECT attachid FROM attachment"
765761
" WHERE target=%Q)"
766762
"ORDER BY mtime DESC",
767763
timeline_query_for_www(), zPageName, zPageName);
768
- db_prepare(&q, zSQL);
769
- free(zSQL);
770764
zWikiPageName = zPageName;
771765
www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
772766
db_finalize(&q);
773767
style_footer();
774768
}
@@ -778,11 +772,10 @@
778772
** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
779773
**
780774
** Show the difference between two wiki pages.
781775
*/
782776
void wdiff_page(void){
783
- char *zTitle;
784777
int rid1, rid2;
785778
const char *zPageName;
786779
Manifest *pW1, *pW2 = 0;
787780
Blob w1, w2, d;
788781
u64 diffFlags;
@@ -791,13 +784,11 @@
791784
rid1 = atoi(PD("a","0"));
792785
if( !g.perm.Hyperlink ){ login_needed(); return; }
793786
if( rid1==0 ) fossil_redirect_home();
794787
rid2 = atoi(PD("b","0"));
795788
zPageName = PD("name","");
796
- zTitle = mprintf("Changes To %s", zPageName);
797
- style_header(zTitle);
798
- free(zTitle);
789
+ style_header("Changes To %s", zPageName);
799790
800791
if( rid2==0 ){
801792
rid2 = db_int(0,
802793
"SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
803794
"(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
804795
--- src/wiki.c
+++ src/wiki.c
@@ -292,11 +292,11 @@
292 style_submenu_element("History", "History", "%s/whistory?name=%T",
293 g.zTop, zPageName);
294 }
295 }
296 style_set_current_page("%T?name=%T", g.zPath, zPageName);
297 style_header(zPageName);
298 blob_init(&wiki, zBody, -1);
299 wiki_render_by_mimetype(&wiki, zMimetype);
300 blob_reset(&wiki);
301 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
302 manifest_destroy(pWiki);
@@ -649,11 +649,11 @@
649 Blob wiki;
650 Manifest *pWiki = 0;
651
652 blob_zero(&body);
653 if( isSandbox ){
654 blob_appendf(&body, db_get("sandbox",""));
655 appendRemark(&body, zMimetype);
656 db_set("sandbox", blob_str(&body), 0);
657 }else{
658 login_verify_csrf_secret();
659 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
@@ -746,29 +746,23 @@
746 **
747 ** Show the complete change history for a single wiki page.
748 */
749 void whistory_page(void){
750 Stmt q;
751 char *zTitle;
752 char *zSQL;
753 const char *zPageName;
754 login_check_credentials();
755 if( !g.perm.Hyperlink ){ login_needed(); return; }
756 zPageName = PD("name","");
757 zTitle = mprintf("History Of %s", zPageName);
758 style_header(zTitle);
759 free(zTitle);
760
761 zSQL = mprintf("%s AND event.objid IN "
762 " (SELECT rid FROM tagxref WHERE tagid="
763 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
764 " UNION SELECT attachid FROM attachment"
765 " WHERE target=%Q)"
766 "ORDER BY mtime DESC",
767 timeline_query_for_www(), zPageName, zPageName);
768 db_prepare(&q, zSQL);
769 free(zSQL);
770 zWikiPageName = zPageName;
771 www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
772 db_finalize(&q);
773 style_footer();
774 }
@@ -778,11 +772,10 @@
778 ** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
779 **
780 ** Show the difference between two wiki pages.
781 */
782 void wdiff_page(void){
783 char *zTitle;
784 int rid1, rid2;
785 const char *zPageName;
786 Manifest *pW1, *pW2 = 0;
787 Blob w1, w2, d;
788 u64 diffFlags;
@@ -791,13 +784,11 @@
791 rid1 = atoi(PD("a","0"));
792 if( !g.perm.Hyperlink ){ login_needed(); return; }
793 if( rid1==0 ) fossil_redirect_home();
794 rid2 = atoi(PD("b","0"));
795 zPageName = PD("name","");
796 zTitle = mprintf("Changes To %s", zPageName);
797 style_header(zTitle);
798 free(zTitle);
799
800 if( rid2==0 ){
801 rid2 = db_int(0,
802 "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
803 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
804
--- src/wiki.c
+++ src/wiki.c
@@ -292,11 +292,11 @@
292 style_submenu_element("History", "History", "%s/whistory?name=%T",
293 g.zTop, zPageName);
294 }
295 }
296 style_set_current_page("%T?name=%T", g.zPath, zPageName);
297 style_header("%s", zPageName);
298 blob_init(&wiki, zBody, -1);
299 wiki_render_by_mimetype(&wiki, zMimetype);
300 blob_reset(&wiki);
301 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
302 manifest_destroy(pWiki);
@@ -649,11 +649,11 @@
649 Blob wiki;
650 Manifest *pWiki = 0;
651
652 blob_zero(&body);
653 if( isSandbox ){
654 blob_append(&body, db_get("sandbox",""), -1);
655 appendRemark(&body, zMimetype);
656 db_set("sandbox", blob_str(&body), 0);
657 }else{
658 login_verify_csrf_secret();
659 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
@@ -746,29 +746,23 @@
746 **
747 ** Show the complete change history for a single wiki page.
748 */
749 void whistory_page(void){
750 Stmt q;
 
 
751 const char *zPageName;
752 login_check_credentials();
753 if( !g.perm.Hyperlink ){ login_needed(); return; }
754 zPageName = PD("name","");
755 style_header("History Of %s", zPageName);
 
 
756
757 db_prepare(&q, "%s AND event.objid IN "
758 " (SELECT rid FROM tagxref WHERE tagid="
759 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
760 " UNION SELECT attachid FROM attachment"
761 " WHERE target=%Q)"
762 "ORDER BY mtime DESC",
763 timeline_query_for_www(), zPageName, zPageName);
 
 
764 zWikiPageName = zPageName;
765 www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
766 db_finalize(&q);
767 style_footer();
768 }
@@ -778,11 +772,10 @@
772 ** URL: /whistory?name=PAGENAME&a=RID1&b=RID2
773 **
774 ** Show the difference between two wiki pages.
775 */
776 void wdiff_page(void){
 
777 int rid1, rid2;
778 const char *zPageName;
779 Manifest *pW1, *pW2 = 0;
780 Blob w1, w2, d;
781 u64 diffFlags;
@@ -791,13 +784,11 @@
784 rid1 = atoi(PD("a","0"));
785 if( !g.perm.Hyperlink ){ login_needed(); return; }
786 if( rid1==0 ) fossil_redirect_home();
787 rid2 = atoi(PD("b","0"));
788 zPageName = PD("name","");
789 style_header("Changes To %s", zPageName);
 
 
790
791 if( rid2==0 ){
792 rid2 = db_int(0,
793 "SELECT objid FROM event JOIN tagxref ON objid=rid AND tagxref.tagid="
794 "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
795
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1046,11 +1046,11 @@
10461046
*/
10471047
static void startAutoParagraph(Renderer *p){
10481048
if( p->wantAutoParagraph==0 ) return;
10491049
if( p->state & WIKI_LINKSONLY ) return;
10501050
if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
1051
- blob_appendf(p->pOut, "<p>", -1);
1051
+ blob_append(p->pOut, "<p>", -1);
10521052
p->wantAutoParagraph = 0;
10531053
p->inAutoParagraph = 1;
10541054
}
10551055
10561056
/*
@@ -1121,11 +1121,11 @@
11211121
if( once ){
11221122
const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
11231123
db_static_prepare(&q,
11241124
"SELECT %s FROM ticket "
11251125
" WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
1126
- zClosedExpr
1126
+ zClosedExpr /*safe-for-%s*/
11271127
);
11281128
once = 0;
11291129
}
11301130
db_bind_text(&q, ":lwr", zLower);
11311131
db_bind_text(&q, ":upr", zUpper);
@@ -1243,11 +1243,11 @@
12431243
}
12441244
}else if( !in_this_repo(zTarget) ){
12451245
if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
12461246
zTerm = "";
12471247
}else{
1248
- blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget);
1248
+ blob_appendf(p->pOut, "<span class=\"brokenlink\">[");
12491249
zTerm = "]</span>";
12501250
}
12511251
}else if( g.perm.Hyperlink ){
12521252
blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
12531253
zTerm = "]</a>";
@@ -1328,11 +1328,11 @@
13281328
if( p->wikiList ){
13291329
popStackToTag(p, p->wikiList);
13301330
p->wikiList = 0;
13311331
}
13321332
endAutoParagraph(p);
1333
- blob_appendf(p->pOut, "\n\n", 1);
1333
+ blob_append(p->pOut, "\n\n", 1);
13341334
p->wantAutoParagraph = 1;
13351335
}
13361336
p->state |= AT_PARAGRAPH|AT_NEWLINE;
13371337
break;
13381338
}
13391339
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1046,11 +1046,11 @@
1046 */
1047 static void startAutoParagraph(Renderer *p){
1048 if( p->wantAutoParagraph==0 ) return;
1049 if( p->state & WIKI_LINKSONLY ) return;
1050 if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
1051 blob_appendf(p->pOut, "<p>", -1);
1052 p->wantAutoParagraph = 0;
1053 p->inAutoParagraph = 1;
1054 }
1055
1056 /*
@@ -1121,11 +1121,11 @@
1121 if( once ){
1122 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
1123 db_static_prepare(&q,
1124 "SELECT %s FROM ticket "
1125 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
1126 zClosedExpr
1127 );
1128 once = 0;
1129 }
1130 db_bind_text(&q, ":lwr", zLower);
1131 db_bind_text(&q, ":upr", zUpper);
@@ -1243,11 +1243,11 @@
1243 }
1244 }else if( !in_this_repo(zTarget) ){
1245 if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
1246 zTerm = "";
1247 }else{
1248 blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget);
1249 zTerm = "]</span>";
1250 }
1251 }else if( g.perm.Hyperlink ){
1252 blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
1253 zTerm = "]</a>";
@@ -1328,11 +1328,11 @@
1328 if( p->wikiList ){
1329 popStackToTag(p, p->wikiList);
1330 p->wikiList = 0;
1331 }
1332 endAutoParagraph(p);
1333 blob_appendf(p->pOut, "\n\n", 1);
1334 p->wantAutoParagraph = 1;
1335 }
1336 p->state |= AT_PARAGRAPH|AT_NEWLINE;
1337 break;
1338 }
1339
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1046,11 +1046,11 @@
1046 */
1047 static void startAutoParagraph(Renderer *p){
1048 if( p->wantAutoParagraph==0 ) return;
1049 if( p->state & WIKI_LINKSONLY ) return;
1050 if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
1051 blob_append(p->pOut, "<p>", -1);
1052 p->wantAutoParagraph = 0;
1053 p->inAutoParagraph = 1;
1054 }
1055
1056 /*
@@ -1121,11 +1121,11 @@
1121 if( once ){
1122 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
1123 db_static_prepare(&q,
1124 "SELECT %s FROM ticket "
1125 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
1126 zClosedExpr /*safe-for-%s*/
1127 );
1128 once = 0;
1129 }
1130 db_bind_text(&q, ":lwr", zLower);
1131 db_bind_text(&q, ":upr", zUpper);
@@ -1243,11 +1243,11 @@
1243 }
1244 }else if( !in_this_repo(zTarget) ){
1245 if( (p->state & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){
1246 zTerm = "";
1247 }else{
1248 blob_appendf(p->pOut, "<span class=\"brokenlink\">[");
1249 zTerm = "]</span>";
1250 }
1251 }else if( g.perm.Hyperlink ){
1252 blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
1253 zTerm = "]</a>";
@@ -1328,11 +1328,11 @@
1328 if( p->wikiList ){
1329 popStackToTag(p, p->wikiList);
1330 p->wikiList = 0;
1331 }
1332 endAutoParagraph(p);
1333 blob_append(p->pOut, "\n\n", 1);
1334 p->wantAutoParagraph = 1;
1335 }
1336 p->state |= AT_PARAGRAPH|AT_NEWLINE;
1337 break;
1338 }
1339
+33 -27
--- src/winhttp.c
+++ src/winhttp.c
@@ -58,10 +58,21 @@
5858
}
5959
zHdr++;
6060
}
6161
return 0;
6262
}
63
+
64
+/*
65
+** Issue a fatal error.
66
+*/
67
+static NORETURN void winhttp_fatal(
68
+ const char *zOp,
69
+ const char *zService,
70
+ const char *zErr
71
+){
72
+ fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
73
+}
6374
6475
/*
6576
** Process a single incoming HTTP request.
6677
*/
6778
static void win32_http_request(void *pAppData){
@@ -297,11 +308,11 @@
297308
zTempPrefix = mprintf("%sfossil_server_P%d_",
298309
fossil_unicode_to_utf8(zTmpPath), iPort);
299310
fossil_print("Listening for %s requests on TCP port %d\n",
300311
(flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
301312
if( zBrowser ){
302
- zBrowser = mprintf(zBrowser, iPort);
313
+ zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
303314
fossil_print("Launch webbrowser: %s\n", zBrowser);
304315
fossil_system(zBrowser);
305316
}
306317
fossil_print("Type Ctrl-C to stop the HTTP server\n");
307318
/* Set the service status to running and pass the listener socket to the
@@ -679,11 +690,10 @@
679690
if( strncmp(zMethod, "create", n)==0 ){
680691
SC_HANDLE hScm;
681692
SC_HANDLE hSvc;
682693
SERVICE_DESCRIPTIONW
683694
svcDescr = {L"Fossil - Distributed Software Configuration Management"};
684
- char *zErrFmt = "unable to create service '%s': %s";
685695
DWORD dwStartType = SERVICE_DEMAND_START;
686696
const char *zDisplay = find_option("display", "D", 1);
687697
const char *zStart = find_option("start", "S", 1);
688698
const char *zUsername = find_option("username", "U", 1);
689699
const char *zPassword = find_option("password", "W", 1);
@@ -714,17 +724,17 @@
714724
if( strncmp(zStart, "auto", strlen(zStart))==0 ){
715725
dwStartType = SERVICE_AUTO_START;
716726
}else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
717727
dwStartType = SERVICE_DEMAND_START;
718728
}else{
719
- fossil_fatal(zErrFmt, zSvcName,
729
+ winhttp_fatal("create", zSvcName,
720730
"specify 'auto' or 'manual' for the '-S|--start' option");
721731
}
722732
}
723733
/* Process options for Fossil running as server. */
724734
if( zPort && (atoi(zPort)<=0) ){
725
- fossil_fatal(zErrFmt, zSvcName,
735
+ winhttp_fatal("create", zSvcName,
726736
"port number must be in the range 1 - 65535.");
727737
}
728738
if( !zRepository ){
729739
db_must_be_within_tree();
730740
}else if( file_isdir(zRepository)==1 ){
@@ -743,11 +753,11 @@
743753
if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
744754
if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
745755
blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
746756
/* Create the service. */
747757
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
748
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
758
+ if( !hScm ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
749759
hSvc = CreateServiceW(
750760
hScm, /* Handle to the SCM */
751761
fossil_utf8_to_unicode(zSvcName), /* Name of the service */
752762
fossil_utf8_to_unicode(zDisplay), /* Display name */
753763
SERVICE_ALL_ACCESS, /* Desired access */
@@ -759,11 +769,11 @@
759769
NULL, /* Tag value */
760770
NULL, /* Service dependencies */
761771
zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
762772
fossil_utf8_to_unicode(zPassword) /* Account password */
763773
);
764
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
774
+ if( !hSvc ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
765775
/* Set the service description. */
766776
ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
767777
fossil_print("Service '%s' successfully created.\n", zSvcName);
768778
CloseServiceHandle(hSvc);
769779
CloseServiceHandle(hScm);
@@ -770,29 +780,28 @@
770780
}else
771781
if( strncmp(zMethod, "delete", n)==0 ){
772782
SC_HANDLE hScm;
773783
SC_HANDLE hSvc;
774784
SERVICE_STATUS sstat;
775
- char *zErrFmt = "unable to delete service '%s': %s";
776785
777786
verify_all_options();
778787
if( g.argc==4 ){
779788
zSvcName = g.argv[3];
780789
}else if( g.argc>4 ){
781790
fossil_fatal("too many arguments for delete method.");
782791
}
783792
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
784
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
793
+ if( !hScm ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
785794
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
786795
SERVICE_ALL_ACCESS);
787
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
796
+ if( !hSvc ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
788797
QueryServiceStatus(hSvc, &sstat);
789798
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
790799
fossil_print("Stopping service '%s'", zSvcName);
791800
if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
792801
if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
793
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
802
+ winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
794803
}
795804
}
796805
while( sstat.dwCurrentState!=SERVICE_STOPPED ){
797806
Sleep(100);
798807
fossil_print(".");
@@ -802,11 +811,11 @@
802811
}
803812
if( !DeleteService(hSvc) ){
804813
if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
805814
fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
806815
}else{
807
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
816
+ winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
808817
}
809818
}else{
810819
fossil_print("Service '%s' successfully deleted.\n", zSvcName);
811820
}
812821
CloseServiceHandle(hSvc);
@@ -818,11 +827,10 @@
818827
SERVICE_STATUS sstat;
819828
LPQUERY_SERVICE_CONFIGW pSvcConfig;
820829
LPSERVICE_DESCRIPTIONW pSvcDescr;
821830
BOOL bStatus;
822831
DWORD nRequired;
823
- const char *zErrFmt = "unable to show service '%s': %s";
824832
static const char *const zSvcTypes[] = {
825833
"Driver service",
826834
"File system driver service",
827835
"Service runs in its own process",
828836
"Service shares a process with other services",
@@ -848,21 +856,21 @@
848856
zSvcName = g.argv[3];
849857
}else if( g.argc>4 ){
850858
fossil_fatal("too many arguments for show method.");
851859
}
852860
hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
853
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
861
+ if( !hScm ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
854862
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
855
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
863
+ if( !hSvc ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
856864
/* Get the service configuration */
857865
bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
858866
if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
859
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
867
+ winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
860868
}
861869
pSvcConfig = fossil_malloc(nRequired);
862870
bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
863
- if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
871
+ if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
864872
/* Translate the service type */
865873
switch( pSvcConfig->dwServiceType ){
866874
case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break;
867875
case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break;
868876
case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break;
@@ -879,19 +887,19 @@
879887
}
880888
/* Get the service description. */
881889
bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
882890
NULL, 0, &nRequired);
883891
if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
884
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
892
+ winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
885893
}
886894
pSvcDescr = fossil_malloc(nRequired);
887895
bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
888896
(LPBYTE)pSvcDescr, nRequired, &nRequired);
889
- if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
897
+ if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
890898
/* Retrieves the current status of the specified service. */
891899
bStatus = QueryServiceStatus(hSvc, &sstat);
892
- if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
900
+ if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
893901
/* Translate the current state. */
894902
switch( sstat.dwCurrentState ){
895903
case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break;
896904
case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break;
897905
case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break;
@@ -921,29 +929,28 @@
921929
}else
922930
if( strncmp(zMethod, "start", n)==0 ){
923931
SC_HANDLE hScm;
924932
SC_HANDLE hSvc;
925933
SERVICE_STATUS sstat;
926
- char *zErrFmt = "unable to start service '%s': %s";
927934
928935
verify_all_options();
929936
if( g.argc==4 ){
930937
zSvcName = g.argv[3];
931938
}else if( g.argc>4 ){
932939
fossil_fatal("too many arguments for start method.");
933940
}
934941
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
935
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
942
+ if( !hScm ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
936943
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
937944
SERVICE_ALL_ACCESS);
938
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
945
+ if( !hSvc ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
939946
QueryServiceStatus(hSvc, &sstat);
940947
if( sstat.dwCurrentState!=SERVICE_RUNNING ){
941948
fossil_print("Starting service '%s'", zSvcName);
942949
if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
943950
if( !StartServiceW(hSvc, 0, NULL) ){
944
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
951
+ winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
945952
}
946953
}
947954
while( sstat.dwCurrentState!=SERVICE_RUNNING ){
948955
Sleep(100);
949956
fossil_print(".");
@@ -958,29 +965,28 @@
958965
}else
959966
if( strncmp(zMethod, "stop", n)==0 ){
960967
SC_HANDLE hScm;
961968
SC_HANDLE hSvc;
962969
SERVICE_STATUS sstat;
963
- char *zErrFmt = "unable to stop service '%s': %s";
964970
965971
verify_all_options();
966972
if( g.argc==4 ){
967973
zSvcName = g.argv[3];
968974
}else if( g.argc>4 ){
969975
fossil_fatal("too many arguments for stop method.");
970976
}
971977
hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
972
- if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
978
+ if( !hScm ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
973979
hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
974980
SERVICE_ALL_ACCESS);
975
- if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
981
+ if( !hSvc ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
976982
QueryServiceStatus(hSvc, &sstat);
977983
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
978984
fossil_print("Stopping service '%s'", zSvcName);
979985
if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
980986
if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
981
- fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
987
+ winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
982988
}
983989
}
984990
while( sstat.dwCurrentState!=SERVICE_STOPPED ){
985991
Sleep(100);
986992
fossil_print(".");
987993
--- src/winhttp.c
+++ src/winhttp.c
@@ -58,10 +58,21 @@
58 }
59 zHdr++;
60 }
61 return 0;
62 }
 
 
 
 
 
 
 
 
 
 
 
63
64 /*
65 ** Process a single incoming HTTP request.
66 */
67 static void win32_http_request(void *pAppData){
@@ -297,11 +308,11 @@
297 zTempPrefix = mprintf("%sfossil_server_P%d_",
298 fossil_unicode_to_utf8(zTmpPath), iPort);
299 fossil_print("Listening for %s requests on TCP port %d\n",
300 (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
301 if( zBrowser ){
302 zBrowser = mprintf(zBrowser, iPort);
303 fossil_print("Launch webbrowser: %s\n", zBrowser);
304 fossil_system(zBrowser);
305 }
306 fossil_print("Type Ctrl-C to stop the HTTP server\n");
307 /* Set the service status to running and pass the listener socket to the
@@ -679,11 +690,10 @@
679 if( strncmp(zMethod, "create", n)==0 ){
680 SC_HANDLE hScm;
681 SC_HANDLE hSvc;
682 SERVICE_DESCRIPTIONW
683 svcDescr = {L"Fossil - Distributed Software Configuration Management"};
684 char *zErrFmt = "unable to create service '%s': %s";
685 DWORD dwStartType = SERVICE_DEMAND_START;
686 const char *zDisplay = find_option("display", "D", 1);
687 const char *zStart = find_option("start", "S", 1);
688 const char *zUsername = find_option("username", "U", 1);
689 const char *zPassword = find_option("password", "W", 1);
@@ -714,17 +724,17 @@
714 if( strncmp(zStart, "auto", strlen(zStart))==0 ){
715 dwStartType = SERVICE_AUTO_START;
716 }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
717 dwStartType = SERVICE_DEMAND_START;
718 }else{
719 fossil_fatal(zErrFmt, zSvcName,
720 "specify 'auto' or 'manual' for the '-S|--start' option");
721 }
722 }
723 /* Process options for Fossil running as server. */
724 if( zPort && (atoi(zPort)<=0) ){
725 fossil_fatal(zErrFmt, zSvcName,
726 "port number must be in the range 1 - 65535.");
727 }
728 if( !zRepository ){
729 db_must_be_within_tree();
730 }else if( file_isdir(zRepository)==1 ){
@@ -743,11 +753,11 @@
743 if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
744 if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
745 blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
746 /* Create the service. */
747 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
748 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
749 hSvc = CreateServiceW(
750 hScm, /* Handle to the SCM */
751 fossil_utf8_to_unicode(zSvcName), /* Name of the service */
752 fossil_utf8_to_unicode(zDisplay), /* Display name */
753 SERVICE_ALL_ACCESS, /* Desired access */
@@ -759,11 +769,11 @@
759 NULL, /* Tag value */
760 NULL, /* Service dependencies */
761 zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
762 fossil_utf8_to_unicode(zPassword) /* Account password */
763 );
764 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
765 /* Set the service description. */
766 ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
767 fossil_print("Service '%s' successfully created.\n", zSvcName);
768 CloseServiceHandle(hSvc);
769 CloseServiceHandle(hScm);
@@ -770,29 +780,28 @@
770 }else
771 if( strncmp(zMethod, "delete", n)==0 ){
772 SC_HANDLE hScm;
773 SC_HANDLE hSvc;
774 SERVICE_STATUS sstat;
775 char *zErrFmt = "unable to delete service '%s': %s";
776
777 verify_all_options();
778 if( g.argc==4 ){
779 zSvcName = g.argv[3];
780 }else if( g.argc>4 ){
781 fossil_fatal("too many arguments for delete method.");
782 }
783 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
784 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
785 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
786 SERVICE_ALL_ACCESS);
787 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
788 QueryServiceStatus(hSvc, &sstat);
789 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
790 fossil_print("Stopping service '%s'", zSvcName);
791 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
792 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
793 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
794 }
795 }
796 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
797 Sleep(100);
798 fossil_print(".");
@@ -802,11 +811,11 @@
802 }
803 if( !DeleteService(hSvc) ){
804 if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
805 fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
806 }else{
807 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
808 }
809 }else{
810 fossil_print("Service '%s' successfully deleted.\n", zSvcName);
811 }
812 CloseServiceHandle(hSvc);
@@ -818,11 +827,10 @@
818 SERVICE_STATUS sstat;
819 LPQUERY_SERVICE_CONFIGW pSvcConfig;
820 LPSERVICE_DESCRIPTIONW pSvcDescr;
821 BOOL bStatus;
822 DWORD nRequired;
823 const char *zErrFmt = "unable to show service '%s': %s";
824 static const char *const zSvcTypes[] = {
825 "Driver service",
826 "File system driver service",
827 "Service runs in its own process",
828 "Service shares a process with other services",
@@ -848,21 +856,21 @@
848 zSvcName = g.argv[3];
849 }else if( g.argc>4 ){
850 fossil_fatal("too many arguments for show method.");
851 }
852 hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
853 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
854 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
855 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
856 /* Get the service configuration */
857 bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
858 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
859 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
860 }
861 pSvcConfig = fossil_malloc(nRequired);
862 bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
863 if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
864 /* Translate the service type */
865 switch( pSvcConfig->dwServiceType ){
866 case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break;
867 case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break;
868 case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break;
@@ -879,19 +887,19 @@
879 }
880 /* Get the service description. */
881 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
882 NULL, 0, &nRequired);
883 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
884 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
885 }
886 pSvcDescr = fossil_malloc(nRequired);
887 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
888 (LPBYTE)pSvcDescr, nRequired, &nRequired);
889 if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
890 /* Retrieves the current status of the specified service. */
891 bStatus = QueryServiceStatus(hSvc, &sstat);
892 if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
893 /* Translate the current state. */
894 switch( sstat.dwCurrentState ){
895 case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break;
896 case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break;
897 case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break;
@@ -921,29 +929,28 @@
921 }else
922 if( strncmp(zMethod, "start", n)==0 ){
923 SC_HANDLE hScm;
924 SC_HANDLE hSvc;
925 SERVICE_STATUS sstat;
926 char *zErrFmt = "unable to start service '%s': %s";
927
928 verify_all_options();
929 if( g.argc==4 ){
930 zSvcName = g.argv[3];
931 }else if( g.argc>4 ){
932 fossil_fatal("too many arguments for start method.");
933 }
934 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
935 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
936 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
937 SERVICE_ALL_ACCESS);
938 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
939 QueryServiceStatus(hSvc, &sstat);
940 if( sstat.dwCurrentState!=SERVICE_RUNNING ){
941 fossil_print("Starting service '%s'", zSvcName);
942 if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
943 if( !StartServiceW(hSvc, 0, NULL) ){
944 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
945 }
946 }
947 while( sstat.dwCurrentState!=SERVICE_RUNNING ){
948 Sleep(100);
949 fossil_print(".");
@@ -958,29 +965,28 @@
958 }else
959 if( strncmp(zMethod, "stop", n)==0 ){
960 SC_HANDLE hScm;
961 SC_HANDLE hSvc;
962 SERVICE_STATUS sstat;
963 char *zErrFmt = "unable to stop service '%s': %s";
964
965 verify_all_options();
966 if( g.argc==4 ){
967 zSvcName = g.argv[3];
968 }else if( g.argc>4 ){
969 fossil_fatal("too many arguments for stop method.");
970 }
971 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
972 if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
973 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
974 SERVICE_ALL_ACCESS);
975 if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
976 QueryServiceStatus(hSvc, &sstat);
977 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
978 fossil_print("Stopping service '%s'", zSvcName);
979 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
980 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
981 fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
982 }
983 }
984 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
985 Sleep(100);
986 fossil_print(".");
987
--- src/winhttp.c
+++ src/winhttp.c
@@ -58,10 +58,21 @@
58 }
59 zHdr++;
60 }
61 return 0;
62 }
63
64 /*
65 ** Issue a fatal error.
66 */
67 static NORETURN void winhttp_fatal(
68 const char *zOp,
69 const char *zService,
70 const char *zErr
71 ){
72 fossil_fatal("unable to %s service '%s': %s", zOp, zService, zErr);
73 }
74
75 /*
76 ** Process a single incoming HTTP request.
77 */
78 static void win32_http_request(void *pAppData){
@@ -297,11 +308,11 @@
308 zTempPrefix = mprintf("%sfossil_server_P%d_",
309 fossil_unicode_to_utf8(zTmpPath), iPort);
310 fossil_print("Listening for %s requests on TCP port %d\n",
311 (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
312 if( zBrowser ){
313 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
314 fossil_print("Launch webbrowser: %s\n", zBrowser);
315 fossil_system(zBrowser);
316 }
317 fossil_print("Type Ctrl-C to stop the HTTP server\n");
318 /* Set the service status to running and pass the listener socket to the
@@ -679,11 +690,10 @@
690 if( strncmp(zMethod, "create", n)==0 ){
691 SC_HANDLE hScm;
692 SC_HANDLE hSvc;
693 SERVICE_DESCRIPTIONW
694 svcDescr = {L"Fossil - Distributed Software Configuration Management"};
 
695 DWORD dwStartType = SERVICE_DEMAND_START;
696 const char *zDisplay = find_option("display", "D", 1);
697 const char *zStart = find_option("start", "S", 1);
698 const char *zUsername = find_option("username", "U", 1);
699 const char *zPassword = find_option("password", "W", 1);
@@ -714,17 +724,17 @@
724 if( strncmp(zStart, "auto", strlen(zStart))==0 ){
725 dwStartType = SERVICE_AUTO_START;
726 }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
727 dwStartType = SERVICE_DEMAND_START;
728 }else{
729 winhttp_fatal("create", zSvcName,
730 "specify 'auto' or 'manual' for the '-S|--start' option");
731 }
732 }
733 /* Process options for Fossil running as server. */
734 if( zPort && (atoi(zPort)<=0) ){
735 winhttp_fatal("create", zSvcName,
736 "port number must be in the range 1 - 65535.");
737 }
738 if( !zRepository ){
739 db_must_be_within_tree();
740 }else if( file_isdir(zRepository)==1 ){
@@ -743,11 +753,11 @@
753 if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
754 if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
755 blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
756 /* Create the service. */
757 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
758 if( !hScm ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
759 hSvc = CreateServiceW(
760 hScm, /* Handle to the SCM */
761 fossil_utf8_to_unicode(zSvcName), /* Name of the service */
762 fossil_utf8_to_unicode(zDisplay), /* Display name */
763 SERVICE_ALL_ACCESS, /* Desired access */
@@ -759,11 +769,11 @@
769 NULL, /* Tag value */
770 NULL, /* Service dependencies */
771 zUsername ? fossil_utf8_to_unicode(zUsername) : 0, /* Account */
772 fossil_utf8_to_unicode(zPassword) /* Account password */
773 );
774 if( !hSvc ) winhttp_fatal("create", zSvcName, win32_get_last_errmsg());
775 /* Set the service description. */
776 ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
777 fossil_print("Service '%s' successfully created.\n", zSvcName);
778 CloseServiceHandle(hSvc);
779 CloseServiceHandle(hScm);
@@ -770,29 +780,28 @@
780 }else
781 if( strncmp(zMethod, "delete", n)==0 ){
782 SC_HANDLE hScm;
783 SC_HANDLE hSvc;
784 SERVICE_STATUS sstat;
 
785
786 verify_all_options();
787 if( g.argc==4 ){
788 zSvcName = g.argv[3];
789 }else if( g.argc>4 ){
790 fossil_fatal("too many arguments for delete method.");
791 }
792 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
793 if( !hScm ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
794 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
795 SERVICE_ALL_ACCESS);
796 if( !hSvc ) winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
797 QueryServiceStatus(hSvc, &sstat);
798 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
799 fossil_print("Stopping service '%s'", zSvcName);
800 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
801 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
802 winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
803 }
804 }
805 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
806 Sleep(100);
807 fossil_print(".");
@@ -802,11 +811,11 @@
811 }
812 if( !DeleteService(hSvc) ){
813 if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
814 fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
815 }else{
816 winhttp_fatal("delete", zSvcName, win32_get_last_errmsg());
817 }
818 }else{
819 fossil_print("Service '%s' successfully deleted.\n", zSvcName);
820 }
821 CloseServiceHandle(hSvc);
@@ -818,11 +827,10 @@
827 SERVICE_STATUS sstat;
828 LPQUERY_SERVICE_CONFIGW pSvcConfig;
829 LPSERVICE_DESCRIPTIONW pSvcDescr;
830 BOOL bStatus;
831 DWORD nRequired;
 
832 static const char *const zSvcTypes[] = {
833 "Driver service",
834 "File system driver service",
835 "Service runs in its own process",
836 "Service shares a process with other services",
@@ -848,21 +856,21 @@
856 zSvcName = g.argv[3];
857 }else if( g.argc>4 ){
858 fossil_fatal("too many arguments for show method.");
859 }
860 hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
861 if( !hScm ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
862 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
863 if( !hSvc ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
864 /* Get the service configuration */
865 bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
866 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
867 winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
868 }
869 pSvcConfig = fossil_malloc(nRequired);
870 bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
871 if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
872 /* Translate the service type */
873 switch( pSvcConfig->dwServiceType ){
874 case SERVICE_KERNEL_DRIVER: zSvcType = zSvcTypes[0]; break;
875 case SERVICE_FILE_SYSTEM_DRIVER: zSvcType = zSvcTypes[1]; break;
876 case SERVICE_WIN32_OWN_PROCESS: zSvcType = zSvcTypes[2]; break;
@@ -879,19 +887,19 @@
887 }
888 /* Get the service description. */
889 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
890 NULL, 0, &nRequired);
891 if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
892 winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
893 }
894 pSvcDescr = fossil_malloc(nRequired);
895 bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
896 (LPBYTE)pSvcDescr, nRequired, &nRequired);
897 if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
898 /* Retrieves the current status of the specified service. */
899 bStatus = QueryServiceStatus(hSvc, &sstat);
900 if( !bStatus ) winhttp_fatal("show", zSvcName, win32_get_last_errmsg());
901 /* Translate the current state. */
902 switch( sstat.dwCurrentState ){
903 case SERVICE_STOPPED: zSvcState = zSvcStates[0]; break;
904 case SERVICE_START_PENDING: zSvcState = zSvcStates[1]; break;
905 case SERVICE_STOP_PENDING: zSvcState = zSvcStates[2]; break;
@@ -921,29 +929,28 @@
929 }else
930 if( strncmp(zMethod, "start", n)==0 ){
931 SC_HANDLE hScm;
932 SC_HANDLE hSvc;
933 SERVICE_STATUS sstat;
 
934
935 verify_all_options();
936 if( g.argc==4 ){
937 zSvcName = g.argv[3];
938 }else if( g.argc>4 ){
939 fossil_fatal("too many arguments for start method.");
940 }
941 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
942 if( !hScm ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
943 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
944 SERVICE_ALL_ACCESS);
945 if( !hSvc ) winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
946 QueryServiceStatus(hSvc, &sstat);
947 if( sstat.dwCurrentState!=SERVICE_RUNNING ){
948 fossil_print("Starting service '%s'", zSvcName);
949 if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
950 if( !StartServiceW(hSvc, 0, NULL) ){
951 winhttp_fatal("start", zSvcName, win32_get_last_errmsg());
952 }
953 }
954 while( sstat.dwCurrentState!=SERVICE_RUNNING ){
955 Sleep(100);
956 fossil_print(".");
@@ -958,29 +965,28 @@
965 }else
966 if( strncmp(zMethod, "stop", n)==0 ){
967 SC_HANDLE hScm;
968 SC_HANDLE hSvc;
969 SERVICE_STATUS sstat;
 
970
971 verify_all_options();
972 if( g.argc==4 ){
973 zSvcName = g.argv[3];
974 }else if( g.argc>4 ){
975 fossil_fatal("too many arguments for stop method.");
976 }
977 hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
978 if( !hScm ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
979 hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName),
980 SERVICE_ALL_ACCESS);
981 if( !hSvc ) winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
982 QueryServiceStatus(hSvc, &sstat);
983 if( sstat.dwCurrentState!=SERVICE_STOPPED ){
984 fossil_print("Stopping service '%s'", zSvcName);
985 if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
986 if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
987 winhttp_fatal("stop", zSvcName, win32_get_last_errmsg());
988 }
989 }
990 while( sstat.dwCurrentState!=SERVICE_STOPPED ){
991 Sleep(100);
992 fossil_print(".");
993
+17 -12
--- src/xfer.c
+++ src/xfer.c
@@ -311,11 +311,11 @@
311311
Blob src, delta;
312312
int size = 0;
313313
int srcId = 0;
314314
315315
for(i=0; srcId==0 && i<count(azQuery); i++){
316
- srcId = db_int(0, azQuery[i], rid);
316
+ srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid);
317317
}
318318
if( srcId>0
319319
&& (pXfer->syncPrivate || !content_is_private(srcId))
320320
&& content_get(srcId, &src)
321321
){
@@ -422,11 +422,11 @@
422422
return;
423423
}
424424
if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425425
pXfer->mxSend<=blob_size(pXfer->pOut) ){
426426
const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427
- blob_appendf(pXfer->pOut, zFormat, pUuid);
427
+ blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid);
428428
pXfer->nIGotSent++;
429429
blob_reset(&uuid);
430430
return;
431431
}
432432
if( nativeDelta ){
@@ -454,11 +454,11 @@
454454
}
455455
remote_has(rid);
456456
blob_reset(&uuid);
457457
#if 0
458458
if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459
- blob_appendf(pXfer->pOut, "\n", 1);
459
+ blob_append(pXfer->pOut, "\n", 1);
460460
}
461461
#endif
462462
}
463463
464464
/*
@@ -514,11 +514,11 @@
514514
pXfer->nFileSent++;
515515
}
516516
blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517517
blob_append(pXfer->pOut, zContent, szC);
518518
if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519
- blob_appendf(pXfer->pOut, "\n", 1);
519
+ blob_append(pXfer->pOut, "\n", 1);
520520
}
521521
if( !isPrivate && srcIsPrivate ){
522522
blob_reset(&fullContent);
523523
}
524524
}
@@ -711,18 +711,18 @@
711711
blob_reset(&cksum);
712712
rid = content_put(&cluster);
713713
blob_reset(&cluster);
714714
nUncl -= nRow;
715715
nRow = 0;
716
- blob_appendf(&deleteWhere, ",%d", rid);
716
+ blob_append_sql(&deleteWhere, ",%d", rid);
717717
}
718718
}
719719
db_finalize(&q);
720720
db_multi_exec(
721721
"DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722722
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723
- blob_str(&deleteWhere)
723
+ blob_sql_text(&deleteWhere)
724724
);
725725
blob_reset(&deleteWhere);
726726
if( nRow>0 ){
727727
md5sum_blob(&cluster, &cksum);
728728
blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1496,11 +1496,12 @@
14961496
nCardSent++;
14971497
if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
14981498
if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
14991499
}
15001500
if( syncFlags & SYNC_VERBOSE ){
1501
- fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
1501
+ fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/,
1502
+ "", "Bytes", "Cards", "Artifacts", "Deltas");
15021503
}
15031504
15041505
while( go ){
15051506
int newPhantom = 0;
15061507
char *zRandomness;
@@ -1593,17 +1594,18 @@
15931594
break;
15941595
}
15951596
15961597
/* Output current stats */
15971598
if( syncFlags & SYNC_VERBOSE ){
1598
- fossil_print(zValueFormat, "Sent:",
1599
+ fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
15991600
blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
16001601
xfer.nFileSent, xfer.nDeltaSent);
16011602
}else{
16021603
nRoundtrip++;
16031604
nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1604
- fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
1605
+ fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1606
+ nRoundtrip, nArtifactSent, nArtifactRcvd);
16051607
}
16061608
nCardSent = 0;
16071609
nCardRcvd = 0;
16081610
xfer.nFileSent = 0;
16091611
xfer.nDeltaSent = 0;
@@ -1814,11 +1816,11 @@
18141816
** to the next cycle.
18151817
*/
18161818
if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
18171819
char *zMsg = blob_terminate(&xfer.aToken[1]);
18181820
defossilize(zMsg);
1819
- if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){
1821
+ if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){
18201822
syncFlags &= ~SYNC_PUSH;
18211823
zMsg = 0;
18221824
}
18231825
if( zMsg && zMsg[0] ){
18241826
fossil_force_newline();
@@ -1860,10 +1862,12 @@
18601862
g.url.flags |= URL_PROMPT_PW;
18611863
g.url.flags &= ~URL_PROMPTED;
18621864
url_prompt_for_password();
18631865
url_remember();
18641866
}
1867
+ }else{
1868
+ nErr++;
18651869
}
18661870
}else{
18671871
blob_appendf(&xfer.err, "server says: %s\n", zMsg);
18681872
nErr++;
18691873
}
@@ -1898,15 +1902,16 @@
18981902
){
18991903
configure_finalize_receive();
19001904
}
19011905
origConfigRcvMask = 0;
19021906
if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1903
- fossil_print(zValueFormat, "Received:",
1907
+ fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:",
19041908
blob_size(&recv), nCardRcvd,
19051909
xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
19061910
}else{
1907
- fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
1911
+ fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1912
+ nRoundtrip, nArtifactSent, nArtifactRcvd);
19081913
}
19091914
blob_reset(&recv);
19101915
nCycle++;
19111916
19121917
/* If we received one or more files on the previous exchange but
19131918
--- src/xfer.c
+++ src/xfer.c
@@ -311,11 +311,11 @@
311 Blob src, delta;
312 int size = 0;
313 int srcId = 0;
314
315 for(i=0; srcId==0 && i<count(azQuery); i++){
316 srcId = db_int(0, azQuery[i], rid);
317 }
318 if( srcId>0
319 && (pXfer->syncPrivate || !content_is_private(srcId))
320 && content_get(srcId, &src)
321 ){
@@ -422,11 +422,11 @@
422 return;
423 }
424 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425 pXfer->mxSend<=blob_size(pXfer->pOut) ){
426 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427 blob_appendf(pXfer->pOut, zFormat, pUuid);
428 pXfer->nIGotSent++;
429 blob_reset(&uuid);
430 return;
431 }
432 if( nativeDelta ){
@@ -454,11 +454,11 @@
454 }
455 remote_has(rid);
456 blob_reset(&uuid);
457 #if 0
458 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459 blob_appendf(pXfer->pOut, "\n", 1);
460 }
461 #endif
462 }
463
464 /*
@@ -514,11 +514,11 @@
514 pXfer->nFileSent++;
515 }
516 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517 blob_append(pXfer->pOut, zContent, szC);
518 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519 blob_appendf(pXfer->pOut, "\n", 1);
520 }
521 if( !isPrivate && srcIsPrivate ){
522 blob_reset(&fullContent);
523 }
524 }
@@ -711,18 +711,18 @@
711 blob_reset(&cksum);
712 rid = content_put(&cluster);
713 blob_reset(&cluster);
714 nUncl -= nRow;
715 nRow = 0;
716 blob_appendf(&deleteWhere, ",%d", rid);
717 }
718 }
719 db_finalize(&q);
720 db_multi_exec(
721 "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723 blob_str(&deleteWhere)
724 );
725 blob_reset(&deleteWhere);
726 if( nRow>0 ){
727 md5sum_blob(&cluster, &cksum);
728 blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1496,11 +1496,12 @@
1496 nCardSent++;
1497 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1498 if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
1499 }
1500 if( syncFlags & SYNC_VERBOSE ){
1501 fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
 
1502 }
1503
1504 while( go ){
1505 int newPhantom = 0;
1506 char *zRandomness;
@@ -1593,17 +1594,18 @@
1593 break;
1594 }
1595
1596 /* Output current stats */
1597 if( syncFlags & SYNC_VERBOSE ){
1598 fossil_print(zValueFormat, "Sent:",
1599 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1600 xfer.nFileSent, xfer.nDeltaSent);
1601 }else{
1602 nRoundtrip++;
1603 nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1604 fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
 
1605 }
1606 nCardSent = 0;
1607 nCardRcvd = 0;
1608 xfer.nFileSent = 0;
1609 xfer.nDeltaSent = 0;
@@ -1814,11 +1816,11 @@
1814 ** to the next cycle.
1815 */
1816 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
1817 char *zMsg = blob_terminate(&xfer.aToken[1]);
1818 defossilize(zMsg);
1819 if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){
1820 syncFlags &= ~SYNC_PUSH;
1821 zMsg = 0;
1822 }
1823 if( zMsg && zMsg[0] ){
1824 fossil_force_newline();
@@ -1860,10 +1862,12 @@
1860 g.url.flags |= URL_PROMPT_PW;
1861 g.url.flags &= ~URL_PROMPTED;
1862 url_prompt_for_password();
1863 url_remember();
1864 }
 
 
1865 }
1866 }else{
1867 blob_appendf(&xfer.err, "server says: %s\n", zMsg);
1868 nErr++;
1869 }
@@ -1898,15 +1902,16 @@
1898 ){
1899 configure_finalize_receive();
1900 }
1901 origConfigRcvMask = 0;
1902 if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1903 fossil_print(zValueFormat, "Received:",
1904 blob_size(&recv), nCardRcvd,
1905 xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1906 }else{
1907 fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
 
1908 }
1909 blob_reset(&recv);
1910 nCycle++;
1911
1912 /* If we received one or more files on the previous exchange but
1913
--- src/xfer.c
+++ src/xfer.c
@@ -311,11 +311,11 @@
311 Blob src, delta;
312 int size = 0;
313 int srcId = 0;
314
315 for(i=0; srcId==0 && i<count(azQuery); i++){
316 srcId = db_int(0, azQuery[i] /*works-like:"%d"*/, rid);
317 }
318 if( srcId>0
319 && (pXfer->syncPrivate || !content_is_private(srcId))
320 && content_get(srcId, &src)
321 ){
@@ -422,11 +422,11 @@
422 return;
423 }
424 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
425 pXfer->mxSend<=blob_size(pXfer->pOut) ){
426 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
427 blob_appendf(pXfer->pOut, zFormat /*works-like:"%b"*/, pUuid);
428 pXfer->nIGotSent++;
429 blob_reset(&uuid);
430 return;
431 }
432 if( nativeDelta ){
@@ -454,11 +454,11 @@
454 }
455 remote_has(rid);
456 blob_reset(&uuid);
457 #if 0
458 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
459 blob_append(pXfer->pOut, "\n", 1);
460 }
461 #endif
462 }
463
464 /*
@@ -514,11 +514,11 @@
514 pXfer->nFileSent++;
515 }
516 blob_appendf(pXfer->pOut, "%d %d\n", szU, szC);
517 blob_append(pXfer->pOut, zContent, szC);
518 if( blob_buffer(pXfer->pOut)[blob_size(pXfer->pOut)-1]!='\n' ){
519 blob_append(pXfer->pOut, "\n", 1);
520 }
521 if( !isPrivate && srcIsPrivate ){
522 blob_reset(&fullContent);
523 }
524 }
@@ -711,18 +711,18 @@
711 blob_reset(&cksum);
712 rid = content_put(&cluster);
713 blob_reset(&cluster);
714 nUncl -= nRow;
715 nRow = 0;
716 blob_append_sql(&deleteWhere, ",%d", rid);
717 }
718 }
719 db_finalize(&q);
720 db_multi_exec(
721 "DELETE FROM unclustered WHERE rid NOT IN (0 %s)"
722 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=unclustered.rid)",
723 blob_sql_text(&deleteWhere)
724 );
725 blob_reset(&deleteWhere);
726 if( nRow>0 ){
727 md5sum_blob(&cluster, &cksum);
728 blob_appendf(&cluster, "Z %b\n", &cksum);
@@ -1496,11 +1496,12 @@
1496 nCardSent++;
1497 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1498 if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
1499 }
1500 if( syncFlags & SYNC_VERBOSE ){
1501 fossil_print(zLabelFormat /*works-like:"%s%s%s%s%d"*/,
1502 "", "Bytes", "Cards", "Artifacts", "Deltas");
1503 }
1504
1505 while( go ){
1506 int newPhantom = 0;
1507 char *zRandomness;
@@ -1593,17 +1594,18 @@
1594 break;
1595 }
1596
1597 /* Output current stats */
1598 if( syncFlags & SYNC_VERBOSE ){
1599 fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Sent:",
1600 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1601 xfer.nFileSent, xfer.nDeltaSent);
1602 }else{
1603 nRoundtrip++;
1604 nArtifactSent += xfer.nFileSent + xfer.nDeltaSent;
1605 fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1606 nRoundtrip, nArtifactSent, nArtifactRcvd);
1607 }
1608 nCardSent = 0;
1609 nCardRcvd = 0;
1610 xfer.nFileSent = 0;
1611 xfer.nDeltaSent = 0;
@@ -1814,11 +1816,11 @@
1816 ** to the next cycle.
1817 */
1818 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
1819 char *zMsg = blob_terminate(&xfer.aToken[1]);
1820 defossilize(zMsg);
1821 if( (syncFlags & SYNC_PUSH) && zMsg && sqlite3_strglob("pull only *", zMsg)==0 ){
1822 syncFlags &= ~SYNC_PUSH;
1823 zMsg = 0;
1824 }
1825 if( zMsg && zMsg[0] ){
1826 fossil_force_newline();
@@ -1860,10 +1862,12 @@
1862 g.url.flags |= URL_PROMPT_PW;
1863 g.url.flags &= ~URL_PROMPTED;
1864 url_prompt_for_password();
1865 url_remember();
1866 }
1867 }else{
1868 nErr++;
1869 }
1870 }else{
1871 blob_appendf(&xfer.err, "server says: %s\n", zMsg);
1872 nErr++;
1873 }
@@ -1898,15 +1902,16 @@
1902 ){
1903 configure_finalize_receive();
1904 }
1905 origConfigRcvMask = 0;
1906 if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
1907 fossil_print(zValueFormat /*works-like:"%s%d%d%d%d"*/, "Received:",
1908 blob_size(&recv), nCardRcvd,
1909 xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1910 }else{
1911 fossil_print(zBriefFormat /*works-like:"%d%d%d"*/,
1912 nRoundtrip, nArtifactSent, nArtifactRcvd);
1913 }
1914 blob_reset(&recv);
1915 nCycle++;
1916
1917 /* If we received one or more files on the previous exchange but
1918
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -40,12 +40,13 @@
4040
4141
APPNAME = $(OBJDIR)\fossil$(E)
4242
4343
all: $(APPNAME)
4444
45
-$(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
45
+$(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
4646
cd $(OBJDIR)
47
+ codecheck1$E $(SRC)
4748
$(DMDIR)\bin\link @link
4849
4950
$(OBJDIR)\fossil.res: $B\win\fossil.rc
5051
$(RC) $(RCFLAGS) -o$@ $**
5152
@@ -64,11 +65,14 @@
6465
$(BCC) -o$@ $**
6566
6667
mkindex$E: $(SRCDIR)\mkindex.c
6768
$(BCC) -o$@ $**
6869
69
-version$E: $B\src\mkversion.c
70
+mkversion$E: $(SRCDIR)\mkversion.c
71
+ $(BCC) -o$@ $**
72
+
73
+codecheck1$E: $(SRCDIR)\codecheck1.c
7074
$(BCC) -o$@ $**
7175
7276
$(OBJDIR)\shell$O : $(SRCDIR)\shell.c
7377
$(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
7478
@@ -82,11 +86,11 @@
8286
$(TCC) -o$@ -c $**
8387
8488
$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
8589
cp $@ $@
8690
87
-VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
91
+VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
8892
+$** > $@
8993
9094
page_index.h: mkindex$E $(SRC)
9195
+$** > $@
9296
@@ -93,11 +97,11 @@
9397
clean:
9498
-del $(OBJDIR)\*.obj
9599
-del *.obj *_.c *.h *.map
96100
97101
realclean:
98
- -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
102
+ -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E
99103
100104
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
101105
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
102106
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
103107
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
104108
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -40,12 +40,13 @@
40
41 APPNAME = $(OBJDIR)\fossil$(E)
42
43 all: $(APPNAME)
44
45 $(APPNAME) : translate$E mkindex$E headers $(OBJ) $(OBJDIR)\link
46 cd $(OBJDIR)
 
47 $(DMDIR)\bin\link @link
48
49 $(OBJDIR)\fossil.res: $B\win\fossil.rc
50 $(RC) $(RCFLAGS) -o$@ $**
51
@@ -64,11 +65,14 @@
64 $(BCC) -o$@ $**
65
66 mkindex$E: $(SRCDIR)\mkindex.c
67 $(BCC) -o$@ $**
68
69 version$E: $B\src\mkversion.c
 
 
 
70 $(BCC) -o$@ $**
71
72 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
73 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
74
@@ -82,11 +86,11 @@
82 $(TCC) -o$@ -c $**
83
84 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
85 cp $@ $@
86
87 VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
88 +$** > $@
89
90 page_index.h: mkindex$E $(SRC)
91 +$** > $@
92
@@ -93,11 +97,11 @@
93 clean:
94 -del $(OBJDIR)\*.obj
95 -del *.obj *_.c *.h *.map
96
97 realclean:
98 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
99
100 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
101 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
102 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
103 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
104
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -40,12 +40,13 @@
40
41 APPNAME = $(OBJDIR)\fossil$(E)
42
43 all: $(APPNAME)
44
45 $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link
46 cd $(OBJDIR)
47 codecheck1$E $(SRC)
48 $(DMDIR)\bin\link @link
49
50 $(OBJDIR)\fossil.res: $B\win\fossil.rc
51 $(RC) $(RCFLAGS) -o$@ $**
52
@@ -64,11 +65,14 @@
65 $(BCC) -o$@ $**
66
67 mkindex$E: $(SRCDIR)\mkindex.c
68 $(BCC) -o$@ $**
69
70 mkversion$E: $(SRCDIR)\mkversion.c
71 $(BCC) -o$@ $**
72
73 codecheck1$E: $(SRCDIR)\codecheck1.c
74 $(BCC) -o$@ $**
75
76 $(OBJDIR)\shell$O : $(SRCDIR)\shell.c
77 $(TCC) -o$@ -c $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) $**
78
@@ -82,11 +86,11 @@
86 $(TCC) -o$@ -c $**
87
88 $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
89 cp $@ $@
90
91 VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
92 +$** > $@
93
94 page_index.h: mkindex$E $(SRC)
95 +$** > $@
96
@@ -93,11 +97,11 @@
97 clean:
98 -del $(OBJDIR)\*.obj
99 -del *.obj *_.c *.h *.map
100
101 realclean:
102 -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E codecheck1$E
103
104 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
105 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
106 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
107 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
108
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -113,12 +113,12 @@
113113
#### The directories where the OpenSSL include and library files are located.
114114
# The recommended usage here is to use the Sysinternals junction tool
115115
# to create a hard link between an "openssl-1.x" sub-directory of the
116116
# Fossil source code directory and the target OpenSSL source directory.
117117
#
118
-OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119
-OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
118
+OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119
+OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120120
121121
#### Either the directory where the Tcl library is installed or the Tcl
122122
# source code directory resides (depending on the value of the macro
123123
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124124
# this directory must have "include" and "lib" sub-directories. If
@@ -685,10 +685,11 @@
685685
ifdef USE_WINDOWS
686686
TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687687
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688688
MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689689
VERSION = $(subst /,\,$(OBJDIR)/version.exe)
690
+CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
690691
CAT = type
691692
CP = copy
692693
GREP = find
693694
MV = copy
694695
RM = del /Q
@@ -697,10 +698,11 @@
697698
else
698699
TRANSLATE = $(OBJDIR)/translate.exe
699700
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700701
MKINDEX = $(OBJDIR)/mkindex.exe
701702
VERSION = $(OBJDIR)/version.exe
703
+CODECHECK1 = $(OBJDIR)/codecheck1.exe
702704
CAT = cat
703705
CP = cp
704706
GREP = grep
705707
MV = mv
706708
RM = rm -f
@@ -750,10 +752,13 @@
750752
$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751753
752754
$(VERSION): $(SRCDIR)/mkversion.c
753755
$(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
754756
757
+$(CODECHECK1): $(SRCDIR)/codecheck1.c
758
+ $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
759
+
755760
# WARNING. DANGER. Running the test suite modifies the repository the
756761
# build is done from, i.e. the checkout belongs to. Do not sync/push
757762
# the repository after running the tests.
758763
test: $(OBJDIR) $(APPNAME)
759764
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -815,11 +820,12 @@
815820
816821
ifdef FOSSIL_BUILD_SSL
817822
APPTARGETS += openssl
818823
endif
819824
820
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
825
+$(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
826
+ $(CODECHECK1) $(TRANS_SRC)
821827
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822828
823829
# This rule prevents make from using its default rules to try build
824830
# an executable named "manifest" out of the file named "manifest.c"
825831
#
826832
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -685,10 +685,11 @@
685 ifdef USE_WINDOWS
686 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
 
690 CAT = type
691 CP = copy
692 GREP = find
693 MV = copy
694 RM = del /Q
@@ -697,10 +698,11 @@
697 else
698 TRANSLATE = $(OBJDIR)/translate.exe
699 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700 MKINDEX = $(OBJDIR)/mkindex.exe
701 VERSION = $(OBJDIR)/version.exe
 
702 CAT = cat
703 CP = cp
704 GREP = grep
705 MV = mv
706 RM = rm -f
@@ -750,10 +752,13 @@
750 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751
752 $(VERSION): $(SRCDIR)/mkversion.c
753 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
754
 
 
 
755 # WARNING. DANGER. Running the test suite modifies the repository the
756 # build is done from, i.e. the checkout belongs to. Do not sync/push
757 # the repository after running the tests.
758 test: $(OBJDIR) $(APPNAME)
759 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -815,11 +820,12 @@
815
816 ifdef FOSSIL_BUILD_SSL
817 APPTARGETS += openssl
818 endif
819
820 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
 
821 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822
823 # This rule prevents make from using its default rules to try build
824 # an executable named "manifest" out of the file named "manifest.c"
825 #
826
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -685,10 +685,11 @@
685 ifdef USE_WINDOWS
686 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
690 CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
691 CAT = type
692 CP = copy
693 GREP = find
694 MV = copy
695 RM = del /Q
@@ -697,10 +698,11 @@
698 else
699 TRANSLATE = $(OBJDIR)/translate.exe
700 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
701 MKINDEX = $(OBJDIR)/mkindex.exe
702 VERSION = $(OBJDIR)/version.exe
703 CODECHECK1 = $(OBJDIR)/codecheck1.exe
704 CAT = cat
705 CP = cp
706 GREP = grep
707 MV = mv
708 RM = rm -f
@@ -750,10 +752,13 @@
752 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
753
754 $(VERSION): $(SRCDIR)/mkversion.c
755 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
756
757 $(CODECHECK1): $(SRCDIR)/codecheck1.c
758 $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
759
760 # WARNING. DANGER. Running the test suite modifies the repository the
761 # build is done from, i.e. the checkout belongs to. Do not sync/push
762 # the repository after running the tests.
763 test: $(OBJDIR) $(APPNAME)
764 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -815,11 +820,12 @@
820
821 ifdef FOSSIL_BUILD_SSL
822 APPTARGETS += openssl
823 endif
824
825 $(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
826 $(CODECHECK1) $(TRANS_SRC)
827 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
828
829 # This rule prevents make from using its default rules to try build
830 # an executable named "manifest" out of the file named "manifest.c"
831 #
832
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -113,12 +113,12 @@
113113
#### The directories where the OpenSSL include and library files are located.
114114
# The recommended usage here is to use the Sysinternals junction tool
115115
# to create a hard link between an "openssl-1.x" sub-directory of the
116116
# Fossil source code directory and the target OpenSSL source directory.
117117
#
118
-OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119
-OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
118
+OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119
+OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120120
121121
#### Either the directory where the Tcl library is installed or the Tcl
122122
# source code directory resides (depending on the value of the macro
123123
# FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124124
# this directory must have "include" and "lib" sub-directories. If
@@ -685,10 +685,11 @@
685685
ifdef USE_WINDOWS
686686
TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687687
MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688688
MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689689
VERSION = $(subst /,\,$(OBJDIR)/version.exe)
690
+CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
690691
CAT = type
691692
CP = copy
692693
GREP = find
693694
MV = copy
694695
RM = del /Q
@@ -697,10 +698,11 @@
697698
else
698699
TRANSLATE = $(OBJDIR)/translate.exe
699700
MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700701
MKINDEX = $(OBJDIR)/mkindex.exe
701702
VERSION = $(OBJDIR)/version.exe
703
+CODECHECK1 = $(OBJDIR)/codecheck1.exe
702704
CAT = cat
703705
CP = cp
704706
GREP = grep
705707
MV = mv
706708
RM = rm -f
@@ -750,10 +752,13 @@
750752
$(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751753
752754
$(VERSION): $(SRCDIR)/mkversion.c
753755
$(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
754756
757
+$(CODECHECK1): $(SRCDIR)/codecheck1.c
758
+ $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
759
+
755760
# WARNING. DANGER. Running the test suite modifies the repository the
756761
# build is done from, i.e. the checkout belongs to. Do not sync/push
757762
# the repository after running the tests.
758763
test: $(OBJDIR) $(APPNAME)
759764
$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -815,11 +820,12 @@
815820
816821
ifdef FOSSIL_BUILD_SSL
817822
APPTARGETS += openssl
818823
endif
819824
820
-$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
825
+$(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
826
+ $(CODECHECK1) $(TRANS_SRC)
821827
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822828
823829
# This rule prevents make from using its default rules to try build
824830
# an executable named "manifest" out of the file named "manifest.c"
825831
#
826832
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1i/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1i
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -685,10 +685,11 @@
685 ifdef USE_WINDOWS
686 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
 
690 CAT = type
691 CP = copy
692 GREP = find
693 MV = copy
694 RM = del /Q
@@ -697,10 +698,11 @@
697 else
698 TRANSLATE = $(OBJDIR)/translate.exe
699 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
700 MKINDEX = $(OBJDIR)/mkindex.exe
701 VERSION = $(OBJDIR)/version.exe
 
702 CAT = cat
703 CP = cp
704 GREP = grep
705 MV = mv
706 RM = rm -f
@@ -750,10 +752,13 @@
750 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
751
752 $(VERSION): $(SRCDIR)/mkversion.c
753 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
754
 
 
 
755 # WARNING. DANGER. Running the test suite modifies the repository the
756 # build is done from, i.e. the checkout belongs to. Do not sync/push
757 # the repository after running the tests.
758 test: $(OBJDIR) $(APPNAME)
759 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -815,11 +820,12 @@
815
816 ifdef FOSSIL_BUILD_SSL
817 APPTARGETS += openssl
818 endif
819
820 $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
 
821 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
822
823 # This rule prevents make from using its default rules to try build
824 # an executable named "manifest" out of the file named "manifest.c"
825 #
826
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -113,12 +113,12 @@
113 #### The directories where the OpenSSL include and library files are located.
114 # The recommended usage here is to use the Sysinternals junction tool
115 # to create a hard link between an "openssl-1.x" sub-directory of the
116 # Fossil source code directory and the target OpenSSL source directory.
117 #
118 OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include
119 OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j
120
121 #### Either the directory where the Tcl library is installed or the Tcl
122 # source code directory resides (depending on the value of the macro
123 # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory,
124 # this directory must have "include" and "lib" sub-directories. If
@@ -685,10 +685,11 @@
685 ifdef USE_WINDOWS
686 TRANSLATE = $(subst /,\,$(OBJDIR)/translate.exe)
687 MAKEHEADERS = $(subst /,\,$(OBJDIR)/makeheaders.exe)
688 MKINDEX = $(subst /,\,$(OBJDIR)/mkindex.exe)
689 VERSION = $(subst /,\,$(OBJDIR)/version.exe)
690 CODECHECK1 = $(subst /,\,$(OBJDIR)/codecheck1.exe)
691 CAT = type
692 CP = copy
693 GREP = find
694 MV = copy
695 RM = del /Q
@@ -697,10 +698,11 @@
698 else
699 TRANSLATE = $(OBJDIR)/translate.exe
700 MAKEHEADERS = $(OBJDIR)/makeheaders.exe
701 MKINDEX = $(OBJDIR)/mkindex.exe
702 VERSION = $(OBJDIR)/version.exe
703 CODECHECK1 = $(OBJDIR)/codecheck1.exe
704 CAT = cat
705 CP = cp
706 GREP = grep
707 MV = mv
708 RM = rm -f
@@ -750,10 +752,13 @@
752 $(BCC) -o $(MKINDEX) $(SRCDIR)/mkindex.c
753
754 $(VERSION): $(SRCDIR)/mkversion.c
755 $(BCC) -o $(VERSION) $(SRCDIR)/mkversion.c
756
757 $(CODECHECK1): $(SRCDIR)/codecheck1.c
758 $(BCC) -o $(CODECHECK1) $(SRCDIR)/codecheck1.c
759
760 # WARNING. DANGER. Running the test suite modifies the repository the
761 # build is done from, i.e. the checkout belongs to. Do not sync/push
762 # the repository after running the tests.
763 test: $(OBJDIR) $(APPNAME)
764 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
@@ -815,11 +820,12 @@
820
821 ifdef FOSSIL_BUILD_SSL
822 APPTARGETS += openssl
823 endif
824
825 $(APPNAME): $(OBJDIR)/headers $(CODECHECK1) $(OBJ) $(EXTRAOBJ) $(OBJDIR)/fossil.o $(APPTARGETS)
826 $(CODECHECK1) $(TRANS_SRC)
827 $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/fossil.o
828
829 # This rule prevents make from using its default rules to try build
830 # an executable named "manifest" out of the file named "manifest.c"
831 #
832
+40 -3
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -1,9 +1,17 @@
11
#
22
##############################################################################
33
# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
44
##############################################################################
5
+#
6
+# This Makefile will only function correctly if used from a sub-directory
7
+# that is a direct child of the top-level directory for this project.
8
+#
9
+!if !exist("..\.fossil-settings")
10
+!error "Please change the current directory to the one containing this file."
11
+!endif
12
+
513
#
614
# This file is automatically generated. Instead of editing this
715
# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
816
# to regenerate this file.
917
#
@@ -21,10 +29,13 @@
2129
PERLDIR = C:\Perl\bin
2230
PERL = perl.exe
2331
2432
# Uncomment to enable debug symbols
2533
# DEBUG = 1
34
+
35
+# Uncomment to support Windows XP with Visual Studio 201x
36
+# FOSSIL_ENABLE_WINXP = 1
2637
2738
# Uncomment to enable JSON API
2839
# FOSSIL_ENABLE_JSON = 1
2940
3041
# Uncomment to enable miniz usage
@@ -44,13 +55,14 @@
4455
4556
# Uncomment to enable Tcl support
4657
# FOSSIL_ENABLE_TCL = 1
4758
4859
!ifdef FOSSIL_ENABLE_SSL
49
-SSLDIR = $(B)\compat\openssl-1.0.1i
60
+SSLDIR = $(B)\compat\openssl-1.0.1j
5061
SSLINCDIR = $(SSLDIR)\inc32
5162
SSLLIBDIR = $(SSLDIR)\out32
63
+SSLLFLAGS = /nologo /opt:ref /debug
5264
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
5365
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
5466
!message Using 'x64' platform for OpenSSL...
5567
SSLCONFIG = VC-WIN64A no-asm
5668
SSLSETUP = ms\do_win64a.bat
@@ -93,10 +105,21 @@
93105
INCL = $(INCL) /I$(TCLINCDIR)
94106
!endif
95107
96108
CFLAGS = /nologo
97109
LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
110
+
111
+!ifdef FOSSIL_ENABLE_WINXP
112
+XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
113
+CFLAGS = $(CFLAGS) $(XPCFLAGS)
114
+!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
115
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
116
+!else
117
+XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
118
+!endif
119
+LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
120
+!endif
98121
99122
!ifdef DEBUG
100123
CFLAGS = $(CFLAGS) /Zi /MTd /Od
101124
LDFLAGS = $(LDFLAGS) /DEBUG
102125
!else
@@ -415,21 +438,29 @@
415438
416439
all: $(OX) $(APPNAME)
417440
418441
zlib:
419442
@echo Building zlib from "$(ZLIBDIR)"...
443
+!ifdef FOSSIL_ENABLE_WINXP
444
+ @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
445
+!else
420446
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
447
+!endif
421448
422449
!ifdef FOSSIL_ENABLE_SSL
423450
openssl:
424451
@echo Building OpenSSL from "$(SSLDIR)"...
425452
!if "$(PERLDIR)" != ""
426453
@set PATH=$(PERLDIR);$(PATH)
427454
!endif
428455
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
429456
@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
457
+!ifdef FOSSIL_ENABLE_WINXP
458
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
459
+!else
430460
@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
461
+!endif
431462
!endif
432463
433464
!ifndef FOSSIL_ENABLE_MINIZ
434465
APPTARGETS = $(APPTARGETS) zlib
435466
!endif
@@ -438,12 +469,13 @@
438469
!ifdef FOSSIL_BUILD_SSL
439470
APPTARGETS = $(APPTARGETS) openssl
440471
!endif
441472
!endif
442473
443
-$(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
474
+$(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
444475
cd $(OX)
476
+ codecheck1$E $(SRC)
445477
link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
446478
447479
$(OX)\linkopts: $B\win\Makefile.msc
448480
echo $(OX)\add.obj > $@
449481
echo $(OX)\allrepo.obj >> $@
@@ -577,11 +609,14 @@
577609
$(BCC) $**
578610
579611
mkindex$E: $(SRCDIR)\mkindex.c
580612
$(BCC) $**
581613
582
-mkversion$E: $B\src\mkversion.c
614
+mkversion$E: $(SRCDIR)\mkversion.c
615
+ $(BCC) $**
616
+
617
+codecheck1$E: $(SRCDIR)\codecheck1.c
583618
$(BCC) $**
584619
585620
$(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
586621
$(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
587622
@@ -629,10 +664,12 @@
629664
-del mkindex$P
630665
-del makeheaders$E
631666
-del makeheaders$P
632667
-del mkversion$E
633668
-del mkversion$P
669
+ -del codecheck1$E
670
+ -del codecheck1$P
634671
635672
$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
636673
$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
637674
$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
638675
$(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
639676
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -1,9 +1,17 @@
1 #
2 ##############################################################################
3 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
4 ##############################################################################
 
 
 
 
 
 
 
 
5 #
6 # This file is automatically generated. Instead of editing this
7 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
8 # to regenerate this file.
9 #
@@ -21,10 +29,13 @@
21 PERLDIR = C:\Perl\bin
22 PERL = perl.exe
23
24 # Uncomment to enable debug symbols
25 # DEBUG = 1
 
 
 
26
27 # Uncomment to enable JSON API
28 # FOSSIL_ENABLE_JSON = 1
29
30 # Uncomment to enable miniz usage
@@ -44,13 +55,14 @@
44
45 # Uncomment to enable Tcl support
46 # FOSSIL_ENABLE_TCL = 1
47
48 !ifdef FOSSIL_ENABLE_SSL
49 SSLDIR = $(B)\compat\openssl-1.0.1i
50 SSLINCDIR = $(SSLDIR)\inc32
51 SSLLIBDIR = $(SSLDIR)\out32
 
52 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
53 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
54 !message Using 'x64' platform for OpenSSL...
55 SSLCONFIG = VC-WIN64A no-asm
56 SSLSETUP = ms\do_win64a.bat
@@ -93,10 +105,21 @@
93 INCL = $(INCL) /I$(TCLINCDIR)
94 !endif
95
96 CFLAGS = /nologo
97 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
 
 
 
 
 
 
 
 
 
 
 
98
99 !ifdef DEBUG
100 CFLAGS = $(CFLAGS) /Zi /MTd /Od
101 LDFLAGS = $(LDFLAGS) /DEBUG
102 !else
@@ -415,21 +438,29 @@
415
416 all: $(OX) $(APPNAME)
417
418 zlib:
419 @echo Building zlib from "$(ZLIBDIR)"...
 
 
 
420 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
 
421
422 !ifdef FOSSIL_ENABLE_SSL
423 openssl:
424 @echo Building OpenSSL from "$(SSLDIR)"...
425 !if "$(PERLDIR)" != ""
426 @set PATH=$(PERLDIR);$(PATH)
427 !endif
428 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
429 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
 
 
 
430 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
 
431 !endif
432
433 !ifndef FOSSIL_ENABLE_MINIZ
434 APPTARGETS = $(APPTARGETS) zlib
435 !endif
@@ -438,12 +469,13 @@
438 !ifdef FOSSIL_BUILD_SSL
439 APPTARGETS = $(APPTARGETS) openssl
440 !endif
441 !endif
442
443 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E headers $(OBJ) $(OX)\linkopts
444 cd $(OX)
 
445 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
446
447 $(OX)\linkopts: $B\win\Makefile.msc
448 echo $(OX)\add.obj > $@
449 echo $(OX)\allrepo.obj >> $@
@@ -577,11 +609,14 @@
577 $(BCC) $**
578
579 mkindex$E: $(SRCDIR)\mkindex.c
580 $(BCC) $**
581
582 mkversion$E: $B\src\mkversion.c
 
 
 
583 $(BCC) $**
584
585 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
586 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
587
@@ -629,10 +664,12 @@
629 -del mkindex$P
630 -del makeheaders$E
631 -del makeheaders$P
632 -del mkversion$E
633 -del mkversion$P
 
 
634
635 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
636 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
637 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
638 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
639
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -1,9 +1,17 @@
1 #
2 ##############################################################################
3 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "src/makemake.tcl")
4 ##############################################################################
5 #
6 # This Makefile will only function correctly if used from a sub-directory
7 # that is a direct child of the top-level directory for this project.
8 #
9 !if !exist("..\.fossil-settings")
10 !error "Please change the current directory to the one containing this file."
11 !endif
12
13 #
14 # This file is automatically generated. Instead of editing this
15 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
16 # to regenerate this file.
17 #
@@ -21,10 +29,13 @@
29 PERLDIR = C:\Perl\bin
30 PERL = perl.exe
31
32 # Uncomment to enable debug symbols
33 # DEBUG = 1
34
35 # Uncomment to support Windows XP with Visual Studio 201x
36 # FOSSIL_ENABLE_WINXP = 1
37
38 # Uncomment to enable JSON API
39 # FOSSIL_ENABLE_JSON = 1
40
41 # Uncomment to enable miniz usage
@@ -44,13 +55,14 @@
55
56 # Uncomment to enable Tcl support
57 # FOSSIL_ENABLE_TCL = 1
58
59 !ifdef FOSSIL_ENABLE_SSL
60 SSLDIR = $(B)\compat\openssl-1.0.1j
61 SSLINCDIR = $(SSLDIR)\inc32
62 SSLLIBDIR = $(SSLDIR)\out32
63 SSLLFLAGS = /nologo /opt:ref /debug
64 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
65 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
66 !message Using 'x64' platform for OpenSSL...
67 SSLCONFIG = VC-WIN64A no-asm
68 SSLSETUP = ms\do_win64a.bat
@@ -93,10 +105,21 @@
105 INCL = $(INCL) /I$(TCLINCDIR)
106 !endif
107
108 CFLAGS = /nologo
109 LDFLAGS = /NODEFAULTLIB:msvcrt /MANIFEST:NO
110
111 !ifdef FOSSIL_ENABLE_WINXP
112 XPCFLAGS = $(XPCFLAGS) /D_USING_V110_SDK71_=1
113 CFLAGS = $(CFLAGS) $(XPCFLAGS)
114 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
115 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
116 !else
117 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
118 !endif
119 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
120 !endif
121
122 !ifdef DEBUG
123 CFLAGS = $(CFLAGS) /Zi /MTd /Od
124 LDFLAGS = $(LDFLAGS) /DEBUG
125 !else
@@ -415,21 +438,29 @@
438
439 all: $(OX) $(APPNAME)
440
441 zlib:
442 @echo Building zlib from "$(ZLIBDIR)"...
443 !ifdef FOSSIL_ENABLE_WINXP
444 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) "CC=cl $(XPCFLAGS)" "LD=link $(XPLDFLAGS)" && popd
445 !else
446 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc $(ZLIB) && popd
447 !endif
448
449 !ifdef FOSSIL_ENABLE_SSL
450 openssl:
451 @echo Building OpenSSL from "$(SSLDIR)"...
452 !if "$(PERLDIR)" != ""
453 @set PATH=$(PERLDIR);$(PATH)
454 !endif
455 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
456 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
457 !ifdef FOSSIL_ENABLE_WINXP
458 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
459 !else
460 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
461 !endif
462 !endif
463
464 !ifndef FOSSIL_ENABLE_MINIZ
465 APPTARGETS = $(APPTARGETS) zlib
466 !endif
@@ -438,12 +469,13 @@
469 !ifdef FOSSIL_BUILD_SSL
470 APPTARGETS = $(APPTARGETS) openssl
471 !endif
472 !endif
473
474 $(APPNAME) : $(APPTARGETS) translate$E mkindex$E codecheck1$E headers $(OBJ) $(OX)\linkopts
475 cd $(OX)
476 codecheck1$E $(SRC)
477 link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts
478
479 $(OX)\linkopts: $B\win\Makefile.msc
480 echo $(OX)\add.obj > $@
481 echo $(OX)\allrepo.obj >> $@
@@ -577,11 +609,14 @@
609 $(BCC) $**
610
611 mkindex$E: $(SRCDIR)\mkindex.c
612 $(BCC) $**
613
614 mkversion$E: $(SRCDIR)\mkversion.c
615 $(BCC) $**
616
617 codecheck1$E: $(SRCDIR)\codecheck1.c
618 $(BCC) $**
619
620 $(OX)\shell$O : $(SRCDIR)\shell.c $B\win\Makefile.msc
621 $(TCC) /Fo$@ $(SHELL_OPTIONS) $(SQLITE_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)\shell.c
622
@@ -629,10 +664,12 @@
664 -del mkindex$P
665 -del makeheaders$E
666 -del makeheaders$P
667 -del mkversion$E
668 -del mkversion$P
669 -del codecheck1$E
670 -del codecheck1$P
671
672 $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h
673 $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h
674 $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h
675 $(OBJDIR)\json_config$O : $(SRCDIR)\json_detail.h
676
--- win/buildmsvc.bat
+++ win/buildmsvc.bat
@@ -192,15 +192,30 @@
192192
IF ERRORLEVEL 1 (
193193
ECHO Could not change to directory "%ROOT%\msvcbld".
194194
GOTO errors
195195
)
196196
197
+REM
198
+REM NOTE: If requested, setup the build environment to refer to the Windows
199
+REM SDK v7.1A, which is required if the binaries are being built with
200
+REM Visual Studio 201x and need to work on Windows XP.
201
+REM
202
+IF DEFINED USE_V110SDK71A (
203
+ %_AECHO% Forcing use of the Windows SDK v7.1A...
204
+ CALL :fn_UseV110Sdk71A
205
+)
206
+
207
+%_VECHO% Path = '%PATH%'
208
+%_VECHO% Include = '%INCLUDE%'
209
+%_VECHO% Lib = '%LIB%'
210
+%_VECHO% NmakeArgs = '%NMAKE_ARGS%'
211
+
197212
REM
198213
REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
199214
REM anything extra from our command line along (e.g. extra options).
200215
REM
201
-%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %*
216
+%__ECHO% nmake /f "%TOOLS%\Makefile.msc" %NMAKE_ARGS% %*
202217
203218
IF ERRORLEVEL 1 (
204219
GOTO errors
205220
)
206221
@@ -213,10 +228,35 @@
213228
ECHO Could not restore directory.
214229
GOTO errors
215230
)
216231
217232
GOTO no_errors
233
+
234
+:fn_UseV110Sdk71A
235
+ IF "%PROCESSOR_ARCHITECTURE%" == "x86" GOTO set_v110Sdk71A_x86
236
+ SET PFILES_SDK71A=%ProgramFiles(x86)%
237
+ GOTO set_v110Sdk71A_done
238
+ :set_v110Sdk71A_x86
239
+ SET PFILES_SDK71A=%ProgramFiles%
240
+ :set_v110Sdk71A_done
241
+ SET PATH=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Bin;%PATH%
242
+ SET INCLUDE=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE%
243
+ IF "%PLATFORM%" == "x64" (
244
+ SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib\x64;%LIB%
245
+ ) ELSE (
246
+ SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib;%LIB%
247
+ )
248
+ CALL :fn_UnsetVariable PFILES_SDK71A
249
+ SET NMAKE_ARGS=%NMAKE_ARGS% FOSSIL_ENABLE_WINXP=1
250
+ GOTO :EOF
251
+
252
+:fn_UnsetVariable
253
+ IF NOT "%1" == "" (
254
+ SET %1=
255
+ CALL :fn_ResetErrorLevel
256
+ )
257
+ GOTO :EOF
218258
219259
:fn_ResetErrorLevel
220260
VERIFY > NUL
221261
GOTO :EOF
222262
223263
--- win/buildmsvc.bat
+++ win/buildmsvc.bat
@@ -192,15 +192,30 @@
192 IF ERRORLEVEL 1 (
193 ECHO Could not change to directory "%ROOT%\msvcbld".
194 GOTO errors
195 )
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197 REM
198 REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
199 REM anything extra from our command line along (e.g. extra options).
200 REM
201 %__ECHO% nmake /f "%TOOLS%\Makefile.msc" %*
202
203 IF ERRORLEVEL 1 (
204 GOTO errors
205 )
206
@@ -213,10 +228,35 @@
213 ECHO Could not restore directory.
214 GOTO errors
215 )
216
217 GOTO no_errors
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
219 :fn_ResetErrorLevel
220 VERIFY > NUL
221 GOTO :EOF
222
223
--- win/buildmsvc.bat
+++ win/buildmsvc.bat
@@ -192,15 +192,30 @@
192 IF ERRORLEVEL 1 (
193 ECHO Could not change to directory "%ROOT%\msvcbld".
194 GOTO errors
195 )
196
197 REM
198 REM NOTE: If requested, setup the build environment to refer to the Windows
199 REM SDK v7.1A, which is required if the binaries are being built with
200 REM Visual Studio 201x and need to work on Windows XP.
201 REM
202 IF DEFINED USE_V110SDK71A (
203 %_AECHO% Forcing use of the Windows SDK v7.1A...
204 CALL :fn_UseV110Sdk71A
205 )
206
207 %_VECHO% Path = '%PATH%'
208 %_VECHO% Include = '%INCLUDE%'
209 %_VECHO% Lib = '%LIB%'
210 %_VECHO% NmakeArgs = '%NMAKE_ARGS%'
211
212 REM
213 REM NOTE: Attempt to execute NMAKE for the Fossil MSVC makefile, passing
214 REM anything extra from our command line along (e.g. extra options).
215 REM
216 %__ECHO% nmake /f "%TOOLS%\Makefile.msc" %NMAKE_ARGS% %*
217
218 IF ERRORLEVEL 1 (
219 GOTO errors
220 )
221
@@ -213,10 +228,35 @@
228 ECHO Could not restore directory.
229 GOTO errors
230 )
231
232 GOTO no_errors
233
234 :fn_UseV110Sdk71A
235 IF "%PROCESSOR_ARCHITECTURE%" == "x86" GOTO set_v110Sdk71A_x86
236 SET PFILES_SDK71A=%ProgramFiles(x86)%
237 GOTO set_v110Sdk71A_done
238 :set_v110Sdk71A_x86
239 SET PFILES_SDK71A=%ProgramFiles%
240 :set_v110Sdk71A_done
241 SET PATH=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Bin;%PATH%
242 SET INCLUDE=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Include;%INCLUDE%
243 IF "%PLATFORM%" == "x64" (
244 SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib\x64;%LIB%
245 ) ELSE (
246 SET LIB=%PFILES_SDK71A%\Microsoft SDKs\Windows\7.1A\Lib;%LIB%
247 )
248 CALL :fn_UnsetVariable PFILES_SDK71A
249 SET NMAKE_ARGS=%NMAKE_ARGS% FOSSIL_ENABLE_WINXP=1
250 GOTO :EOF
251
252 :fn_UnsetVariable
253 IF NOT "%1" == "" (
254 SET %1=
255 CALL :fn_ResetErrorLevel
256 )
257 GOTO :EOF
258
259 :fn_ResetErrorLevel
260 VERIFY > NUL
261 GOTO :EOF
262
263
+1 -1
--- www/build.wiki
+++ www/build.wiki
@@ -122,11 +122,11 @@
122122
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
123123
first <a href="https://www.openssl.org/source/">download the official
124124
source code for OpenSSL</a> and extract it to an appropriately named
125125
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
126126
[/tree?ci=trunk&name=compat | compat] directory (e.g.
127
-"<b>compat/openssl-1.0.1i</b>"), then make sure that some recent
127
+"<b>compat/openssl-1.0.1j</b>"), then make sure that some recent
128128
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
129129
and finally run one of the following commands:
130130
<blockquote><pre>
131131
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
132132
</pre></blockquote>
133133
--- www/build.wiki
+++ www/build.wiki
@@ -122,11 +122,11 @@
122 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
123 first <a href="https://www.openssl.org/source/">download the official
124 source code for OpenSSL</a> and extract it to an appropriately named
125 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
126 [/tree?ci=trunk&name=compat | compat] directory (e.g.
127 "<b>compat/openssl-1.0.1i</b>"), then make sure that some recent
128 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
129 and finally run one of the following commands:
130 <blockquote><pre>
131 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
132 </pre></blockquote>
133
--- www/build.wiki
+++ www/build.wiki
@@ -122,11 +122,11 @@
122 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
123 first <a href="https://www.openssl.org/source/">download the official
124 source code for OpenSSL</a> and extract it to an appropriately named
125 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
126 [/tree?ci=trunk&name=compat | compat] directory (e.g.
127 "<b>compat/openssl-1.0.1j</b>"), then make sure that some recent
128 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
129 and finally run one of the following commands:
130 <blockquote><pre>
131 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
132 </pre></blockquote>
133

Keyboard Shortcuts

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