Fossil SCM

Merge updates from trunk.

mistachkin 2019-05-17 18:54 offline-sync merge
Commit be8b227b24016129ecb72824e1a35142da5ee09ea2482e0411f706a481d96c89
+1 -1
--- Dockerfile
+++ Dockerfile
@@ -1,9 +1,9 @@
11
###
22
# Dockerfile for Fossil
33
###
4
-FROM fedora:28
4
+FROM fedora:29
55
66
### Now install some additional parts we will need for the build
77
RUN dnf update -y && dnf install -y gcc make tcl tcl-devel zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil
88
99
### If you want to build "trunk", change the next line accordingly.
1010
--- Dockerfile
+++ Dockerfile
@@ -1,9 +1,9 @@
1 ###
2 # Dockerfile for Fossil
3 ###
4 FROM fedora:28
5
6 ### Now install some additional parts we will need for the build
7 RUN dnf update -y && dnf install -y gcc make tcl tcl-devel zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil
8
9 ### If you want to build "trunk", change the next line accordingly.
10
--- Dockerfile
+++ Dockerfile
@@ -1,9 +1,9 @@
1 ###
2 # Dockerfile for Fossil
3 ###
4 FROM fedora:29
5
6 ### Now install some additional parts we will need for the build
7 RUN dnf update -y && dnf install -y gcc make tcl tcl-devel zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil
8
9 ### If you want to build "trunk", change the next line accordingly.
10

No diff available

--- autosetup/find-tclsh
+++ autosetup/find-tclsh
@@ -2,11 +2,11 @@
22
# Looks for a suitable tclsh or jimsh in the PATH
33
# If not found, builds a bootstrap jimsh from source
44
d=`dirname "$0"`
55
{ "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0
66
PATH="$PATH:$d"; export PATH
7
-for tclsh in jimsh tclsh tclsh8.5 tclsh8.6; do
7
+for tclsh in jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; do
88
{ $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0
99
done
1010
echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0"
1111
for cc in ${CC_FOR_BUILD:-cc} gcc; do
1212
{ $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue
1313
--- autosetup/find-tclsh
+++ autosetup/find-tclsh
@@ -2,11 +2,11 @@
2 # Looks for a suitable tclsh or jimsh in the PATH
3 # If not found, builds a bootstrap jimsh from source
4 d=`dirname "$0"`
5 { "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0
6 PATH="$PATH:$d"; export PATH
7 for tclsh in jimsh tclsh tclsh8.5 tclsh8.6; do
8 { $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0
9 done
10 echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0"
11 for cc in ${CC_FOR_BUILD:-cc} gcc; do
12 { $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue
13
--- autosetup/find-tclsh
+++ autosetup/find-tclsh
@@ -2,11 +2,11 @@
2 # Looks for a suitable tclsh or jimsh in the PATH
3 # If not found, builds a bootstrap jimsh from source
4 d=`dirname "$0"`
5 { "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0
6 PATH="$PATH:$d"; export PATH
7 for tclsh in jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; do
8 { $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0
9 done
10 echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0"
11 for cc in ${CC_FOR_BUILD:-cc} gcc; do
12 { $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue
13
--- skins/bootstrap/footer.txt
+++ skins/bootstrap/footer.txt
@@ -7,11 +7,11 @@
77
<div id="push"></div>
88
</div>
99
<footer id="footer">
1010
<p>&#169; Copyright $<project_name>. All right reserved. Fossil $release_version &#183; <a href="$home/timeline.rss">RSS</a></p>
1111
</footer>
12
-<script>
12
+<script nonce="$<nonce>">
1313
var tables = document.querySelectorAll('table');
1414
for (var i = 0; i < tables.length; i++) {
1515
if (tables[i].id !== "timelineTable")
1616
tables[i].classList.add('table');
1717
};
1818
--- skins/bootstrap/footer.txt
+++ skins/bootstrap/footer.txt
@@ -7,11 +7,11 @@
7 <div id="push"></div>
8 </div>
9 <footer id="footer">
10 <p>&#169; Copyright $<project_name>. All right reserved. Fossil $release_version &#183; <a href="$home/timeline.rss">RSS</a></p>
11 </footer>
12 <script>
13 var tables = document.querySelectorAll('table');
14 for (var i = 0; i < tables.length; i++) {
15 if (tables[i].id !== "timelineTable")
16 tables[i].classList.add('table');
17 };
18
--- skins/bootstrap/footer.txt
+++ skins/bootstrap/footer.txt
@@ -7,11 +7,11 @@
7 <div id="push"></div>
8 </div>
9 <footer id="footer">
10 <p>&#169; Copyright $<project_name>. All right reserved. Fossil $release_version &#183; <a href="$home/timeline.rss">RSS</a></p>
11 </footer>
12 <script nonce="$<nonce>">
13 var tables = document.querySelectorAll('table');
14 for (var i = 0; i < tables.length; i++) {
15 if (tables[i].id !== "timelineTable")
16 tables[i].classList.add('table');
17 };
18
--- skins/bootstrap/header.txt
+++ skins/bootstrap/header.txt
@@ -5,11 +5,11 @@
55
<title>$<project_name>: $<title></title>
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data:; script-src 'self' 'nonce-$<nonce>'; style-src 'self' 'unsafe-inline'"/>
88
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" />
99
<link rel="stylesheet" href="$home/style.css?default" type="text/css" media="screen" />
10
- <script>
10
+ <script nonce="$<nonce>">
1111
function gebi(x){
1212
if(/^#/.test(x)) x = x.substr(1);
1313
var e = document.getElementById(x);
1414
if(!e) throw new Error("Expecting element with ID "+x);
1515
else return e;
1616
--- skins/bootstrap/header.txt
+++ skins/bootstrap/header.txt
@@ -5,11 +5,11 @@
5 <title>$<project_name>: $<title></title>
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <meta http-equiv="Content-Security-Policy" content="default-src 'self' data:; script-src 'self' 'nonce-$<nonce>'; style-src 'self' 'unsafe-inline'"/>
8 <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" />
9 <link rel="stylesheet" href="$home/style.css?default" type="text/css" media="screen" />
10 <script>
11 function gebi(x){
12 if(/^#/.test(x)) x = x.substr(1);
13 var e = document.getElementById(x);
14 if(!e) throw new Error("Expecting element with ID "+x);
15 else return e;
16
--- skins/bootstrap/header.txt
+++ skins/bootstrap/header.txt
@@ -5,11 +5,11 @@
5 <title>$<project_name>: $<title></title>
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <meta http-equiv="Content-Security-Policy" content="default-src 'self' data:; script-src 'self' 'nonce-$<nonce>'; style-src 'self' 'unsafe-inline'"/>
8 <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" />
9 <link rel="stylesheet" href="$home/style.css?default" type="text/css" media="screen" />
10 <script nonce="$<nonce>">
11 function gebi(x){
12 if(/^#/.test(x)) x = x.substr(1);
13 var e = document.getElementById(x);
14 if(!e) throw new Error("Expecting element with ID "+x);
15 else return e;
16
--- src/capabilities.c
+++ src/capabilities.c
@@ -364,11 +364,11 @@
364364
" FROM t LEFT JOIN user ON t.id=user.login"
365365
" UNION ALL"
366366
" SELECT 'New User Default', fullcap(%Q), 10, 1"
367367
" UNION ALL"
368368
" SELECT 'Regular User', fullcap(capunion(cap)), 20, count(*) FROM user"
369
- " WHERE cap NOT GLOB '*[as]*'"
369
+ " WHERE cap NOT GLOB '*[as]*' AND login NOT IN (SELECT id FROM t)"
370370
" UNION ALL"
371371
" SELECT 'Adminstrator', fullcap(capunion(cap)), 30, count(*) FROM user"
372372
" WHERE cap GLOB '*[as]*'"
373373
" ORDER BY 3 ASC",
374374
db_get("default-perms","")
375375
--- src/capabilities.c
+++ src/capabilities.c
@@ -364,11 +364,11 @@
364 " FROM t LEFT JOIN user ON t.id=user.login"
365 " UNION ALL"
366 " SELECT 'New User Default', fullcap(%Q), 10, 1"
367 " UNION ALL"
368 " SELECT 'Regular User', fullcap(capunion(cap)), 20, count(*) FROM user"
369 " WHERE cap NOT GLOB '*[as]*'"
370 " UNION ALL"
371 " SELECT 'Adminstrator', fullcap(capunion(cap)), 30, count(*) FROM user"
372 " WHERE cap GLOB '*[as]*'"
373 " ORDER BY 3 ASC",
374 db_get("default-perms","")
375
--- src/capabilities.c
+++ src/capabilities.c
@@ -364,11 +364,11 @@
364 " FROM t LEFT JOIN user ON t.id=user.login"
365 " UNION ALL"
366 " SELECT 'New User Default', fullcap(%Q), 10, 1"
367 " UNION ALL"
368 " SELECT 'Regular User', fullcap(capunion(cap)), 20, count(*) FROM user"
369 " WHERE cap NOT GLOB '*[as]*' AND login NOT IN (SELECT id FROM t)"
370 " UNION ALL"
371 " SELECT 'Adminstrator', fullcap(capunion(cap)), 30, count(*) FROM user"
372 " WHERE cap GLOB '*[as]*'"
373 " ORDER BY 3 ASC",
374 db_get("default-perms","")
375
+1 -1
--- src/checkin.c
+++ src/checkin.c
@@ -1209,11 +1209,11 @@
12091209
if( g.zLocalRoot!=0 ){
12101210
file_relative_name(g.zLocalRoot, &fname, 1);
12111211
zFile = db_text(0, "SELECT '%qci-comment-'||hex(randomblob(6))||'.txt'",
12121212
blob_str(&fname));
12131213
}else{
1214
- file_tempname(&fname, "ci-comment");
1214
+ file_tempname(&fname, "ci-comment",0);
12151215
zFile = mprintf("%s", blob_str(&fname));
12161216
}
12171217
blob_reset(&fname);
12181218
}
12191219
#if defined(_WIN32)
12201220
--- src/checkin.c
+++ src/checkin.c
@@ -1209,11 +1209,11 @@
1209 if( g.zLocalRoot!=0 ){
1210 file_relative_name(g.zLocalRoot, &fname, 1);
1211 zFile = db_text(0, "SELECT '%qci-comment-'||hex(randomblob(6))||'.txt'",
1212 blob_str(&fname));
1213 }else{
1214 file_tempname(&fname, "ci-comment");
1215 zFile = mprintf("%s", blob_str(&fname));
1216 }
1217 blob_reset(&fname);
1218 }
1219 #if defined(_WIN32)
1220
--- src/checkin.c
+++ src/checkin.c
@@ -1209,11 +1209,11 @@
1209 if( g.zLocalRoot!=0 ){
1210 file_relative_name(g.zLocalRoot, &fname, 1);
1211 zFile = db_text(0, "SELECT '%qci-comment-'||hex(randomblob(6))||'.txt'",
1212 blob_str(&fname));
1213 }else{
1214 file_tempname(&fname, "ci-comment",0);
1215 zFile = mprintf("%s", blob_str(&fname));
1216 }
1217 blob_reset(&fname);
1218 }
1219 #if defined(_WIN32)
1220
--- src/default_css.txt
+++ src/default_css.txt
@@ -189,10 +189,16 @@
189189
border-left: 7px solid #600000;
190190
}
191191
.tl-line.warp {
192192
background: #600000;
193193
}
194
+.tl-line.dotted {
195
+ width: 0px;
196
+ border-top: 0px dotted #888;
197
+ border-left: 2px dotted #888;
198
+ background: rgba(255,255,255,0);
199
+}
194200
span.tagDsp {
195201
font-weight: bold;
196202
}
197203
span.wikiError {
198204
font-weight: bold;
199205
--- src/default_css.txt
+++ src/default_css.txt
@@ -189,10 +189,16 @@
189 border-left: 7px solid #600000;
190 }
191 .tl-line.warp {
192 background: #600000;
193 }
 
 
 
 
 
 
194 span.tagDsp {
195 font-weight: bold;
196 }
197 span.wikiError {
198 font-weight: bold;
199
--- src/default_css.txt
+++ src/default_css.txt
@@ -189,10 +189,16 @@
189 border-left: 7px solid #600000;
190 }
191 .tl-line.warp {
192 background: #600000;
193 }
194 .tl-line.dotted {
195 width: 0px;
196 border-top: 0px dotted #888;
197 border-left: 2px dotted #888;
198 background: rgba(255,255,255,0);
199 }
200 span.tagDsp {
201 font-weight: bold;
202 }
203 span.wikiError {
204 font-weight: bold;
205
+3 -18
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -213,11 +213,10 @@
213213
}
214214
215215
/* Release memory resources */
216216
blob_reset(&file2);
217217
}else{
218
- int cnt = 0;
219218
Blob nameFile1; /* Name of temporary file to old pFile1 content */
220219
Blob cmd; /* Text of command to run */
221220
222221
if( !fIncludeBinary ){
223222
Blob file2;
@@ -246,15 +245,11 @@
246245
blob_reset(&file2);
247246
}
248247
249248
/* Construct a temporary file to hold pFile1 based on the name of
250249
** zFile2 */
251
- blob_zero(&nameFile1);
252
- do{
253
- blob_reset(&nameFile1);
254
- blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++);
255
- }while( file_access(blob_str(&nameFile1),F_OK)==0 );
250
+ file_tempname(&nameFile1, zFile2, "orig");
256251
blob_write_to_file(pFile1, blob_str(&nameFile1));
257252
258253
/* Construct the external diff command */
259254
blob_zero(&cmd);
260255
blob_append(&cmd, zDiffCmd, -1);
@@ -317,12 +312,10 @@
317312
blob_reset(&out);
318313
}else{
319314
Blob cmd;
320315
Blob temp1;
321316
Blob temp2;
322
- Blob prefix1;
323
- Blob prefix2;
324317
325318
if( !fIncludeBinary ){
326319
if( isBin1 || isBin2 ){
327320
fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
328321
return;
@@ -336,19 +329,13 @@
336329
}
337330
glob_free(pBinary);
338331
}
339332
}
340333
341
- /* Construct a prefix for the temporary file names */
342
- blob_zero(&prefix1);
343
- blob_zero(&prefix2);
344
- blob_appendf(&prefix1, "%s-v1", zName);
345
- blob_appendf(&prefix2, "%s-v2", zName);
346
-
347334
/* Construct a temporary file names */
348
- file_tempname(&temp1, blob_str(&prefix1));
349
- file_tempname(&temp2, blob_str(&prefix2));
335
+ file_tempname(&temp1, zName, "before");
336
+ file_tempname(&temp2, zName, "after");
350337
blob_write_to_file(pFile1, blob_str(&temp1));
351338
blob_write_to_file(pFile2, blob_str(&temp2));
352339
353340
/* Construct the external diff command */
354341
blob_zero(&cmd);
@@ -361,12 +348,10 @@
361348
362349
/* Delete the temporary file and clean up memory used */
363350
file_delete(blob_str(&temp1));
364351
file_delete(blob_str(&temp2));
365352
366
- blob_reset(&prefix1);
367
- blob_reset(&prefix2);
368353
blob_reset(&temp1);
369354
blob_reset(&temp2);
370355
blob_reset(&cmd);
371356
}
372357
}
373358
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -213,11 +213,10 @@
213 }
214
215 /* Release memory resources */
216 blob_reset(&file2);
217 }else{
218 int cnt = 0;
219 Blob nameFile1; /* Name of temporary file to old pFile1 content */
220 Blob cmd; /* Text of command to run */
221
222 if( !fIncludeBinary ){
223 Blob file2;
@@ -246,15 +245,11 @@
246 blob_reset(&file2);
247 }
248
249 /* Construct a temporary file to hold pFile1 based on the name of
250 ** zFile2 */
251 blob_zero(&nameFile1);
252 do{
253 blob_reset(&nameFile1);
254 blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++);
255 }while( file_access(blob_str(&nameFile1),F_OK)==0 );
256 blob_write_to_file(pFile1, blob_str(&nameFile1));
257
258 /* Construct the external diff command */
259 blob_zero(&cmd);
260 blob_append(&cmd, zDiffCmd, -1);
@@ -317,12 +312,10 @@
317 blob_reset(&out);
318 }else{
319 Blob cmd;
320 Blob temp1;
321 Blob temp2;
322 Blob prefix1;
323 Blob prefix2;
324
325 if( !fIncludeBinary ){
326 if( isBin1 || isBin2 ){
327 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
328 return;
@@ -336,19 +329,13 @@
336 }
337 glob_free(pBinary);
338 }
339 }
340
341 /* Construct a prefix for the temporary file names */
342 blob_zero(&prefix1);
343 blob_zero(&prefix2);
344 blob_appendf(&prefix1, "%s-v1", zName);
345 blob_appendf(&prefix2, "%s-v2", zName);
346
347 /* Construct a temporary file names */
348 file_tempname(&temp1, blob_str(&prefix1));
349 file_tempname(&temp2, blob_str(&prefix2));
350 blob_write_to_file(pFile1, blob_str(&temp1));
351 blob_write_to_file(pFile2, blob_str(&temp2));
352
353 /* Construct the external diff command */
354 blob_zero(&cmd);
@@ -361,12 +348,10 @@
361
362 /* Delete the temporary file and clean up memory used */
363 file_delete(blob_str(&temp1));
364 file_delete(blob_str(&temp2));
365
366 blob_reset(&prefix1);
367 blob_reset(&prefix2);
368 blob_reset(&temp1);
369 blob_reset(&temp2);
370 blob_reset(&cmd);
371 }
372 }
373
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -213,11 +213,10 @@
213 }
214
215 /* Release memory resources */
216 blob_reset(&file2);
217 }else{
 
218 Blob nameFile1; /* Name of temporary file to old pFile1 content */
219 Blob cmd; /* Text of command to run */
220
221 if( !fIncludeBinary ){
222 Blob file2;
@@ -246,15 +245,11 @@
245 blob_reset(&file2);
246 }
247
248 /* Construct a temporary file to hold pFile1 based on the name of
249 ** zFile2 */
250 file_tempname(&nameFile1, zFile2, "orig");
 
 
 
 
251 blob_write_to_file(pFile1, blob_str(&nameFile1));
252
253 /* Construct the external diff command */
254 blob_zero(&cmd);
255 blob_append(&cmd, zDiffCmd, -1);
@@ -317,12 +312,10 @@
312 blob_reset(&out);
313 }else{
314 Blob cmd;
315 Blob temp1;
316 Blob temp2;
 
 
317
318 if( !fIncludeBinary ){
319 if( isBin1 || isBin2 ){
320 fossil_print("%s",DIFF_CANNOT_COMPUTE_BINARY);
321 return;
@@ -336,19 +329,13 @@
329 }
330 glob_free(pBinary);
331 }
332 }
333
 
 
 
 
 
 
334 /* Construct a temporary file names */
335 file_tempname(&temp1, zName, "before");
336 file_tempname(&temp2, zName, "after");
337 blob_write_to_file(pFile1, blob_str(&temp1));
338 blob_write_to_file(pFile2, blob_str(&temp2));
339
340 /* Construct the external diff command */
341 blob_zero(&cmd);
@@ -361,12 +348,10 @@
348
349 /* Delete the temporary file and clean up memory used */
350 file_delete(blob_str(&temp1));
351 file_delete(blob_str(&temp2));
352
 
 
353 blob_reset(&temp1);
354 blob_reset(&temp2);
355 blob_reset(&cmd);
356 }
357 }
358
+8 -5
--- src/encode.c
+++ src/encode.c
@@ -376,13 +376,15 @@
376376
}
377377
return c;
378378
}
379379
380380
/*
381
-** Encode a UTF8 string for JSON. All special characters are escaped.
381
+** Encode a UTF8 string as a JSON string literal (without the surrounding
382
+** "...") and return a pointer to the encoding. Space to hold the encoding
383
+** is obtained from fossil_malloc() and must be freed by the caller.
382384
*/
383
-void blob_append_json_string(Blob *pBlob, const char *zStr){
385
+char *encode_json_string_literal(const char *zStr){
384386
const unsigned char *z;
385387
char *zOut;
386388
u32 c;
387389
int n, i, j;
388390
z = (const unsigned char*)zStr;
@@ -398,14 +400,14 @@
398400
}
399401
}else{
400402
n++;
401403
}
402404
}
403
- i = blob_size(pBlob);
404
- blob_resize(pBlob, i+n);
405
- zOut = blob_buffer(pBlob);
405
+ zOut = fossil_malloc(n+1);
406
+ if( zOut==0 ) return 0;
406407
z = (const unsigned char*)zStr;
408
+ i = 0;
407409
while( (c = fossil_utf8_read(&z))!=0 ){
408410
if( c=='\\' ){
409411
zOut[i++] = '\\';
410412
zOut[i++] = c;
411413
}else if( c<' ' || c>=0x7f ){
@@ -425,10 +427,11 @@
425427
}else{
426428
zOut[i++] = c;
427429
}
428430
}
429431
zOut[i] = 0;
432
+ return zOut;
430433
}
431434
432435
/*
433436
** The characters used for HTTP base64 encoding.
434437
*/
435438
--- src/encode.c
+++ src/encode.c
@@ -376,13 +376,15 @@
376 }
377 return c;
378 }
379
380 /*
381 ** Encode a UTF8 string for JSON. All special characters are escaped.
 
 
382 */
383 void blob_append_json_string(Blob *pBlob, const char *zStr){
384 const unsigned char *z;
385 char *zOut;
386 u32 c;
387 int n, i, j;
388 z = (const unsigned char*)zStr;
@@ -398,14 +400,14 @@
398 }
399 }else{
400 n++;
401 }
402 }
403 i = blob_size(pBlob);
404 blob_resize(pBlob, i+n);
405 zOut = blob_buffer(pBlob);
406 z = (const unsigned char*)zStr;
 
407 while( (c = fossil_utf8_read(&z))!=0 ){
408 if( c=='\\' ){
409 zOut[i++] = '\\';
410 zOut[i++] = c;
411 }else if( c<' ' || c>=0x7f ){
@@ -425,10 +427,11 @@
425 }else{
426 zOut[i++] = c;
427 }
428 }
429 zOut[i] = 0;
 
430 }
431
432 /*
433 ** The characters used for HTTP base64 encoding.
434 */
435
--- src/encode.c
+++ src/encode.c
@@ -376,13 +376,15 @@
376 }
377 return c;
378 }
379
380 /*
381 ** Encode a UTF8 string as a JSON string literal (without the surrounding
382 ** "...") and return a pointer to the encoding. Space to hold the encoding
383 ** is obtained from fossil_malloc() and must be freed by the caller.
384 */
385 char *encode_json_string_literal(const char *zStr){
386 const unsigned char *z;
387 char *zOut;
388 u32 c;
389 int n, i, j;
390 z = (const unsigned char*)zStr;
@@ -398,14 +400,14 @@
400 }
401 }else{
402 n++;
403 }
404 }
405 zOut = fossil_malloc(n+1);
406 if( zOut==0 ) return 0;
 
407 z = (const unsigned char*)zStr;
408 i = 0;
409 while( (c = fossil_utf8_read(&z))!=0 ){
410 if( c=='\\' ){
411 zOut[i++] = '\\';
412 zOut[i++] = c;
413 }else if( c<' ' || c>=0x7f ){
@@ -425,10 +427,11 @@
427 }else{
428 zOut[i++] = c;
429 }
430 }
431 zOut[i] = 0;
432 return zOut;
433 }
434
435 /*
436 ** The characters used for HTTP base64 encoding.
437 */
438
+135 -14
--- src/export.c
+++ src/export.c
@@ -952,17 +952,18 @@
952952
** then create the mark.
953953
**
954954
** The string returned is obtained from fossil_malloc() and should
955955
** be freed by the caller.
956956
*/
957
-static char *gitmirror_find_mark(const char *zUuid, int bCreate){
957
+static char *gitmirror_find_mark(const char *zUuid, int isFile, int bCreate){
958958
static Stmt sFind, sIns;
959959
db_static_prepare(&sFind,
960960
"SELECT coalesce(githash,printf(':%%d',id))"
961
- " FROM mirror.mmark WHERE uuid=:uuid"
961
+ " FROM mirror.mmark WHERE uuid=:uuid AND isfile=:isfile"
962962
);
963963
db_bind_text(&sFind, ":uuid", zUuid);
964
+ db_bind_int(&sFind, ":isfile", isFile!=0);
964965
if( db_step(&sFind)==SQLITE_ROW ){
965966
char *zMark = fossil_strdup(db_column_text(&sFind, 0));
966967
db_reset(&sFind);
967968
return zMark;
968969
}
@@ -969,13 +970,14 @@
969970
db_reset(&sFind);
970971
if( !bCreate ){
971972
return 0;
972973
}
973974
db_static_prepare(&sIns,
974
- "INSERT INTO mirror.mmark(uuid) VALUES(:uuid)"
975
+ "INSERT INTO mirror.mmark(uuid,isfile) VALUES(:uuid,:isfile)"
975976
);
976977
db_bind_text(&sIns, ":uuid", zUuid);
978
+ db_bind_int(&sIns, ":isfile", isFile!=0);
977979
db_step(&sIns);
978980
db_reset(&sIns);
979981
return mprintf(":%d", db_last_insert_rowid());
980982
}
981983
@@ -1016,11 +1018,11 @@
10161018
}else{
10171019
return 1;
10181020
}
10191021
}
10201022
}
1021
- zMark = gitmirror_find_mark(zUuid, 1);
1023
+ zMark = gitmirror_find_mark(zUuid, 1, 1);
10221024
if( zMark[0]==':' ){
10231025
fprintf(xCmd, "blob\nmark %s\ndata %d\n", zMark, blob_size(&data));
10241026
fwrite(blob_buffer(&data), 1, blob_size(&data), xCmd);
10251027
fprintf(xCmd, "\n");
10261028
}
@@ -1059,10 +1061,11 @@
10591061
char *zMark; /* The Git-name of the check-in */
10601062
Blob sql; /* String of SQL for part of the query */
10611063
Blob comment; /* The comment text for the check-in */
10621064
int nErr = 0; /* Number of errors */
10631065
int bPhantomOk; /* True if phantom files should be ignored */
1066
+ char buf[24];
10641067
10651068
pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
10661069
if( pMan==0 ){
10671070
/* Must be a phantom. Return without doing anything, and in particular
10681071
** without creating a mark for this check-in. */
@@ -1071,11 +1074,11 @@
10711074
}
10721075
10731076
/* Check to see if any parent logins have not yet been processed, and
10741077
** if so, create them */
10751078
for(i=0; i<pMan->nParent; i++){
1076
- char *zPMark = gitmirror_find_mark(pMan->azParent[i], 0);
1079
+ char *zPMark = gitmirror_find_mark(pMan->azParent[i], 0, 0);
10771080
if( zPMark==0 ){
10781081
int prid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q",
10791082
pMan->azParent[i]);
10801083
int rc = gitmirror_send_checkin(xCmd, prid, pMan->azParent[i],
10811084
pnLimit, fManifest);
@@ -1129,16 +1132,18 @@
11291132
}
11301133
11311134
/* Export the check-in */
11321135
fprintf(xCmd, "commit refs/heads/%s\n", zBranch);
11331136
fossil_free(zBranch);
1134
- zMark = gitmirror_find_mark(zUuid,1);
1137
+ zMark = gitmirror_find_mark(zUuid,0,1);
11351138
fprintf(xCmd, "mark %s\n", zMark);
11361139
fossil_free(zMark);
1137
- fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n",
1138
- pMan->zUser, pMan->zUser,
1140
+ sqlite3_snprintf(sizeof(buf), buf, "%lld",
11391141
(sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
1142
+ );
1143
+ fprintf(xCmd, "committer %s <%[email protected]> %s +0000\n",
1144
+ pMan->zUser, pMan->zUser, buf
11401145
);
11411146
blob_init(&comment, pMan->zComment, -1);
11421147
if( blob_size(&comment)==0 ){
11431148
blob_append(&comment, "(no comment)", -1);
11441149
}
@@ -1145,11 +1150,11 @@
11451150
blob_appendf(&comment, "\n\nFossilOrigin-Name: %s", zUuid);
11461151
fprintf(xCmd, "data %d\n%s\n", blob_size(&comment), blob_str(&comment));
11471152
blob_reset(&comment);
11481153
iParent = -1; /* Which ancestor is the primary parent */
11491154
for(i=0; i<pMan->nParent; i++){
1150
- char *zOther = gitmirror_find_mark(pMan->azParent[i], 0);
1155
+ char *zOther = gitmirror_find_mark(pMan->azParent[i],0,0);
11511156
if( zOther==0 ) continue;
11521157
if( iParent<0 ){
11531158
iParent = i;
11541159
fprintf(xCmd, "from %s\n", zOther);
11551160
}else{
@@ -1180,11 +1185,11 @@
11801185
}
11811186
db_prepare(&q,
11821187
"SELECT x.filename, x.perm,"
11831188
" coalesce(mmark.githash,printf(':%%d',mmark.id))"
11841189
" FROM (%s) AS x, mirror.mmark"
1185
- " WHERE mmark.uuid=x.uuid",
1190
+ " WHERE mmark.uuid=x.uuid AND isfile",
11861191
blob_sql_text(&sql)
11871192
);
11881193
blob_reset(&sql);
11891194
while( db_step(&q)==SQLITE_ROW ){
11901195
const char *zFilename = db_column_text(&q,0);
@@ -1308,14 +1313,35 @@
13081313
" key TEXT PRIMARY KEY,\n"
13091314
" Value ANY\n"
13101315
") WITHOUT ROWID;\n"
13111316
"CREATE TABLE IF NOT EXISTS mirror.mmark(\n"
13121317
" id INTEGER PRIMARY KEY,\n"
1313
- " uuid TEXT UNIQUE,\n"
1314
- " githash TEXT\n"
1318
+ " uuid TEXT,\n"
1319
+ " isfile BOOLEAN,\n"
1320
+ " githash TEXT,\n"
1321
+ " UNIQUE(uuid,isfile)\n"
13151322
");"
13161323
);
1324
+ if( !db_table_has_column("mirror","mmark","isfile") ){
1325
+ db_multi_exec(
1326
+ "ALTER TABLE mirror.mmark RENAME TO mmark_old;"
1327
+ "CREATE TABLE IF NOT EXISTS mirror.mmark(\n"
1328
+ " id INTEGER PRIMARY KEY,\n"
1329
+ " uuid TEXT,\n"
1330
+ " isfile BOOLEAN,\n"
1331
+ " githash TEXT,\n"
1332
+ " UNIQUE(uuid,isfile)\n"
1333
+ ");"
1334
+ "INSERT OR IGNORE INTO mirror.mmark(id,uuid,githash,isfile)"
1335
+ " SELECT id,uuid,githash,"
1336
+ " NOT EXISTS(SELECT 1 FROM repository.event, repository.blob"
1337
+ " WHERE event.objid=blob.rid"
1338
+ " AND blob.uuid=mmark_old.uuid)"
1339
+ " FROM mirror.mmark_old;\n"
1340
+ "DROP TABLE mirror.mmark_old;\n"
1341
+ );
1342
+ }
13171343
13181344
/* Change the autopush setting if the --autopush flag is present */
13191345
if( zAutoPush ){
13201346
if( is_false(zAutoPush) ){
13211347
db_multi_exec("DELETE FROM mirror.mconfig WHERE key='autopush'");
@@ -1375,11 +1401,11 @@
13751401
"INSERT INTO tomirror "
13761402
"SELECT objid, mtime, blob.uuid FROM event, blob\n"
13771403
" WHERE type='ci'"
13781404
" AND mtime>coalesce((SELECT value FROM mconfig WHERE key='start'),0.0)"
13791405
" AND blob.rid=event.objid"
1380
- " AND blob.uuid NOT IN (SELECT uuid FROM mirror.mmark);"
1406
+ " AND blob.uuid NOT IN (SELECT uuid FROM mirror.mmark WHERE NOT isfile);"
13811407
);
13821408
nTotal = db_int(0, "SELECT count(*) FROM tomirror");
13831409
if( nLimit<nTotal ){
13841410
nTotal = nLimit;
13851411
}else if( nLimit>nTotal ){
@@ -1461,10 +1487,45 @@
14611487
gitmirror_message(VERB_NORMAL, "%s\n", zTagCmd);
14621488
fossil_system(zTagCmd);
14631489
fossil_free(zTagCmd);
14641490
}
14651491
db_finalize(&q);
1492
+
1493
+ /* Update all references that might have changed since the start time */
1494
+ db_prepare(&q,
1495
+ "SELECT"
1496
+ " tagxref.value AS name,"
1497
+ " max(event.mtime) AS mtime,"
1498
+ " mmark.githash AS gitckin"
1499
+ " FROM tagxref, tag, event, blob, mmark"
1500
+ " WHERE tagxref.tagid=tag.tagid"
1501
+ " AND tagxref.tagtype>0"
1502
+ " AND tag.tagname='branch'"
1503
+ " AND event.objid=tagxref.rid"
1504
+ " AND event.mtime > coalesce((SELECT value FROM mconfig"
1505
+ " WHERE key='start'),0.0)"
1506
+ " AND blob.rid=tagxref.rid"
1507
+ " AND mmark.uuid=blob.uuid"
1508
+ " GROUP BY 1"
1509
+ );
1510
+ while( db_step(&q)==SQLITE_ROW ){
1511
+ char *zBrname = fossil_strdup(db_column_text(&q,0));
1512
+ const char *zObj = db_column_text(&q,2);
1513
+ char *zRefCmd;
1514
+ if( fossil_strcmp(zBrname,"trunk")==0 ){
1515
+ fossil_free(zBrname);
1516
+ zBrname = fossil_strdup("master");
1517
+ }else{
1518
+ gitmirror_sanitize_name(zBrname);
1519
+ }
1520
+ zRefCmd = mprintf("git update-ref \"refs/heads/%s\" %s", zBrname, zObj);
1521
+ fossil_free(zBrname);
1522
+ gitmirror_message(VERB_NORMAL, "%s\n", zRefCmd);
1523
+ fossil_system(zRefCmd);
1524
+ fossil_free(zRefCmd);
1525
+ }
1526
+ db_finalize(&q);
14661527
14671528
/* Update the start time */
14681529
if( rEnd>0.0 ){
14691530
db_prepare(&q, "REPLACE INTO mirror.mconfig(key,value) VALUES('start',:x)");
14701531
db_bind_double(&q, ":x", rEnd);
@@ -1496,10 +1557,63 @@
14961557
zPushCmd = mprintf("git push --mirror %s", zPushUrl);
14971558
fossil_system(zPushCmd);
14981559
fossil_free(zPushCmd);
14991560
}
15001561
}
1562
+
1563
+/*
1564
+** Implementation of the "fossil git status" command.
1565
+**
1566
+** Show the status of a "git export".
1567
+*/
1568
+void gitmirror_status_command(void){
1569
+ char *zMirror;
1570
+ char *z;
1571
+ int n, k;
1572
+ db_find_and_open_repository(0, 0);
1573
+ verify_all_options();
1574
+ zMirror = db_get("last-git-export-repo", 0);
1575
+ if( zMirror==0 ){
1576
+ fossil_print("Git mirror: none\n");
1577
+ return;
1578
+ }
1579
+ fossil_print("Git mirror: %s\n", zMirror);
1580
+ db_multi_exec("ATTACH '%q/.mirror_state/db' AS mirror;", zMirror);
1581
+ z = db_text(0, "SELECT datetime(value) FROM mconfig WHERE key='start'");
1582
+ if( z ){
1583
+ double rAge = db_double(0.0, "SELECT julianday('now') - value"
1584
+ " FROM mconfig WHERE key='start'");
1585
+ if( rAge>1.0/86400.0 ){
1586
+ fossil_print("Last export: %s (%z ago)\n", z, human_readable_age(rAge));
1587
+ }else{
1588
+ fossil_print("Last export: %s (moments ago)\n", z);
1589
+ }
1590
+ }
1591
+ z = db_text(0, "SELECT value FROM mconfig WHERE key='autopush'");
1592
+ if( z==0 ){
1593
+ fossil_print("Autopush: off\n");
1594
+ }else{
1595
+ UrlData url;
1596
+ url_parse_local(z, 0, &url);
1597
+ fossil_print("Autopush: %s\n", url.canonical);
1598
+ }
1599
+ n = db_int(0,
1600
+ "SELECT count(*) FROM event"
1601
+ " WHERE type='ci'"
1602
+ " AND mtime>coalesce((SELECT value FROM mconfig"
1603
+ " WHERE key='start'),0.0)"
1604
+ );
1605
+ if( n==0 ){
1606
+ fossil_print("Status: up-to-date\n");
1607
+ }else{
1608
+ fossil_print("Status: %d check-in%s awaiting export\n",
1609
+ n, n==1 ? "" : "s");
1610
+ }
1611
+ n = db_int(0, "SELECT count(*) FROM mmark WHERE isfile");
1612
+ k = db_int(0, "SELECT count(*) FROm mmark WHERE NOT isfile");
1613
+ fossil_print("Exported: %d check-ins and %d file blobs\n", k, n);
1614
+}
15011615
15021616
/*
15031617
** COMMAND: git
15041618
**
15051619
** Usage: %fossil git SUBCOMMAND
@@ -1539,10 +1653,14 @@
15391653
** --verbose|-v More output.
15401654
**
15411655
** fossil git import MIRROR
15421656
**
15431657
** TBD...
1658
+**
1659
+** fossil git status
1660
+**
1661
+** Show the status of the current Git mirror, if there is one.
15441662
*/
15451663
void gitmirror_command(void){
15461664
char *zCmd;
15471665
int nCmd;
15481666
if( g.argc<3 ){
@@ -1554,11 +1672,14 @@
15541672
gitmirror_export_command();
15551673
}else
15561674
if( nCmd>2 && strncmp(zCmd,"import",nCmd)==0 ){
15571675
fossil_fatal("not yet implemented - check back later");
15581676
}else
1677
+ if( nCmd>2 && strncmp(zCmd,"status",nCmd)==0 ){
1678
+ gitmirror_status_command();
1679
+ }else
15591680
{
15601681
fossil_fatal("unknown subcommand \"%s\": should be one of "
1561
- "\"export\", \"import\"",
1682
+ "\"export\", \"import\", \"status\"",
15621683
zCmd);
15631684
}
15641685
}
15651686
--- src/export.c
+++ src/export.c
@@ -952,17 +952,18 @@
952 ** then create the mark.
953 **
954 ** The string returned is obtained from fossil_malloc() and should
955 ** be freed by the caller.
956 */
957 static char *gitmirror_find_mark(const char *zUuid, int bCreate){
958 static Stmt sFind, sIns;
959 db_static_prepare(&sFind,
960 "SELECT coalesce(githash,printf(':%%d',id))"
961 " FROM mirror.mmark WHERE uuid=:uuid"
962 );
963 db_bind_text(&sFind, ":uuid", zUuid);
 
964 if( db_step(&sFind)==SQLITE_ROW ){
965 char *zMark = fossil_strdup(db_column_text(&sFind, 0));
966 db_reset(&sFind);
967 return zMark;
968 }
@@ -969,13 +970,14 @@
969 db_reset(&sFind);
970 if( !bCreate ){
971 return 0;
972 }
973 db_static_prepare(&sIns,
974 "INSERT INTO mirror.mmark(uuid) VALUES(:uuid)"
975 );
976 db_bind_text(&sIns, ":uuid", zUuid);
 
977 db_step(&sIns);
978 db_reset(&sIns);
979 return mprintf(":%d", db_last_insert_rowid());
980 }
981
@@ -1016,11 +1018,11 @@
1016 }else{
1017 return 1;
1018 }
1019 }
1020 }
1021 zMark = gitmirror_find_mark(zUuid, 1);
1022 if( zMark[0]==':' ){
1023 fprintf(xCmd, "blob\nmark %s\ndata %d\n", zMark, blob_size(&data));
1024 fwrite(blob_buffer(&data), 1, blob_size(&data), xCmd);
1025 fprintf(xCmd, "\n");
1026 }
@@ -1059,10 +1061,11 @@
1059 char *zMark; /* The Git-name of the check-in */
1060 Blob sql; /* String of SQL for part of the query */
1061 Blob comment; /* The comment text for the check-in */
1062 int nErr = 0; /* Number of errors */
1063 int bPhantomOk; /* True if phantom files should be ignored */
 
1064
1065 pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
1066 if( pMan==0 ){
1067 /* Must be a phantom. Return without doing anything, and in particular
1068 ** without creating a mark for this check-in. */
@@ -1071,11 +1074,11 @@
1071 }
1072
1073 /* Check to see if any parent logins have not yet been processed, and
1074 ** if so, create them */
1075 for(i=0; i<pMan->nParent; i++){
1076 char *zPMark = gitmirror_find_mark(pMan->azParent[i], 0);
1077 if( zPMark==0 ){
1078 int prid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q",
1079 pMan->azParent[i]);
1080 int rc = gitmirror_send_checkin(xCmd, prid, pMan->azParent[i],
1081 pnLimit, fManifest);
@@ -1129,16 +1132,18 @@
1129 }
1130
1131 /* Export the check-in */
1132 fprintf(xCmd, "commit refs/heads/%s\n", zBranch);
1133 fossil_free(zBranch);
1134 zMark = gitmirror_find_mark(zUuid,1);
1135 fprintf(xCmd, "mark %s\n", zMark);
1136 fossil_free(zMark);
1137 fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n",
1138 pMan->zUser, pMan->zUser,
1139 (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
 
 
 
1140 );
1141 blob_init(&comment, pMan->zComment, -1);
1142 if( blob_size(&comment)==0 ){
1143 blob_append(&comment, "(no comment)", -1);
1144 }
@@ -1145,11 +1150,11 @@
1145 blob_appendf(&comment, "\n\nFossilOrigin-Name: %s", zUuid);
1146 fprintf(xCmd, "data %d\n%s\n", blob_size(&comment), blob_str(&comment));
1147 blob_reset(&comment);
1148 iParent = -1; /* Which ancestor is the primary parent */
1149 for(i=0; i<pMan->nParent; i++){
1150 char *zOther = gitmirror_find_mark(pMan->azParent[i], 0);
1151 if( zOther==0 ) continue;
1152 if( iParent<0 ){
1153 iParent = i;
1154 fprintf(xCmd, "from %s\n", zOther);
1155 }else{
@@ -1180,11 +1185,11 @@
1180 }
1181 db_prepare(&q,
1182 "SELECT x.filename, x.perm,"
1183 " coalesce(mmark.githash,printf(':%%d',mmark.id))"
1184 " FROM (%s) AS x, mirror.mmark"
1185 " WHERE mmark.uuid=x.uuid",
1186 blob_sql_text(&sql)
1187 );
1188 blob_reset(&sql);
1189 while( db_step(&q)==SQLITE_ROW ){
1190 const char *zFilename = db_column_text(&q,0);
@@ -1308,14 +1313,35 @@
1308 " key TEXT PRIMARY KEY,\n"
1309 " Value ANY\n"
1310 ") WITHOUT ROWID;\n"
1311 "CREATE TABLE IF NOT EXISTS mirror.mmark(\n"
1312 " id INTEGER PRIMARY KEY,\n"
1313 " uuid TEXT UNIQUE,\n"
1314 " githash TEXT\n"
 
 
1315 ");"
1316 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1317
1318 /* Change the autopush setting if the --autopush flag is present */
1319 if( zAutoPush ){
1320 if( is_false(zAutoPush) ){
1321 db_multi_exec("DELETE FROM mirror.mconfig WHERE key='autopush'");
@@ -1375,11 +1401,11 @@
1375 "INSERT INTO tomirror "
1376 "SELECT objid, mtime, blob.uuid FROM event, blob\n"
1377 " WHERE type='ci'"
1378 " AND mtime>coalesce((SELECT value FROM mconfig WHERE key='start'),0.0)"
1379 " AND blob.rid=event.objid"
1380 " AND blob.uuid NOT IN (SELECT uuid FROM mirror.mmark);"
1381 );
1382 nTotal = db_int(0, "SELECT count(*) FROM tomirror");
1383 if( nLimit<nTotal ){
1384 nTotal = nLimit;
1385 }else if( nLimit>nTotal ){
@@ -1461,10 +1487,45 @@
1461 gitmirror_message(VERB_NORMAL, "%s\n", zTagCmd);
1462 fossil_system(zTagCmd);
1463 fossil_free(zTagCmd);
1464 }
1465 db_finalize(&q);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1466
1467 /* Update the start time */
1468 if( rEnd>0.0 ){
1469 db_prepare(&q, "REPLACE INTO mirror.mconfig(key,value) VALUES('start',:x)");
1470 db_bind_double(&q, ":x", rEnd);
@@ -1496,10 +1557,63 @@
1496 zPushCmd = mprintf("git push --mirror %s", zPushUrl);
1497 fossil_system(zPushCmd);
1498 fossil_free(zPushCmd);
1499 }
1500 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1501
1502 /*
1503 ** COMMAND: git
1504 **
1505 ** Usage: %fossil git SUBCOMMAND
@@ -1539,10 +1653,14 @@
1539 ** --verbose|-v More output.
1540 **
1541 ** fossil git import MIRROR
1542 **
1543 ** TBD...
 
 
 
 
1544 */
1545 void gitmirror_command(void){
1546 char *zCmd;
1547 int nCmd;
1548 if( g.argc<3 ){
@@ -1554,11 +1672,14 @@
1554 gitmirror_export_command();
1555 }else
1556 if( nCmd>2 && strncmp(zCmd,"import",nCmd)==0 ){
1557 fossil_fatal("not yet implemented - check back later");
1558 }else
 
 
 
1559 {
1560 fossil_fatal("unknown subcommand \"%s\": should be one of "
1561 "\"export\", \"import\"",
1562 zCmd);
1563 }
1564 }
1565
--- src/export.c
+++ src/export.c
@@ -952,17 +952,18 @@
952 ** then create the mark.
953 **
954 ** The string returned is obtained from fossil_malloc() and should
955 ** be freed by the caller.
956 */
957 static char *gitmirror_find_mark(const char *zUuid, int isFile, int bCreate){
958 static Stmt sFind, sIns;
959 db_static_prepare(&sFind,
960 "SELECT coalesce(githash,printf(':%%d',id))"
961 " FROM mirror.mmark WHERE uuid=:uuid AND isfile=:isfile"
962 );
963 db_bind_text(&sFind, ":uuid", zUuid);
964 db_bind_int(&sFind, ":isfile", isFile!=0);
965 if( db_step(&sFind)==SQLITE_ROW ){
966 char *zMark = fossil_strdup(db_column_text(&sFind, 0));
967 db_reset(&sFind);
968 return zMark;
969 }
@@ -969,13 +970,14 @@
970 db_reset(&sFind);
971 if( !bCreate ){
972 return 0;
973 }
974 db_static_prepare(&sIns,
975 "INSERT INTO mirror.mmark(uuid,isfile) VALUES(:uuid,:isfile)"
976 );
977 db_bind_text(&sIns, ":uuid", zUuid);
978 db_bind_int(&sIns, ":isfile", isFile!=0);
979 db_step(&sIns);
980 db_reset(&sIns);
981 return mprintf(":%d", db_last_insert_rowid());
982 }
983
@@ -1016,11 +1018,11 @@
1018 }else{
1019 return 1;
1020 }
1021 }
1022 }
1023 zMark = gitmirror_find_mark(zUuid, 1, 1);
1024 if( zMark[0]==':' ){
1025 fprintf(xCmd, "blob\nmark %s\ndata %d\n", zMark, blob_size(&data));
1026 fwrite(blob_buffer(&data), 1, blob_size(&data), xCmd);
1027 fprintf(xCmd, "\n");
1028 }
@@ -1059,10 +1061,11 @@
1061 char *zMark; /* The Git-name of the check-in */
1062 Blob sql; /* String of SQL for part of the query */
1063 Blob comment; /* The comment text for the check-in */
1064 int nErr = 0; /* Number of errors */
1065 int bPhantomOk; /* True if phantom files should be ignored */
1066 char buf[24];
1067
1068 pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
1069 if( pMan==0 ){
1070 /* Must be a phantom. Return without doing anything, and in particular
1071 ** without creating a mark for this check-in. */
@@ -1071,11 +1074,11 @@
1074 }
1075
1076 /* Check to see if any parent logins have not yet been processed, and
1077 ** if so, create them */
1078 for(i=0; i<pMan->nParent; i++){
1079 char *zPMark = gitmirror_find_mark(pMan->azParent[i], 0, 0);
1080 if( zPMark==0 ){
1081 int prid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q",
1082 pMan->azParent[i]);
1083 int rc = gitmirror_send_checkin(xCmd, prid, pMan->azParent[i],
1084 pnLimit, fManifest);
@@ -1129,16 +1132,18 @@
1132 }
1133
1134 /* Export the check-in */
1135 fprintf(xCmd, "commit refs/heads/%s\n", zBranch);
1136 fossil_free(zBranch);
1137 zMark = gitmirror_find_mark(zUuid,0,1);
1138 fprintf(xCmd, "mark %s\n", zMark);
1139 fossil_free(zMark);
1140 sqlite3_snprintf(sizeof(buf), buf, "%lld",
 
1141 (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
1142 );
1143 fprintf(xCmd, "committer %s <%[email protected]> %s +0000\n",
1144 pMan->zUser, pMan->zUser, buf
1145 );
1146 blob_init(&comment, pMan->zComment, -1);
1147 if( blob_size(&comment)==0 ){
1148 blob_append(&comment, "(no comment)", -1);
1149 }
@@ -1145,11 +1150,11 @@
1150 blob_appendf(&comment, "\n\nFossilOrigin-Name: %s", zUuid);
1151 fprintf(xCmd, "data %d\n%s\n", blob_size(&comment), blob_str(&comment));
1152 blob_reset(&comment);
1153 iParent = -1; /* Which ancestor is the primary parent */
1154 for(i=0; i<pMan->nParent; i++){
1155 char *zOther = gitmirror_find_mark(pMan->azParent[i],0,0);
1156 if( zOther==0 ) continue;
1157 if( iParent<0 ){
1158 iParent = i;
1159 fprintf(xCmd, "from %s\n", zOther);
1160 }else{
@@ -1180,11 +1185,11 @@
1185 }
1186 db_prepare(&q,
1187 "SELECT x.filename, x.perm,"
1188 " coalesce(mmark.githash,printf(':%%d',mmark.id))"
1189 " FROM (%s) AS x, mirror.mmark"
1190 " WHERE mmark.uuid=x.uuid AND isfile",
1191 blob_sql_text(&sql)
1192 );
1193 blob_reset(&sql);
1194 while( db_step(&q)==SQLITE_ROW ){
1195 const char *zFilename = db_column_text(&q,0);
@@ -1308,14 +1313,35 @@
1313 " key TEXT PRIMARY KEY,\n"
1314 " Value ANY\n"
1315 ") WITHOUT ROWID;\n"
1316 "CREATE TABLE IF NOT EXISTS mirror.mmark(\n"
1317 " id INTEGER PRIMARY KEY,\n"
1318 " uuid TEXT,\n"
1319 " isfile BOOLEAN,\n"
1320 " githash TEXT,\n"
1321 " UNIQUE(uuid,isfile)\n"
1322 ");"
1323 );
1324 if( !db_table_has_column("mirror","mmark","isfile") ){
1325 db_multi_exec(
1326 "ALTER TABLE mirror.mmark RENAME TO mmark_old;"
1327 "CREATE TABLE IF NOT EXISTS mirror.mmark(\n"
1328 " id INTEGER PRIMARY KEY,\n"
1329 " uuid TEXT,\n"
1330 " isfile BOOLEAN,\n"
1331 " githash TEXT,\n"
1332 " UNIQUE(uuid,isfile)\n"
1333 ");"
1334 "INSERT OR IGNORE INTO mirror.mmark(id,uuid,githash,isfile)"
1335 " SELECT id,uuid,githash,"
1336 " NOT EXISTS(SELECT 1 FROM repository.event, repository.blob"
1337 " WHERE event.objid=blob.rid"
1338 " AND blob.uuid=mmark_old.uuid)"
1339 " FROM mirror.mmark_old;\n"
1340 "DROP TABLE mirror.mmark_old;\n"
1341 );
1342 }
1343
1344 /* Change the autopush setting if the --autopush flag is present */
1345 if( zAutoPush ){
1346 if( is_false(zAutoPush) ){
1347 db_multi_exec("DELETE FROM mirror.mconfig WHERE key='autopush'");
@@ -1375,11 +1401,11 @@
1401 "INSERT INTO tomirror "
1402 "SELECT objid, mtime, blob.uuid FROM event, blob\n"
1403 " WHERE type='ci'"
1404 " AND mtime>coalesce((SELECT value FROM mconfig WHERE key='start'),0.0)"
1405 " AND blob.rid=event.objid"
1406 " AND blob.uuid NOT IN (SELECT uuid FROM mirror.mmark WHERE NOT isfile);"
1407 );
1408 nTotal = db_int(0, "SELECT count(*) FROM tomirror");
1409 if( nLimit<nTotal ){
1410 nTotal = nLimit;
1411 }else if( nLimit>nTotal ){
@@ -1461,10 +1487,45 @@
1487 gitmirror_message(VERB_NORMAL, "%s\n", zTagCmd);
1488 fossil_system(zTagCmd);
1489 fossil_free(zTagCmd);
1490 }
1491 db_finalize(&q);
1492
1493 /* Update all references that might have changed since the start time */
1494 db_prepare(&q,
1495 "SELECT"
1496 " tagxref.value AS name,"
1497 " max(event.mtime) AS mtime,"
1498 " mmark.githash AS gitckin"
1499 " FROM tagxref, tag, event, blob, mmark"
1500 " WHERE tagxref.tagid=tag.tagid"
1501 " AND tagxref.tagtype>0"
1502 " AND tag.tagname='branch'"
1503 " AND event.objid=tagxref.rid"
1504 " AND event.mtime > coalesce((SELECT value FROM mconfig"
1505 " WHERE key='start'),0.0)"
1506 " AND blob.rid=tagxref.rid"
1507 " AND mmark.uuid=blob.uuid"
1508 " GROUP BY 1"
1509 );
1510 while( db_step(&q)==SQLITE_ROW ){
1511 char *zBrname = fossil_strdup(db_column_text(&q,0));
1512 const char *zObj = db_column_text(&q,2);
1513 char *zRefCmd;
1514 if( fossil_strcmp(zBrname,"trunk")==0 ){
1515 fossil_free(zBrname);
1516 zBrname = fossil_strdup("master");
1517 }else{
1518 gitmirror_sanitize_name(zBrname);
1519 }
1520 zRefCmd = mprintf("git update-ref \"refs/heads/%s\" %s", zBrname, zObj);
1521 fossil_free(zBrname);
1522 gitmirror_message(VERB_NORMAL, "%s\n", zRefCmd);
1523 fossil_system(zRefCmd);
1524 fossil_free(zRefCmd);
1525 }
1526 db_finalize(&q);
1527
1528 /* Update the start time */
1529 if( rEnd>0.0 ){
1530 db_prepare(&q, "REPLACE INTO mirror.mconfig(key,value) VALUES('start',:x)");
1531 db_bind_double(&q, ":x", rEnd);
@@ -1496,10 +1557,63 @@
1557 zPushCmd = mprintf("git push --mirror %s", zPushUrl);
1558 fossil_system(zPushCmd);
1559 fossil_free(zPushCmd);
1560 }
1561 }
1562
1563 /*
1564 ** Implementation of the "fossil git status" command.
1565 **
1566 ** Show the status of a "git export".
1567 */
1568 void gitmirror_status_command(void){
1569 char *zMirror;
1570 char *z;
1571 int n, k;
1572 db_find_and_open_repository(0, 0);
1573 verify_all_options();
1574 zMirror = db_get("last-git-export-repo", 0);
1575 if( zMirror==0 ){
1576 fossil_print("Git mirror: none\n");
1577 return;
1578 }
1579 fossil_print("Git mirror: %s\n", zMirror);
1580 db_multi_exec("ATTACH '%q/.mirror_state/db' AS mirror;", zMirror);
1581 z = db_text(0, "SELECT datetime(value) FROM mconfig WHERE key='start'");
1582 if( z ){
1583 double rAge = db_double(0.0, "SELECT julianday('now') - value"
1584 " FROM mconfig WHERE key='start'");
1585 if( rAge>1.0/86400.0 ){
1586 fossil_print("Last export: %s (%z ago)\n", z, human_readable_age(rAge));
1587 }else{
1588 fossil_print("Last export: %s (moments ago)\n", z);
1589 }
1590 }
1591 z = db_text(0, "SELECT value FROM mconfig WHERE key='autopush'");
1592 if( z==0 ){
1593 fossil_print("Autopush: off\n");
1594 }else{
1595 UrlData url;
1596 url_parse_local(z, 0, &url);
1597 fossil_print("Autopush: %s\n", url.canonical);
1598 }
1599 n = db_int(0,
1600 "SELECT count(*) FROM event"
1601 " WHERE type='ci'"
1602 " AND mtime>coalesce((SELECT value FROM mconfig"
1603 " WHERE key='start'),0.0)"
1604 );
1605 if( n==0 ){
1606 fossil_print("Status: up-to-date\n");
1607 }else{
1608 fossil_print("Status: %d check-in%s awaiting export\n",
1609 n, n==1 ? "" : "s");
1610 }
1611 n = db_int(0, "SELECT count(*) FROM mmark WHERE isfile");
1612 k = db_int(0, "SELECT count(*) FROm mmark WHERE NOT isfile");
1613 fossil_print("Exported: %d check-ins and %d file blobs\n", k, n);
1614 }
1615
1616 /*
1617 ** COMMAND: git
1618 **
1619 ** Usage: %fossil git SUBCOMMAND
@@ -1539,10 +1653,14 @@
1653 ** --verbose|-v More output.
1654 **
1655 ** fossil git import MIRROR
1656 **
1657 ** TBD...
1658 **
1659 ** fossil git status
1660 **
1661 ** Show the status of the current Git mirror, if there is one.
1662 */
1663 void gitmirror_command(void){
1664 char *zCmd;
1665 int nCmd;
1666 if( g.argc<3 ){
@@ -1554,11 +1672,14 @@
1672 gitmirror_export_command();
1673 }else
1674 if( nCmd>2 && strncmp(zCmd,"import",nCmd)==0 ){
1675 fossil_fatal("not yet implemented - check back later");
1676 }else
1677 if( nCmd>2 && strncmp(zCmd,"status",nCmd)==0 ){
1678 gitmirror_status_command();
1679 }else
1680 {
1681 fossil_fatal("unknown subcommand \"%s\": should be one of "
1682 "\"export\", \"import\", \"status\"",
1683 zCmd);
1684 }
1685 }
1686
+45 -10
--- src/file.c
+++ src/file.c
@@ -1459,13 +1459,20 @@
14591459
blob_set(pPath, "/");
14601460
}
14611461
}
14621462
14631463
/*
1464
-** Construct a random temporary filename into pBuf starting with zPrefix.
1464
+** Construct a random temporary filename into pBuf where the name of
1465
+** the temporary file is derived from zBasis. The suffix on the temp
1466
+** file is the same as the suffix on zBasis, and the temp file has
1467
+** the root of zBasis in its name.
1468
+**
1469
+** If zTag is not NULL, then try to create the temp-file using zTag
1470
+** as a differentiator. If that fails, or if zTag is NULL, then use
1471
+** a bunch of random characters as the tag.
14651472
*/
1466
-void file_tempname(Blob *pBuf, const char *zPrefix){
1473
+void file_tempname(Blob *pBuf, const char *zBasis, const char *zTag){
14671474
#if defined(_WIN32)
14681475
const char *azDirs[] = {
14691476
0, /* GetTempPath */
14701477
0, /* TEMP */
14711478
0, /* TMP */
@@ -1488,10 +1495,12 @@
14881495
"0123456789";
14891496
unsigned int i;
14901497
const char *zDir = ".";
14911498
int cnt = 0;
14921499
char zRand[16];
1500
+ int nBasis;
1501
+ const char *zSuffix;
14931502
14941503
#if defined(_WIN32)
14951504
wchar_t zTmpPath[MAX_PATH];
14961505
14971506
if( GetTempPathW(MAX_PATH, zTmpPath) ){
@@ -1513,19 +1522,43 @@
15131522
if( !file_isdir(azDirs[i], ExtFILE) ) continue;
15141523
zDir = azDirs[i];
15151524
break;
15161525
}
15171526
1527
+ assert( zBasis!=0 );
1528
+ zSuffix = 0;
1529
+ for(i=0; zBasis[i]; i++){
1530
+ if( zBasis[i]=='/' || zBasis[i]=='\\' ){
1531
+ zBasis += i+1;
1532
+ i = -1;
1533
+ }else if( zBasis[i]=='.' ){
1534
+ zSuffix = zBasis + i;
1535
+ }
1536
+ }
1537
+ if( zSuffix==0 || zSuffix<=zBasis ){
1538
+ zSuffix = "";
1539
+ nBasis = i;
1540
+ }else{
1541
+ nBasis = (int)(zSuffix - zBasis);
1542
+ }
1543
+ if( nBasis==0 ){
1544
+ nBasis = 6;
1545
+ zBasis = "fossil";
1546
+ }
15181547
do{
15191548
blob_zero(pBuf);
15201549
if( cnt++>20 ) fossil_panic("cannot generate a temporary filename");
1521
- sqlite3_randomness(15, zRand);
1522
- for(i=0; i<15; i++){
1523
- zRand[i] = (char)zChars[ ((unsigned char)zRand[i])%(sizeof(zChars)-1) ];
1550
+ if( zTag==0 ){
1551
+ sqlite3_randomness(15, zRand);
1552
+ for(i=0; i<15; i++){
1553
+ zRand[i] = (char)zChars[ ((unsigned char)zRand[i])%(sizeof(zChars)-1) ];
1554
+ }
1555
+ zRand[15] = 0;
1556
+ zTag = zRand;
15241557
}
1525
- zRand[15] = 0;
1526
- blob_appendf(pBuf, "%s/%s-%s.txt", zDir, zPrefix ? zPrefix : "", zRand);
1558
+ blob_appendf(pBuf, "%s/%.*s~%s%s", zDir, nBasis, zBasis, zTag, zSuffix);
1559
+ zTag = 0;
15271560
}while( file_size(blob_str(pBuf), ExtFILE)>=0 );
15281561
15291562
#if defined(_WIN32)
15301563
fossil_path_free((char *)azDirs[0]);
15311564
fossil_path_free((char *)azDirs[1]);
@@ -1557,28 +1590,30 @@
15571590
}
15581591
15591592
15601593
/*
15611594
** COMMAND: test-tempname
1562
-** Usage: fossil test-name [--time SUFFIX] BASENAME ...
1595
+** Usage: fossil test-name [--time SUFFIX] [--tag NAME] BASENAME ...
15631596
**
15641597
** Generate temporary filenames derived from BASENAME. Use the --time
1565
-** option to generate temp names based on the time of day.
1598
+** option to generate temp names based on the time of day. If --tag NAME
1599
+** is specified, try to use NAME as the differentiator in the temp file.
15661600
*/
15671601
void file_test_tempname(void){
15681602
int i;
15691603
const char *zSuffix = find_option("time",0,1);
15701604
Blob x = BLOB_INITIALIZER;
15711605
char *z;
1606
+ const char *zTag = find_option("tag",0,1);
15721607
verify_all_options();
15731608
for(i=2; i<g.argc; i++){
15741609
if( zSuffix ){
15751610
z = file_time_tempname(g.argv[i], zSuffix);
15761611
fossil_print("%s\n", z);
15771612
fossil_free(z);
15781613
}else{
1579
- file_tempname(&x, g.argv[i]);
1614
+ file_tempname(&x, g.argv[i], zTag);
15801615
fossil_print("%s\n", blob_str(&x));
15811616
blob_reset(&x);
15821617
}
15831618
}
15841619
}
15851620
--- src/file.c
+++ src/file.c
@@ -1459,13 +1459,20 @@
1459 blob_set(pPath, "/");
1460 }
1461 }
1462
1463 /*
1464 ** Construct a random temporary filename into pBuf starting with zPrefix.
 
 
 
 
 
 
 
1465 */
1466 void file_tempname(Blob *pBuf, const char *zPrefix){
1467 #if defined(_WIN32)
1468 const char *azDirs[] = {
1469 0, /* GetTempPath */
1470 0, /* TEMP */
1471 0, /* TMP */
@@ -1488,10 +1495,12 @@
1488 "0123456789";
1489 unsigned int i;
1490 const char *zDir = ".";
1491 int cnt = 0;
1492 char zRand[16];
 
 
1493
1494 #if defined(_WIN32)
1495 wchar_t zTmpPath[MAX_PATH];
1496
1497 if( GetTempPathW(MAX_PATH, zTmpPath) ){
@@ -1513,19 +1522,43 @@
1513 if( !file_isdir(azDirs[i], ExtFILE) ) continue;
1514 zDir = azDirs[i];
1515 break;
1516 }
1517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1518 do{
1519 blob_zero(pBuf);
1520 if( cnt++>20 ) fossil_panic("cannot generate a temporary filename");
1521 sqlite3_randomness(15, zRand);
1522 for(i=0; i<15; i++){
1523 zRand[i] = (char)zChars[ ((unsigned char)zRand[i])%(sizeof(zChars)-1) ];
 
 
 
 
1524 }
1525 zRand[15] = 0;
1526 blob_appendf(pBuf, "%s/%s-%s.txt", zDir, zPrefix ? zPrefix : "", zRand);
1527 }while( file_size(blob_str(pBuf), ExtFILE)>=0 );
1528
1529 #if defined(_WIN32)
1530 fossil_path_free((char *)azDirs[0]);
1531 fossil_path_free((char *)azDirs[1]);
@@ -1557,28 +1590,30 @@
1557 }
1558
1559
1560 /*
1561 ** COMMAND: test-tempname
1562 ** Usage: fossil test-name [--time SUFFIX] BASENAME ...
1563 **
1564 ** Generate temporary filenames derived from BASENAME. Use the --time
1565 ** option to generate temp names based on the time of day.
 
1566 */
1567 void file_test_tempname(void){
1568 int i;
1569 const char *zSuffix = find_option("time",0,1);
1570 Blob x = BLOB_INITIALIZER;
1571 char *z;
 
1572 verify_all_options();
1573 for(i=2; i<g.argc; i++){
1574 if( zSuffix ){
1575 z = file_time_tempname(g.argv[i], zSuffix);
1576 fossil_print("%s\n", z);
1577 fossil_free(z);
1578 }else{
1579 file_tempname(&x, g.argv[i]);
1580 fossil_print("%s\n", blob_str(&x));
1581 blob_reset(&x);
1582 }
1583 }
1584 }
1585
--- src/file.c
+++ src/file.c
@@ -1459,13 +1459,20 @@
1459 blob_set(pPath, "/");
1460 }
1461 }
1462
1463 /*
1464 ** Construct a random temporary filename into pBuf where the name of
1465 ** the temporary file is derived from zBasis. The suffix on the temp
1466 ** file is the same as the suffix on zBasis, and the temp file has
1467 ** the root of zBasis in its name.
1468 **
1469 ** If zTag is not NULL, then try to create the temp-file using zTag
1470 ** as a differentiator. If that fails, or if zTag is NULL, then use
1471 ** a bunch of random characters as the tag.
1472 */
1473 void file_tempname(Blob *pBuf, const char *zBasis, const char *zTag){
1474 #if defined(_WIN32)
1475 const char *azDirs[] = {
1476 0, /* GetTempPath */
1477 0, /* TEMP */
1478 0, /* TMP */
@@ -1488,10 +1495,12 @@
1495 "0123456789";
1496 unsigned int i;
1497 const char *zDir = ".";
1498 int cnt = 0;
1499 char zRand[16];
1500 int nBasis;
1501 const char *zSuffix;
1502
1503 #if defined(_WIN32)
1504 wchar_t zTmpPath[MAX_PATH];
1505
1506 if( GetTempPathW(MAX_PATH, zTmpPath) ){
@@ -1513,19 +1522,43 @@
1522 if( !file_isdir(azDirs[i], ExtFILE) ) continue;
1523 zDir = azDirs[i];
1524 break;
1525 }
1526
1527 assert( zBasis!=0 );
1528 zSuffix = 0;
1529 for(i=0; zBasis[i]; i++){
1530 if( zBasis[i]=='/' || zBasis[i]=='\\' ){
1531 zBasis += i+1;
1532 i = -1;
1533 }else if( zBasis[i]=='.' ){
1534 zSuffix = zBasis + i;
1535 }
1536 }
1537 if( zSuffix==0 || zSuffix<=zBasis ){
1538 zSuffix = "";
1539 nBasis = i;
1540 }else{
1541 nBasis = (int)(zSuffix - zBasis);
1542 }
1543 if( nBasis==0 ){
1544 nBasis = 6;
1545 zBasis = "fossil";
1546 }
1547 do{
1548 blob_zero(pBuf);
1549 if( cnt++>20 ) fossil_panic("cannot generate a temporary filename");
1550 if( zTag==0 ){
1551 sqlite3_randomness(15, zRand);
1552 for(i=0; i<15; i++){
1553 zRand[i] = (char)zChars[ ((unsigned char)zRand[i])%(sizeof(zChars)-1) ];
1554 }
1555 zRand[15] = 0;
1556 zTag = zRand;
1557 }
1558 blob_appendf(pBuf, "%s/%.*s~%s%s", zDir, nBasis, zBasis, zTag, zSuffix);
1559 zTag = 0;
1560 }while( file_size(blob_str(pBuf), ExtFILE)>=0 );
1561
1562 #if defined(_WIN32)
1563 fossil_path_free((char *)azDirs[0]);
1564 fossil_path_free((char *)azDirs[1]);
@@ -1557,28 +1590,30 @@
1590 }
1591
1592
1593 /*
1594 ** COMMAND: test-tempname
1595 ** Usage: fossil test-name [--time SUFFIX] [--tag NAME] BASENAME ...
1596 **
1597 ** Generate temporary filenames derived from BASENAME. Use the --time
1598 ** option to generate temp names based on the time of day. If --tag NAME
1599 ** is specified, try to use NAME as the differentiator in the temp file.
1600 */
1601 void file_test_tempname(void){
1602 int i;
1603 const char *zSuffix = find_option("time",0,1);
1604 Blob x = BLOB_INITIALIZER;
1605 char *z;
1606 const char *zTag = find_option("tag",0,1);
1607 verify_all_options();
1608 for(i=2; i<g.argc; i++){
1609 if( zSuffix ){
1610 z = file_time_tempname(g.argv[i], zSuffix);
1611 fossil_print("%s\n", z);
1612 fossil_free(z);
1613 }else{
1614 file_tempname(&x, g.argv[i], zTag);
1615 fossil_print("%s\n", blob_str(&x));
1616 blob_reset(&x);
1617 }
1618 }
1619 }
1620
+3 -2
--- src/finfo.c
+++ src/finfo.c
@@ -645,16 +645,17 @@
645645
@ </td></tr>
646646
}
647647
db_finalize(&q);
648648
db_finalize(&qparent);
649649
if( pGraph ){
650
- graph_finish(pGraph, 1);
650
+ graph_finish(pGraph, TIMELINE_DISJOINT);
651651
if( pGraph->nErr ){
652652
graph_free(pGraph);
653653
pGraph = 0;
654654
}else{
655
- @ <tr class="timelineBottom"><td></td><td></td><td></td></tr>
655
+ @ <tr class="timelineBottom" id="btm-%d(iTableId)">\
656
+ @ <td></td><td></td><td></td></tr>
656657
}
657658
}
658659
@ </table>
659660
timeline_output_graph_javascript(pGraph, TIMELINE_FILEDIFF, iTableId);
660661
style_footer();
661662
--- src/finfo.c
+++ src/finfo.c
@@ -645,16 +645,17 @@
645 @ </td></tr>
646 }
647 db_finalize(&q);
648 db_finalize(&qparent);
649 if( pGraph ){
650 graph_finish(pGraph, 1);
651 if( pGraph->nErr ){
652 graph_free(pGraph);
653 pGraph = 0;
654 }else{
655 @ <tr class="timelineBottom"><td></td><td></td><td></td></tr>
 
656 }
657 }
658 @ </table>
659 timeline_output_graph_javascript(pGraph, TIMELINE_FILEDIFF, iTableId);
660 style_footer();
661
--- src/finfo.c
+++ src/finfo.c
@@ -645,16 +645,17 @@
645 @ </td></tr>
646 }
647 db_finalize(&q);
648 db_finalize(&qparent);
649 if( pGraph ){
650 graph_finish(pGraph, TIMELINE_DISJOINT);
651 if( pGraph->nErr ){
652 graph_free(pGraph);
653 pGraph = 0;
654 }else{
655 @ <tr class="timelineBottom" id="btm-%d(iTableId)">\
656 @ <td></td><td></td><td></td></tr>
657 }
658 }
659 @ </table>
660 timeline_output_graph_javascript(pGraph, TIMELINE_FILEDIFF, iTableId);
661 style_footer();
662
+34 -4
--- src/graph.c
+++ src/graph.c
@@ -49,10 +49,11 @@
4949
int idx; /* Row index. First is 1. 0 used for "none" */
5050
int idxTop; /* Direct descendent highest up on the graph */
5151
GraphRow *pChild; /* Child immediately above this node */
5252
u8 isDup; /* True if this is duplicate of a prior entry */
5353
u8 isLeaf; /* True if this is a leaf node */
54
+ u8 isStepParent; /* pChild is actually a step-child */
5455
u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
5556
u8 timeWarp; /* Child is earlier in time */
5657
u8 bDescender; /* True if riser from bottom of graph to here. */
5758
i8 iRail; /* Which rail this check-in appears on. 0-based.*/
5859
i8 mergeOut; /* Merge out to this rail. -1 if no merge-out */
@@ -69,12 +70,12 @@
6970
/* Context while building a graph
7071
*/
7172
struct GraphContext {
7273
int nErr; /* Number of errors encountered */
7374
int mxRail; /* Number of rails required to render the graph */
74
- GraphRow *pFirst; /* First row in the list */
75
- GraphRow *pLast; /* Last row in the list */
75
+ GraphRow *pFirst; /* First row in the list. Top row of graph. */
76
+ GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
7677
int nBranch; /* Number of distinct branches */
7778
char **azBranch; /* Names of the branches */
7879
int nRow; /* Number of rows */
7980
int nHash; /* Number of slots in apHash[] */
8081
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
@@ -371,17 +372,24 @@
371372
**
372373
** When primary or merge parents are off-screen, normally a line is drawn
373374
** from the node down to the bottom of the graph. This line is called a
374375
** "descender". But if the omitDescenders flag is true, then lines down
375376
** to the bottom of the screen are omitted.
377
+**
378
+** The tmFlags parameter is zero or more of the TIMELINE_* constants.
379
+** Only the following are honored:
380
+**
381
+** TIMELINE_DISJOINT: Omit descenders
382
+** TIMELINE_FILLGAPS: Use step-children
376383
*/
377
-void graph_finish(GraphContext *p, int omitDescenders){
384
+void graph_finish(GraphContext *p, u32 tmFlags){
378385
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
379386
int i, j;
380387
u64 mask;
381388
int hasDup = 0; /* True if one or more isDup entries */
382389
const char *zTrunk;
390
+ int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
383391
384392
/* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
385393
** coming up from the bottom of the graph from off-screen check-in Y
386394
** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0.
387395
*/
@@ -477,10 +485,32 @@
477485
if( pRow->idxTop < pParent->idxTop ){
478486
pParent->pChild = pRow;
479487
pParent->idxTop = pRow->idxTop;
480488
}
481489
}
490
+
491
+ if( tmFlags & TIMELINE_FILLGAPS ){
492
+ /* If a node has no pChild, and there is a later node (a node higher
493
+ ** up on the graph) in the same branch that has no parent, then make
494
+ ** the lower node a step-child of the upper node.
495
+ */
496
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
497
+ if( pRow->pChild ) continue;
498
+ for(pLoop=pRow->pPrev; pLoop; pLoop=pLoop->pPrev){
499
+ if( pLoop->nParent>0
500
+ && pLoop->zBranch==pRow->zBranch
501
+ && hashFind(p,pLoop->aParent[0])==0
502
+ ){
503
+ pRow->pChild = pLoop;
504
+ pRow->idxTop = pLoop->idxTop;
505
+ pRow->isStepParent = 1;
506
+ pLoop->aParent[0] = pRow->rid;
507
+ break;
508
+ }
509
+ }
510
+ }
511
+ }
482512
483513
/* Identify rows where the primary parent is off screen. Assign
484514
** each to a rail and draw descenders to the bottom of the screen.
485515
**
486516
** Strive to put the "trunk" branch on far left.
@@ -589,11 +619,11 @@
589619
iMrail = j;
590620
break;
591621
}
592622
}
593623
if( iMrail==-1 ){
594
- iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
624
+ iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0);
595625
if( p->mxRail>=GR_MAX_RAIL ) return;
596626
mergeRiserFrom[iMrail] = parentRid;
597627
}
598628
mask = BIT(iMrail);
599629
if( i>=pRow->nNonCherrypick ){
600630
--- src/graph.c
+++ src/graph.c
@@ -49,10 +49,11 @@
49 int idx; /* Row index. First is 1. 0 used for "none" */
50 int idxTop; /* Direct descendent highest up on the graph */
51 GraphRow *pChild; /* Child immediately above this node */
52 u8 isDup; /* True if this is duplicate of a prior entry */
53 u8 isLeaf; /* True if this is a leaf node */
 
54 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
55 u8 timeWarp; /* Child is earlier in time */
56 u8 bDescender; /* True if riser from bottom of graph to here. */
57 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
58 i8 mergeOut; /* Merge out to this rail. -1 if no merge-out */
@@ -69,12 +70,12 @@
69 /* Context while building a graph
70 */
71 struct GraphContext {
72 int nErr; /* Number of errors encountered */
73 int mxRail; /* Number of rails required to render the graph */
74 GraphRow *pFirst; /* First row in the list */
75 GraphRow *pLast; /* Last row in the list */
76 int nBranch; /* Number of distinct branches */
77 char **azBranch; /* Names of the branches */
78 int nRow; /* Number of rows */
79 int nHash; /* Number of slots in apHash[] */
80 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
@@ -371,17 +372,24 @@
371 **
372 ** When primary or merge parents are off-screen, normally a line is drawn
373 ** from the node down to the bottom of the graph. This line is called a
374 ** "descender". But if the omitDescenders flag is true, then lines down
375 ** to the bottom of the screen are omitted.
 
 
 
 
 
 
376 */
377 void graph_finish(GraphContext *p, int omitDescenders){
378 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
379 int i, j;
380 u64 mask;
381 int hasDup = 0; /* True if one or more isDup entries */
382 const char *zTrunk;
 
383
384 /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
385 ** coming up from the bottom of the graph from off-screen check-in Y
386 ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0.
387 */
@@ -477,10 +485,32 @@
477 if( pRow->idxTop < pParent->idxTop ){
478 pParent->pChild = pRow;
479 pParent->idxTop = pRow->idxTop;
480 }
481 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
482
483 /* Identify rows where the primary parent is off screen. Assign
484 ** each to a rail and draw descenders to the bottom of the screen.
485 **
486 ** Strive to put the "trunk" branch on far left.
@@ -589,11 +619,11 @@
589 iMrail = j;
590 break;
591 }
592 }
593 if( iMrail==-1 ){
594 iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
595 if( p->mxRail>=GR_MAX_RAIL ) return;
596 mergeRiserFrom[iMrail] = parentRid;
597 }
598 mask = BIT(iMrail);
599 if( i>=pRow->nNonCherrypick ){
600
--- src/graph.c
+++ src/graph.c
@@ -49,10 +49,11 @@
49 int idx; /* Row index. First is 1. 0 used for "none" */
50 int idxTop; /* Direct descendent highest up on the graph */
51 GraphRow *pChild; /* Child immediately above this node */
52 u8 isDup; /* True if this is duplicate of a prior entry */
53 u8 isLeaf; /* True if this is a leaf node */
54 u8 isStepParent; /* pChild is actually a step-child */
55 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
56 u8 timeWarp; /* Child is earlier in time */
57 u8 bDescender; /* True if riser from bottom of graph to here. */
58 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
59 i8 mergeOut; /* Merge out to this rail. -1 if no merge-out */
@@ -69,12 +70,12 @@
70 /* Context while building a graph
71 */
72 struct GraphContext {
73 int nErr; /* Number of errors encountered */
74 int mxRail; /* Number of rails required to render the graph */
75 GraphRow *pFirst; /* First row in the list. Top row of graph. */
76 GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
77 int nBranch; /* Number of distinct branches */
78 char **azBranch; /* Names of the branches */
79 int nRow; /* Number of rows */
80 int nHash; /* Number of slots in apHash[] */
81 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
@@ -371,17 +372,24 @@
372 **
373 ** When primary or merge parents are off-screen, normally a line is drawn
374 ** from the node down to the bottom of the graph. This line is called a
375 ** "descender". But if the omitDescenders flag is true, then lines down
376 ** to the bottom of the screen are omitted.
377 **
378 ** The tmFlags parameter is zero or more of the TIMELINE_* constants.
379 ** Only the following are honored:
380 **
381 ** TIMELINE_DISJOINT: Omit descenders
382 ** TIMELINE_FILLGAPS: Use step-children
383 */
384 void graph_finish(GraphContext *p, u32 tmFlags){
385 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
386 int i, j;
387 u64 mask;
388 int hasDup = 0; /* True if one or more isDup entries */
389 const char *zTrunk;
390 int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
391
392 /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
393 ** coming up from the bottom of the graph from off-screen check-in Y
394 ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0.
395 */
@@ -477,10 +485,32 @@
485 if( pRow->idxTop < pParent->idxTop ){
486 pParent->pChild = pRow;
487 pParent->idxTop = pRow->idxTop;
488 }
489 }
490
491 if( tmFlags & TIMELINE_FILLGAPS ){
492 /* If a node has no pChild, and there is a later node (a node higher
493 ** up on the graph) in the same branch that has no parent, then make
494 ** the lower node a step-child of the upper node.
495 */
496 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
497 if( pRow->pChild ) continue;
498 for(pLoop=pRow->pPrev; pLoop; pLoop=pLoop->pPrev){
499 if( pLoop->nParent>0
500 && pLoop->zBranch==pRow->zBranch
501 && hashFind(p,pLoop->aParent[0])==0
502 ){
503 pRow->pChild = pLoop;
504 pRow->idxTop = pLoop->idxTop;
505 pRow->isStepParent = 1;
506 pLoop->aParent[0] = pRow->rid;
507 break;
508 }
509 }
510 }
511 }
512
513 /* Identify rows where the primary parent is off screen. Assign
514 ** each to a rail and draw descenders to the bottom of the screen.
515 **
516 ** Strive to put the "trunk" branch on far left.
@@ -589,11 +619,11 @@
619 iMrail = j;
620 break;
621 }
622 }
623 if( iMrail==-1 ){
624 iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0);
625 if( p->mxRail>=GR_MAX_RAIL ) return;
626 mergeRiserFrom[iMrail] = parentRid;
627 }
628 mask = BIT(iMrail);
629 if( i>=pRow->nNonCherrypick ){
630
+10 -2
--- src/graph.js
+++ src/graph.js
@@ -92,11 +92,11 @@
9292
9393
var elems = {};
9494
var elemClasses = [
9595
"rail", "mergeoffset", "node", "arrow u", "arrow u sm", "line",
9696
"arrow merge r", "line merge", "arrow warp", "line warp",
97
- "line cherrypick"
97
+ "line cherrypick", "line dotted"
9898
];
9999
for( var i=0; i<elemClasses.length; i++ ){
100100
var cls = elemClasses[i];
101101
var elem = document.createElement("div");
102102
elem.className = "tl-" + cls;
@@ -115,10 +115,11 @@
115115
mArrow = elems.arrow_merge_r;
116116
mLine = elems.line_merge;
117117
cpLine = elems.line_cherrypick;
118118
wArrow = elems.arrow_warp;
119119
wLine = elems.line_warp;
120
+ dotLine = elems.line_dotted;
120121
121122
var minRailPitch = Math.ceil((node.w+line.w)/2 + mArrow.w + 1);
122123
if( window.innerWidth<400 ){
123124
railPitch = minRailPitch;
124125
}else{
@@ -196,10 +197,16 @@
196197
drawLine(line,color,x,y0,null,y1);
197198
x = to.x + (node.w-arw.w)/2;
198199
var n = drawBox(arw.cls,null,x,y);
199200
if(color) n.style.borderBottomColor = color;
200201
}
202
+ function drawUpDotted(from,to,color){
203
+ var x = to.x + (node.w-line.w)/2;
204
+ var y0 = from.y + node.h/2;
205
+ var y1 = Math.ceil(to.y + node.h);
206
+ drawLine(dotLine,color,x,y0,null,y1);
207
+ }
201208
/* Draw thin horizontal or vertical lines representing merges */
202209
function drawMergeLine(x0,y0,x1,y1){
203210
drawLine(mLine,null,x0,y0,x1,y1);
204211
}
205212
function drawCherrypickLine(x0,y0,x1,y1){
@@ -236,10 +243,11 @@
236243
e = document.getElementById("md"+p.id);
237244
if(e) e.style.backgroundColor = p.bg;
238245
}
239246
if( p.r<0 ) return;
240247
if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
248
+ if( p.sb>0 ) drawUpDotted(p,tx.rowinfo[p.sb-tx.iTopRow],null);
241249
var cls = node.cls;
242250
if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge";
243251
if( p.f&1 ) cls += " leaf";
244252
var n = drawBox(cls,p.bg,p.x,p.y);
245253
n.id = "tln"+p.id;
@@ -348,11 +356,11 @@
348356
for(var i=0; i<tx.rowinfo.length; i++ ){
349357
var e = document.getElementById("m"+tx.rowinfo[i].id);
350358
tx.rowinfo[i].y = absoluteY(e) - canvasY;
351359
tx.rowinfo[i].x = tx.rowinfo[i].r*railPitch;
352360
}
353
- var tlBtm = document.querySelector(".timelineBottom");
361
+ var tlBtm = document.getElementById(tx.bottomRowId);
354362
if( tlBtm.offsetHeight<node.h ){
355363
tlBtm.style.height = node.h + "px";
356364
}
357365
var btm = absoluteY(tlBtm) - canvasY + tlBtm.offsetHeight;
358366
for( var i=0; i<tx.nrail; i++) mergeBtm[i] = btm;
359367
--- src/graph.js
+++ src/graph.js
@@ -92,11 +92,11 @@
92
93 var elems = {};
94 var elemClasses = [
95 "rail", "mergeoffset", "node", "arrow u", "arrow u sm", "line",
96 "arrow merge r", "line merge", "arrow warp", "line warp",
97 "line cherrypick"
98 ];
99 for( var i=0; i<elemClasses.length; i++ ){
100 var cls = elemClasses[i];
101 var elem = document.createElement("div");
102 elem.className = "tl-" + cls;
@@ -115,10 +115,11 @@
115 mArrow = elems.arrow_merge_r;
116 mLine = elems.line_merge;
117 cpLine = elems.line_cherrypick;
118 wArrow = elems.arrow_warp;
119 wLine = elems.line_warp;
 
120
121 var minRailPitch = Math.ceil((node.w+line.w)/2 + mArrow.w + 1);
122 if( window.innerWidth<400 ){
123 railPitch = minRailPitch;
124 }else{
@@ -196,10 +197,16 @@
196 drawLine(line,color,x,y0,null,y1);
197 x = to.x + (node.w-arw.w)/2;
198 var n = drawBox(arw.cls,null,x,y);
199 if(color) n.style.borderBottomColor = color;
200 }
 
 
 
 
 
 
201 /* Draw thin horizontal or vertical lines representing merges */
202 function drawMergeLine(x0,y0,x1,y1){
203 drawLine(mLine,null,x0,y0,x1,y1);
204 }
205 function drawCherrypickLine(x0,y0,x1,y1){
@@ -236,10 +243,11 @@
236 e = document.getElementById("md"+p.id);
237 if(e) e.style.backgroundColor = p.bg;
238 }
239 if( p.r<0 ) return;
240 if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
 
241 var cls = node.cls;
242 if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge";
243 if( p.f&1 ) cls += " leaf";
244 var n = drawBox(cls,p.bg,p.x,p.y);
245 n.id = "tln"+p.id;
@@ -348,11 +356,11 @@
348 for(var i=0; i<tx.rowinfo.length; i++ ){
349 var e = document.getElementById("m"+tx.rowinfo[i].id);
350 tx.rowinfo[i].y = absoluteY(e) - canvasY;
351 tx.rowinfo[i].x = tx.rowinfo[i].r*railPitch;
352 }
353 var tlBtm = document.querySelector(".timelineBottom");
354 if( tlBtm.offsetHeight<node.h ){
355 tlBtm.style.height = node.h + "px";
356 }
357 var btm = absoluteY(tlBtm) - canvasY + tlBtm.offsetHeight;
358 for( var i=0; i<tx.nrail; i++) mergeBtm[i] = btm;
359
--- src/graph.js
+++ src/graph.js
@@ -92,11 +92,11 @@
92
93 var elems = {};
94 var elemClasses = [
95 "rail", "mergeoffset", "node", "arrow u", "arrow u sm", "line",
96 "arrow merge r", "line merge", "arrow warp", "line warp",
97 "line cherrypick", "line dotted"
98 ];
99 for( var i=0; i<elemClasses.length; i++ ){
100 var cls = elemClasses[i];
101 var elem = document.createElement("div");
102 elem.className = "tl-" + cls;
@@ -115,10 +115,11 @@
115 mArrow = elems.arrow_merge_r;
116 mLine = elems.line_merge;
117 cpLine = elems.line_cherrypick;
118 wArrow = elems.arrow_warp;
119 wLine = elems.line_warp;
120 dotLine = elems.line_dotted;
121
122 var minRailPitch = Math.ceil((node.w+line.w)/2 + mArrow.w + 1);
123 if( window.innerWidth<400 ){
124 railPitch = minRailPitch;
125 }else{
@@ -196,10 +197,16 @@
197 drawLine(line,color,x,y0,null,y1);
198 x = to.x + (node.w-arw.w)/2;
199 var n = drawBox(arw.cls,null,x,y);
200 if(color) n.style.borderBottomColor = color;
201 }
202 function drawUpDotted(from,to,color){
203 var x = to.x + (node.w-line.w)/2;
204 var y0 = from.y + node.h/2;
205 var y1 = Math.ceil(to.y + node.h);
206 drawLine(dotLine,color,x,y0,null,y1);
207 }
208 /* Draw thin horizontal or vertical lines representing merges */
209 function drawMergeLine(x0,y0,x1,y1){
210 drawLine(mLine,null,x0,y0,x1,y1);
211 }
212 function drawCherrypickLine(x0,y0,x1,y1){
@@ -236,10 +243,11 @@
243 e = document.getElementById("md"+p.id);
244 if(e) e.style.backgroundColor = p.bg;
245 }
246 if( p.r<0 ) return;
247 if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
248 if( p.sb>0 ) drawUpDotted(p,tx.rowinfo[p.sb-tx.iTopRow],null);
249 var cls = node.cls;
250 if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge";
251 if( p.f&1 ) cls += " leaf";
252 var n = drawBox(cls,p.bg,p.x,p.y);
253 n.id = "tln"+p.id;
@@ -348,11 +356,11 @@
356 for(var i=0; i<tx.rowinfo.length; i++ ){
357 var e = document.getElementById("m"+tx.rowinfo[i].id);
358 tx.rowinfo[i].y = absoluteY(e) - canvasY;
359 tx.rowinfo[i].x = tx.rowinfo[i].r*railPitch;
360 }
361 var tlBtm = document.getElementById(tx.bottomRowId);
362 if( tlBtm.offsetHeight<node.h ){
363 tlBtm.style.height = node.h + "px";
364 }
365 var btm = absoluteY(tlBtm) - canvasY + tlBtm.offsetHeight;
366 for( var i=0; i<tx.nrail; i++) mergeBtm[i] = btm;
367
+1 -1
--- src/href.js
+++ src/href.js
@@ -34,11 +34,11 @@
3434
var jx = x.textContent || x.innerText;
3535
var g = JSON.parse(jx);
3636
var isOperaMini =
3737
Object.prototype.toString.call(window.operamini)==="[object OperaMini]";
3838
if(g.mouseover && !isOperaMini){
39
- document.getElementByTagName("body")[0].onmousemove=function(){
39
+ document.getElementsByTagName("body")[0].onmousemove=function(){
4040
setTimeout(setAllHrefs, g.delay);
4141
}
4242
}else{
4343
setTimeout(setAllHrefs, g.delay);
4444
}
4545
--- src/href.js
+++ src/href.js
@@ -34,11 +34,11 @@
34 var jx = x.textContent || x.innerText;
35 var g = JSON.parse(jx);
36 var isOperaMini =
37 Object.prototype.toString.call(window.operamini)==="[object OperaMini]";
38 if(g.mouseover && !isOperaMini){
39 document.getElementByTagName("body")[0].onmousemove=function(){
40 setTimeout(setAllHrefs, g.delay);
41 }
42 }else{
43 setTimeout(setAllHrefs, g.delay);
44 }
45
--- src/href.js
+++ src/href.js
@@ -34,11 +34,11 @@
34 var jx = x.textContent || x.innerText;
35 var g = JSON.parse(jx);
36 var isOperaMini =
37 Object.prototype.toString.call(window.operamini)==="[object OperaMini]";
38 if(g.mouseover && !isOperaMini){
39 document.getElementsByTagName("body")[0].onmousemove=function(){
40 setTimeout(setAllHrefs, g.delay);
41 }
42 }else{
43 setTimeout(setAllHrefs, g.delay);
44 }
45
+4 -4
--- src/http.c
+++ src/http.c
@@ -286,11 +286,11 @@
286286
g.zHttpAuth = prompt_for_httpauth_creds();
287287
transport_close(&g.url);
288288
return http_exchange(pSend, pReply, useLogin, maxRedirect);
289289
}
290290
}
291
- if( rc!=200 && rc!=301 && rc!=302 ){
291
+ if( rc!=200 && rc!=301 && rc!=302 && rc!=307 && rc!=308 ){
292292
int ii;
293293
for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
294294
while( zLine[ii]==' ' ) ii++;
295295
fossil_warning("server says: %s", &zLine[ii]);
296296
goto write_err;
@@ -300,11 +300,11 @@
300300
}else{
301301
closeConnection = 0;
302302
}
303303
}else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
304304
if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
305
- if( rc!=200 && rc!=301 && rc!=302 ){
305
+ if( rc!=200 && rc!=301 && rc!=302 && rc!=307 && rc!=308 ){
306306
int ii;
307307
for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
308308
while( zLine[ii]==' ' ) ii++;
309309
fossil_warning("server says: %s", &zLine[ii]);
310310
goto write_err;
@@ -320,11 +320,11 @@
320320
if( c=='c' || c=='C' ){
321321
closeConnection = 1;
322322
}else if( c=='k' || c=='K' ){
323323
closeConnection = 0;
324324
}
325
- }else if( ( rc==301 || rc==302 ) &&
325
+ }else if( ( rc==301 || rc==302 || rc==307 || rc==308 ) &&
326326
fossil_strnicmp(zLine, "location:", 9)==0 ){
327327
int i, j;
328328
329329
if ( --maxRedirect == 0){
330330
fossil_warning("redirect limit exceeded");
@@ -345,11 +345,11 @@
345345
transport_close(&g.url);
346346
transport_global_shutdown(&g.url);
347347
fSeenHttpAuth = 0;
348348
if( g.zHttpAuth ) free(g.zHttpAuth);
349349
g.zHttpAuth = get_httpauth();
350
- url_remember();
350
+ if( rc==301 || rc==308 ) url_remember();
351351
return http_exchange(pSend, pReply, useLogin, maxRedirect);
352352
}else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
353353
if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
354354
isCompressed = 0;
355355
}else if( fossil_strnicmp(&zLine[14],
356356
--- src/http.c
+++ src/http.c
@@ -286,11 +286,11 @@
286 g.zHttpAuth = prompt_for_httpauth_creds();
287 transport_close(&g.url);
288 return http_exchange(pSend, pReply, useLogin, maxRedirect);
289 }
290 }
291 if( rc!=200 && rc!=301 && rc!=302 ){
292 int ii;
293 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
294 while( zLine[ii]==' ' ) ii++;
295 fossil_warning("server says: %s", &zLine[ii]);
296 goto write_err;
@@ -300,11 +300,11 @@
300 }else{
301 closeConnection = 0;
302 }
303 }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
304 if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
305 if( rc!=200 && rc!=301 && rc!=302 ){
306 int ii;
307 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
308 while( zLine[ii]==' ' ) ii++;
309 fossil_warning("server says: %s", &zLine[ii]);
310 goto write_err;
@@ -320,11 +320,11 @@
320 if( c=='c' || c=='C' ){
321 closeConnection = 1;
322 }else if( c=='k' || c=='K' ){
323 closeConnection = 0;
324 }
325 }else if( ( rc==301 || rc==302 ) &&
326 fossil_strnicmp(zLine, "location:", 9)==0 ){
327 int i, j;
328
329 if ( --maxRedirect == 0){
330 fossil_warning("redirect limit exceeded");
@@ -345,11 +345,11 @@
345 transport_close(&g.url);
346 transport_global_shutdown(&g.url);
347 fSeenHttpAuth = 0;
348 if( g.zHttpAuth ) free(g.zHttpAuth);
349 g.zHttpAuth = get_httpauth();
350 url_remember();
351 return http_exchange(pSend, pReply, useLogin, maxRedirect);
352 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
353 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
354 isCompressed = 0;
355 }else if( fossil_strnicmp(&zLine[14],
356
--- src/http.c
+++ src/http.c
@@ -286,11 +286,11 @@
286 g.zHttpAuth = prompt_for_httpauth_creds();
287 transport_close(&g.url);
288 return http_exchange(pSend, pReply, useLogin, maxRedirect);
289 }
290 }
291 if( rc!=200 && rc!=301 && rc!=302 && rc!=307 && rc!=308 ){
292 int ii;
293 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
294 while( zLine[ii]==' ' ) ii++;
295 fossil_warning("server says: %s", &zLine[ii]);
296 goto write_err;
@@ -300,11 +300,11 @@
300 }else{
301 closeConnection = 0;
302 }
303 }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
304 if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
305 if( rc!=200 && rc!=301 && rc!=302 && rc!=307 && rc!=308 ){
306 int ii;
307 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
308 while( zLine[ii]==' ' ) ii++;
309 fossil_warning("server says: %s", &zLine[ii]);
310 goto write_err;
@@ -320,11 +320,11 @@
320 if( c=='c' || c=='C' ){
321 closeConnection = 1;
322 }else if( c=='k' || c=='K' ){
323 closeConnection = 0;
324 }
325 }else if( ( rc==301 || rc==302 || rc==307 || rc==308 ) &&
326 fossil_strnicmp(zLine, "location:", 9)==0 ){
327 int i, j;
328
329 if ( --maxRedirect == 0){
330 fossil_warning("redirect limit exceeded");
@@ -345,11 +345,11 @@
345 transport_close(&g.url);
346 transport_global_shutdown(&g.url);
347 fSeenHttpAuth = 0;
348 if( g.zHttpAuth ) free(g.zHttpAuth);
349 g.zHttpAuth = get_httpauth();
350 if( rc==301 || rc==308 ) url_remember();
351 return http_exchange(pSend, pReply, useLogin, maxRedirect);
352 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
353 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
354 isCompressed = 0;
355 }else if( fossil_strnicmp(&zLine[14],
356
+2 -2
--- src/info.c
+++ src/info.c
@@ -281,12 +281,12 @@
281281
}
282282
}
283283
blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
284284
db_prepare(&q, "%s", blob_sql_text(&sql));
285285
www_print_timeline(&q,
286
- TIMELINE_DISJOINT
287
- |TIMELINE_GRAPH
286
+ TIMELINE_GRAPH
287
+ |TIMELINE_FILLGAPS
288288
|TIMELINE_NOSCROLL
289289
|TIMELINE_CHPICK,
290290
0, 0, rid, 0);
291291
db_finalize(&q);
292292
}
293293
--- src/info.c
+++ src/info.c
@@ -281,12 +281,12 @@
281 }
282 }
283 blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
284 db_prepare(&q, "%s", blob_sql_text(&sql));
285 www_print_timeline(&q,
286 TIMELINE_DISJOINT
287 |TIMELINE_GRAPH
288 |TIMELINE_NOSCROLL
289 |TIMELINE_CHPICK,
290 0, 0, rid, 0);
291 db_finalize(&q);
292 }
293
--- src/info.c
+++ src/info.c
@@ -281,12 +281,12 @@
281 }
282 }
283 blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
284 db_prepare(&q, "%s", blob_sql_text(&sql));
285 www_print_timeline(&q,
286 TIMELINE_GRAPH
287 |TIMELINE_FILLGAPS
288 |TIMELINE_NOSCROLL
289 |TIMELINE_CHPICK,
290 0, 0, rid, 0);
291 db_finalize(&q);
292 }
293
+38 -74
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -695,13 +695,13 @@
695695
ZLIBCONFIG =
696696
ZLIBTARGETS =
697697
endif
698698
699699
#### Disable creation of the OpenSSL shared libraries. Also, disable support
700
-# for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
700
+# for SSLv3 (i.e. thereby forcing the use of TLS).
701701
#
702
-SSLCONFIG += no-ssl2 no-ssl3 no-weak-ssl-ciphers no-shared
702
+SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared
703703
704704
#### When using zlib, make sure that OpenSSL is configured to use the zlib
705705
# that Fossil knows about (i.e. the one within the source tree).
706706
#
707707
ifndef FOSSIL_ENABLE_MINIZ
@@ -711,11 +711,11 @@
711711
#### The directories where the OpenSSL include and library files are located.
712712
# The recommended usage here is to use the Sysinternals junction tool
713713
# to create a hard link between an "openssl-1.x" sub-directory of the
714714
# Fossil source code directory and the target OpenSSL source directory.
715715
#
716
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2r
716
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1b
717717
OPENSSLINCDIR = $(OPENSSLDIR)/include
718718
OPENSSLLIBDIR = $(OPENSSLDIR)
719719
720720
#### Either the directory where the Tcl library is installed or the Tcl
721721
# source code directory resides (depending on the value of the macro
@@ -1165,10 +1165,11 @@
11651165
BLDTARGETS = zlib
11661166
endif
11671167
11681168
openssl: $(BLDTARGETS)
11691169
cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
1170
+ sed -i -e 's/^PERL=C:\\.*$$/PERL=perl.exe/i' $(OPENSSLLIBDIR)/Makefile
11701171
$(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
11711172
11721173
clean-openssl:
11731174
$(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
11741175
@@ -1567,78 +1568,42 @@
15671568
!ifndef USE_SEE
15681569
USE_SEE = 0
15691570
!endif
15701571
15711572
!if $(FOSSIL_ENABLE_SSL)!=0
1572
-SSLDIR = $(B)\compat\openssl-1.0.2r
1573
-SSLINCDIR = $(SSLDIR)\inc32
1574
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
1575
-SSLLIBDIR = $(SSLDIR)\out32dll
1576
-!else
1577
-SSLLIBDIR = $(SSLDIR)\out32
1578
-!endif
1579
-SSLLFLAGS = /nologo /opt:ref /debug
1580
-SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib
1581
-!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1582
-!message Using 'x64' platform for OpenSSL...
1583
-# BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
1584
-# SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
1585
-SSLCONFIG = VC-WIN64A no-asm
1586
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
1587
-SSLCONFIG = $(SSLCONFIG) shared
1588
-!else
1589
-SSLCONFIG = $(SSLCONFIG) no-shared
1590
-!endif
1591
-SSLSETUP = ms\do_win64a.bat
1592
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
1593
-SSLNMAKE = ms\ntdll.mak all
1594
-!else
1595
-SSLNMAKE = ms\nt.mak all
1596
-!endif
1597
-# BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
1598
-!if $(FOSSIL_DYNAMIC_BUILD)==0
1599
-SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
1600
-!endif
1601
-!elseif "$(PLATFORM)"=="ia64"
1602
-!message Using 'ia64' platform for OpenSSL...
1603
-# BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
1604
-# SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
1605
-SSLCONFIG = VC-WIN64I no-asm
1606
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
1607
-SSLCONFIG = $(SSLCONFIG) shared
1608
-!else
1609
-SSLCONFIG = $(SSLCONFIG) no-shared
1610
-!endif
1611
-SSLSETUP = ms\do_win64i.bat
1612
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
1613
-SSLNMAKE = ms\ntdll.mak all
1614
-!else
1615
-SSLNMAKE = ms\nt.mak all
1616
-!endif
1617
-# BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
1618
-!if $(FOSSIL_DYNAMIC_BUILD)==0
1619
-SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
1620
-!endif
1621
-!else
1622
-!message Assuming 'x86' platform for OpenSSL...
1623
-# BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
1624
-# SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
1625
-SSLCONFIG = VC-WIN32 no-asm
1626
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
1627
-SSLCONFIG = $(SSLCONFIG) shared
1628
-!else
1629
-SSLCONFIG = $(SSLCONFIG) no-shared
1630
-!endif
1631
-SSLSETUP = ms\do_ms.bat
1632
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
1633
-SSLNMAKE = ms\ntdll.mak all
1634
-!else
1635
-SSLNMAKE = ms\nt.mak all
1636
-!endif
1637
-# BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
1638
-!if $(FOSSIL_DYNAMIC_BUILD)==0
1639
-SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
1573
+SSLDIR = $(B)\compat\openssl-1.1.1b
1574
+SSLINCDIR = $(SSLDIR)\include
1575
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
1576
+SSLLIBDIR = $(SSLDIR)
1577
+!else
1578
+SSLLIBDIR = $(SSLDIR)
1579
+!endif
1580
+SSLLFLAGS = /nologo /opt:ref /debug
1581
+SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
1582
+!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1583
+!message Using 'x64' platform for OpenSSL...
1584
+SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
1585
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
1586
+SSLCONFIG = $(SSLCONFIG) shared
1587
+!else
1588
+SSLCONFIG = $(SSLCONFIG) no-shared
1589
+!endif
1590
+!elseif "$(PLATFORM)"=="ia64"
1591
+!message Using 'ia64' platform for OpenSSL...
1592
+SSLCONFIG = VC-WIN64I no-asm no-ssl3 no-weak-ssl-ciphers
1593
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
1594
+SSLCONFIG = $(SSLCONFIG) shared
1595
+!else
1596
+SSLCONFIG = $(SSLCONFIG) no-shared
1597
+!endif
1598
+!else
1599
+!message Assuming 'x86' platform for OpenSSL...
1600
+SSLCONFIG = VC-WIN32 no-asm no-ssl3 no-weak-ssl-ciphers
1601
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
1602
+SSLCONFIG = $(SSLCONFIG) shared
1603
+!else
1604
+SSLCONFIG = $(SSLCONFIG) no-shared
16401605
!endif
16411606
!endif
16421607
!endif
16431608
16441609
!if $(FOSSIL_ENABLE_TCL)!=0
@@ -1857,15 +1822,14 @@
18571822
@echo Building OpenSSL from "$(SSLDIR)"...
18581823
!if "$(PERLDIR)" != ""
18591824
@set PATH=$(PERLDIR);$(PATH)
18601825
!endif
18611826
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1862
- @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
18631827
!if $(FOSSIL_ENABLE_WINXP)!=0
1864
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1828
+ @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
18651829
!else
1866
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
1830
+ @pushd "$(SSLDIR)" && $(MAKE) && popd
18671831
!endif
18681832
!endif
18691833
18701834
!if $(FOSSIL_ENABLE_MINIZ)==0
18711835
!if $(FOSSIL_BUILD_ZLIB)!=0
18721836
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -695,13 +695,13 @@
695 ZLIBCONFIG =
696 ZLIBTARGETS =
697 endif
698
699 #### Disable creation of the OpenSSL shared libraries. Also, disable support
700 # for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
701 #
702 SSLCONFIG += no-ssl2 no-ssl3 no-weak-ssl-ciphers no-shared
703
704 #### When using zlib, make sure that OpenSSL is configured to use the zlib
705 # that Fossil knows about (i.e. the one within the source tree).
706 #
707 ifndef FOSSIL_ENABLE_MINIZ
@@ -711,11 +711,11 @@
711 #### The directories where the OpenSSL include and library files are located.
712 # The recommended usage here is to use the Sysinternals junction tool
713 # to create a hard link between an "openssl-1.x" sub-directory of the
714 # Fossil source code directory and the target OpenSSL source directory.
715 #
716 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2r
717 OPENSSLINCDIR = $(OPENSSLDIR)/include
718 OPENSSLLIBDIR = $(OPENSSLDIR)
719
720 #### Either the directory where the Tcl library is installed or the Tcl
721 # source code directory resides (depending on the value of the macro
@@ -1165,10 +1165,11 @@
1165 BLDTARGETS = zlib
1166 endif
1167
1168 openssl: $(BLDTARGETS)
1169 cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
 
1170 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
1171
1172 clean-openssl:
1173 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
1174
@@ -1567,78 +1568,42 @@
1567 !ifndef USE_SEE
1568 USE_SEE = 0
1569 !endif
1570
1571 !if $(FOSSIL_ENABLE_SSL)!=0
1572 SSLDIR = $(B)\compat\openssl-1.0.2r
1573 SSLINCDIR = $(SSLDIR)\inc32
1574 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1575 SSLLIBDIR = $(SSLDIR)\out32dll
1576 !else
1577 SSLLIBDIR = $(SSLDIR)\out32
1578 !endif
1579 SSLLFLAGS = /nologo /opt:ref /debug
1580 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib
1581 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1582 !message Using 'x64' platform for OpenSSL...
1583 # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
1584 # SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
1585 SSLCONFIG = VC-WIN64A no-asm
1586 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1587 SSLCONFIG = $(SSLCONFIG) shared
1588 !else
1589 SSLCONFIG = $(SSLCONFIG) no-shared
1590 !endif
1591 SSLSETUP = ms\do_win64a.bat
1592 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1593 SSLNMAKE = ms\ntdll.mak all
1594 !else
1595 SSLNMAKE = ms\nt.mak all
1596 !endif
1597 # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
1598 !if $(FOSSIL_DYNAMIC_BUILD)==0
1599 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
1600 !endif
1601 !elseif "$(PLATFORM)"=="ia64"
1602 !message Using 'ia64' platform for OpenSSL...
1603 # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
1604 # SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
1605 SSLCONFIG = VC-WIN64I no-asm
1606 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1607 SSLCONFIG = $(SSLCONFIG) shared
1608 !else
1609 SSLCONFIG = $(SSLCONFIG) no-shared
1610 !endif
1611 SSLSETUP = ms\do_win64i.bat
1612 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1613 SSLNMAKE = ms\ntdll.mak all
1614 !else
1615 SSLNMAKE = ms\nt.mak all
1616 !endif
1617 # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
1618 !if $(FOSSIL_DYNAMIC_BUILD)==0
1619 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
1620 !endif
1621 !else
1622 !message Assuming 'x86' platform for OpenSSL...
1623 # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
1624 # SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
1625 SSLCONFIG = VC-WIN32 no-asm
1626 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1627 SSLCONFIG = $(SSLCONFIG) shared
1628 !else
1629 SSLCONFIG = $(SSLCONFIG) no-shared
1630 !endif
1631 SSLSETUP = ms\do_ms.bat
1632 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1633 SSLNMAKE = ms\ntdll.mak all
1634 !else
1635 SSLNMAKE = ms\nt.mak all
1636 !endif
1637 # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
1638 !if $(FOSSIL_DYNAMIC_BUILD)==0
1639 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
1640 !endif
1641 !endif
1642 !endif
1643
1644 !if $(FOSSIL_ENABLE_TCL)!=0
@@ -1857,15 +1822,14 @@
1857 @echo Building OpenSSL from "$(SSLDIR)"...
1858 !if "$(PERLDIR)" != ""
1859 @set PATH=$(PERLDIR);$(PATH)
1860 !endif
1861 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1862 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
1863 !if $(FOSSIL_ENABLE_WINXP)!=0
1864 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1865 !else
1866 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
1867 !endif
1868 !endif
1869
1870 !if $(FOSSIL_ENABLE_MINIZ)==0
1871 !if $(FOSSIL_BUILD_ZLIB)!=0
1872
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -695,13 +695,13 @@
695 ZLIBCONFIG =
696 ZLIBTARGETS =
697 endif
698
699 #### Disable creation of the OpenSSL shared libraries. Also, disable support
700 # for SSLv3 (i.e. thereby forcing the use of TLS).
701 #
702 SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared
703
704 #### When using zlib, make sure that OpenSSL is configured to use the zlib
705 # that Fossil knows about (i.e. the one within the source tree).
706 #
707 ifndef FOSSIL_ENABLE_MINIZ
@@ -711,11 +711,11 @@
711 #### The directories where the OpenSSL include and library files are located.
712 # The recommended usage here is to use the Sysinternals junction tool
713 # to create a hard link between an "openssl-1.x" sub-directory of the
714 # Fossil source code directory and the target OpenSSL source directory.
715 #
716 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1b
717 OPENSSLINCDIR = $(OPENSSLDIR)/include
718 OPENSSLLIBDIR = $(OPENSSLDIR)
719
720 #### Either the directory where the Tcl library is installed or the Tcl
721 # source code directory resides (depending on the value of the macro
@@ -1165,10 +1165,11 @@
1165 BLDTARGETS = zlib
1166 endif
1167
1168 openssl: $(BLDTARGETS)
1169 cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
1170 sed -i -e 's/^PERL=C:\\.*$$/PERL=perl.exe/i' $(OPENSSLLIBDIR)/Makefile
1171 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
1172
1173 clean-openssl:
1174 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
1175
@@ -1567,78 +1568,42 @@
1568 !ifndef USE_SEE
1569 USE_SEE = 0
1570 !endif
1571
1572 !if $(FOSSIL_ENABLE_SSL)!=0
1573 SSLDIR = $(B)\compat\openssl-1.1.1b
1574 SSLINCDIR = $(SSLDIR)\include
1575 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1576 SSLLIBDIR = $(SSLDIR)
1577 !else
1578 SSLLIBDIR = $(SSLDIR)
1579 !endif
1580 SSLLFLAGS = /nologo /opt:ref /debug
1581 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
1582 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1583 !message Using 'x64' platform for OpenSSL...
1584 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
1585 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1586 SSLCONFIG = $(SSLCONFIG) shared
1587 !else
1588 SSLCONFIG = $(SSLCONFIG) no-shared
1589 !endif
1590 !elseif "$(PLATFORM)"=="ia64"
1591 !message Using 'ia64' platform for OpenSSL...
1592 SSLCONFIG = VC-WIN64I no-asm no-ssl3 no-weak-ssl-ciphers
1593 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1594 SSLCONFIG = $(SSLCONFIG) shared
1595 !else
1596 SSLCONFIG = $(SSLCONFIG) no-shared
1597 !endif
1598 !else
1599 !message Assuming 'x86' platform for OpenSSL...
1600 SSLCONFIG = VC-WIN32 no-asm no-ssl3 no-weak-ssl-ciphers
1601 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1602 SSLCONFIG = $(SSLCONFIG) shared
1603 !else
1604 SSLCONFIG = $(SSLCONFIG) no-shared
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1605 !endif
1606 !endif
1607 !endif
1608
1609 !if $(FOSSIL_ENABLE_TCL)!=0
@@ -1857,15 +1822,14 @@
1822 @echo Building OpenSSL from "$(SSLDIR)"...
1823 !if "$(PERLDIR)" != ""
1824 @set PATH=$(PERLDIR);$(PATH)
1825 !endif
1826 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
 
1827 !if $(FOSSIL_ENABLE_WINXP)!=0
1828 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1829 !else
1830 @pushd "$(SSLDIR)" && $(MAKE) && popd
1831 !endif
1832 !endif
1833
1834 !if $(FOSSIL_ENABLE_MINIZ)==0
1835 !if $(FOSSIL_BUILD_ZLIB)!=0
1836
--- src/markdown.md
+++ src/markdown.md
@@ -58,10 +58,11 @@
5858
>
5959
* bullet item
6060
+ bullet item
6161
- bullet item
6262
1. numbered item
63
+ 2) numbered item
6364
6465
> A two-level list is created by placing additional whitespace before the
6566
> **\***/**+**/**-**/**1.** of the secondary items.
6667
6768
>
6869
--- src/markdown.md
+++ src/markdown.md
@@ -58,10 +58,11 @@
58 >
59 * bullet item
60 + bullet item
61 - bullet item
62 1. numbered item
 
63
64 > A two-level list is created by placing additional whitespace before the
65 > **\***/**+**/**-**/**1.** of the secondary items.
66
67 >
68
--- src/markdown.md
+++ src/markdown.md
@@ -58,10 +58,11 @@
58 >
59 * bullet item
60 + bullet item
61 - bullet item
62 1. numbered item
63 2) numbered item
64
65 > A two-level list is created by placing additional whitespace before the
66 > **\***/**+**/**-**/**1.** of the secondary items.
67
68 >
69
+1 -1
--- src/merge.c
+++ src/merge.c
@@ -752,11 +752,11 @@
752752
zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName);
753753
}
754754
zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
755755
if( file_size(zFullNewPath, RepoFILE)>=0 ){
756756
Blob tmpPath;
757
- file_tempname(&tmpPath, "");
757
+ file_tempname(&tmpPath, "", 0);
758758
db_multi_exec("INSERT INTO tmprn(fn,tmpfn) VALUES(%Q,%Q)",
759759
zNewName, blob_str(&tmpPath));
760760
if( file_islink(zFullNewPath) ){
761761
symlink_copy(zFullNewPath, blob_str(&tmpPath));
762762
}else{
763763
--- src/merge.c
+++ src/merge.c
@@ -752,11 +752,11 @@
752 zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName);
753 }
754 zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
755 if( file_size(zFullNewPath, RepoFILE)>=0 ){
756 Blob tmpPath;
757 file_tempname(&tmpPath, "");
758 db_multi_exec("INSERT INTO tmprn(fn,tmpfn) VALUES(%Q,%Q)",
759 zNewName, blob_str(&tmpPath));
760 if( file_islink(zFullNewPath) ){
761 symlink_copy(zFullNewPath, blob_str(&tmpPath));
762 }else{
763
--- src/merge.c
+++ src/merge.c
@@ -752,11 +752,11 @@
752 zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName);
753 }
754 zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
755 if( file_size(zFullNewPath, RepoFILE)>=0 ){
756 Blob tmpPath;
757 file_tempname(&tmpPath, "", 0);
758 db_multi_exec("INSERT INTO tmprn(fn,tmpfn) VALUES(%Q,%Q)",
759 zNewName, blob_str(&tmpPath));
760 if( file_islink(zFullNewPath) ){
761 symlink_copy(zFullNewPath, blob_str(&tmpPath));
762 }else{
763
--- src/moderate.c
+++ src/moderate.c
@@ -189,5 +189,38 @@
189189
www_print_timeline(&q, 0, 0, 0, 0, 0);
190190
db_finalize(&q);
191191
}
192192
style_footer();
193193
}
194
+
195
+/*
196
+** Disapproves any entries in the modreq table which belong to any
197
+** user whose name is no longer found in the user table. This is only
198
+** intended to be called after user deletion via /setup_uedit.
199
+**
200
+** To figure out whether a name exists it cross-references
201
+** coalesce(event.euser, event.user) with user.login, limiting the
202
+** selection to event entries where objid matches an entry in the
203
+** modreq table.
204
+**
205
+** This is a no-op if called without g.perm.Admin permissions or if
206
+** moderation_table_exists() returns false.
207
+*/
208
+void moderation_disapprove_for_missing_users(){
209
+ Stmt q;
210
+ if( !g.perm.Admin || !moderation_table_exists() ){
211
+ return;
212
+ }
213
+ db_begin_transaction();
214
+ db_prepare(&q,
215
+ "SELECT objid FROM event WHERE objid IN "
216
+ "(SELECT objid FROM modreq) "
217
+ "AND coalesce(euser,user) NOT IN "
218
+ "(SELECT login FROM user)"
219
+ );
220
+ while( db_step(&q)==SQLITE_ROW ){
221
+ int const objid = db_column_int(&q, 0);
222
+ moderation_disapprove(objid);
223
+ }
224
+ db_finalize(&q);
225
+ db_end_transaction(0);
226
+}
194227
--- src/moderate.c
+++ src/moderate.c
@@ -189,5 +189,38 @@
189 www_print_timeline(&q, 0, 0, 0, 0, 0);
190 db_finalize(&q);
191 }
192 style_footer();
193 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
--- src/moderate.c
+++ src/moderate.c
@@ -189,5 +189,38 @@
189 www_print_timeline(&q, 0, 0, 0, 0, 0);
190 db_finalize(&q);
191 }
192 style_footer();
193 }
194
195 /*
196 ** Disapproves any entries in the modreq table which belong to any
197 ** user whose name is no longer found in the user table. This is only
198 ** intended to be called after user deletion via /setup_uedit.
199 **
200 ** To figure out whether a name exists it cross-references
201 ** coalesce(event.euser, event.user) with user.login, limiting the
202 ** selection to event entries where objid matches an entry in the
203 ** modreq table.
204 **
205 ** This is a no-op if called without g.perm.Admin permissions or if
206 ** moderation_table_exists() returns false.
207 */
208 void moderation_disapprove_for_missing_users(){
209 Stmt q;
210 if( !g.perm.Admin || !moderation_table_exists() ){
211 return;
212 }
213 db_begin_transaction();
214 db_prepare(&q,
215 "SELECT objid FROM event WHERE objid IN "
216 "(SELECT objid FROM modreq) "
217 "AND coalesce(euser,user) NOT IN "
218 "(SELECT login FROM user)"
219 );
220 while( db_step(&q)==SQLITE_ROW ){
221 int const objid = db_column_int(&q, 0);
222 moderation_disapprove(objid);
223 }
224 db_finalize(&q);
225 db_end_transaction(0);
226 }
227
+16
--- src/printf.c
+++ src/printf.c
@@ -99,10 +99,11 @@
9999
#define etFOSSILIZE 20 /* The fossil header encoding format. */
100100
#define etPATH 21 /* Path type */
101101
#define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
102102
#define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
103103
#define etROOT 24 /* String value of g.zTop: %R */
104
+#define etJSONSTR 25 /* String encoded as a JSON string literal: %j */
104105
105106
106107
/*
107108
** An "etByte" is an 8-bit unsigned value.
108109
*/
@@ -150,10 +151,11 @@
150151
{ 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
151152
{ 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
152153
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
153154
{ 'F', 0, 4, etFOSSILIZE, 0, 0 },
154155
{ 'S', 0, 4, etSTRINGID, 0, 0 },
156
+ { 'j', 0, 0, etJSONSTR, 0, 0 },
155157
{ 'c', 0, 0, etCHARX, 0, 0 },
156158
{ 'o', 8, 0, etRADIX, 0, 2 },
157159
{ 'u', 10, 0, etRADIX, 0, 0 },
158160
{ 'x', 16, 0, etRADIX, 16, 1 },
159161
{ 'X', 16, 0, etRADIX, 0, 4 },
@@ -779,10 +781,24 @@
779781
case etFOSSILIZE: {
780782
int limit = flag_alternateform ? va_arg(ap,int) : -1;
781783
char *zMem = va_arg(ap,char*);
782784
if( zMem==0 ) zMem = "";
783785
zExtra = bufpt = fossilize(zMem, limit);
786
+ length = strlen(bufpt);
787
+ if( precision>=0 && precision<length ) length = precision;
788
+ break;
789
+ }
790
+ case etJSONSTR: {
791
+ int limit = flag_alternateform ? va_arg(ap,int) : -1;
792
+ char *zMem = va_arg(ap,char*);
793
+ if( limit!=0 ){
794
+ /* Ignore the limit flag, if set, for JSON string
795
+ ** output. This block exists to squelch the associated
796
+ ** "unused variable" compiler warning. */
797
+ }
798
+ if( zMem==0 ) zMem = "";
799
+ zExtra = bufpt = encode_json_string_literal(zMem);
784800
length = strlen(bufpt);
785801
if( precision>=0 && precision<length ) length = precision;
786802
break;
787803
}
788804
case etWIKISTR: {
789805
--- src/printf.c
+++ src/printf.c
@@ -99,10 +99,11 @@
99 #define etFOSSILIZE 20 /* The fossil header encoding format. */
100 #define etPATH 21 /* Path type */
101 #define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
102 #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
103 #define etROOT 24 /* String value of g.zTop: %R */
 
104
105
106 /*
107 ** An "etByte" is an 8-bit unsigned value.
108 */
@@ -150,10 +151,11 @@
150 { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
151 { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
152 { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
153 { 'F', 0, 4, etFOSSILIZE, 0, 0 },
154 { 'S', 0, 4, etSTRINGID, 0, 0 },
 
155 { 'c', 0, 0, etCHARX, 0, 0 },
156 { 'o', 8, 0, etRADIX, 0, 2 },
157 { 'u', 10, 0, etRADIX, 0, 0 },
158 { 'x', 16, 0, etRADIX, 16, 1 },
159 { 'X', 16, 0, etRADIX, 0, 4 },
@@ -779,10 +781,24 @@
779 case etFOSSILIZE: {
780 int limit = flag_alternateform ? va_arg(ap,int) : -1;
781 char *zMem = va_arg(ap,char*);
782 if( zMem==0 ) zMem = "";
783 zExtra = bufpt = fossilize(zMem, limit);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
784 length = strlen(bufpt);
785 if( precision>=0 && precision<length ) length = precision;
786 break;
787 }
788 case etWIKISTR: {
789
--- src/printf.c
+++ src/printf.c
@@ -99,10 +99,11 @@
99 #define etFOSSILIZE 20 /* The fossil header encoding format. */
100 #define etPATH 21 /* Path type */
101 #define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
102 #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */
103 #define etROOT 24 /* String value of g.zTop: %R */
104 #define etJSONSTR 25 /* String encoded as a JSON string literal: %j */
105
106
107 /*
108 ** An "etByte" is an 8-bit unsigned value.
109 */
@@ -150,10 +151,11 @@
151 { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
152 { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
153 { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
154 { 'F', 0, 4, etFOSSILIZE, 0, 0 },
155 { 'S', 0, 4, etSTRINGID, 0, 0 },
156 { 'j', 0, 0, etJSONSTR, 0, 0 },
157 { 'c', 0, 0, etCHARX, 0, 0 },
158 { 'o', 8, 0, etRADIX, 0, 2 },
159 { 'u', 10, 0, etRADIX, 0, 0 },
160 { 'x', 16, 0, etRADIX, 16, 1 },
161 { 'X', 16, 0, etRADIX, 0, 4 },
@@ -779,10 +781,24 @@
781 case etFOSSILIZE: {
782 int limit = flag_alternateform ? va_arg(ap,int) : -1;
783 char *zMem = va_arg(ap,char*);
784 if( zMem==0 ) zMem = "";
785 zExtra = bufpt = fossilize(zMem, limit);
786 length = strlen(bufpt);
787 if( precision>=0 && precision<length ) length = precision;
788 break;
789 }
790 case etJSONSTR: {
791 int limit = flag_alternateform ? va_arg(ap,int) : -1;
792 char *zMem = va_arg(ap,char*);
793 if( limit!=0 ){
794 /* Ignore the limit flag, if set, for JSON string
795 ** output. This block exists to squelch the associated
796 ** "unused variable" compiler warning. */
797 }
798 if( zMem==0 ) zMem = "";
799 zExtra = bufpt = encode_json_string_literal(zMem);
800 length = strlen(bufpt);
801 if( precision>=0 && precision<length ) length = precision;
802 break;
803 }
804 case etWIKISTR: {
805
+5 -7
--- src/repolist.c
+++ src/repolist.c
@@ -46,11 +46,11 @@
4646
pRepo->isValid = 0;
4747
pRepo->zProjName = 0;
4848
pRepo->rMTime = 0.0;
4949
5050
g.dbIgnoreErrors++;
51
- rc = sqlite3_open(pRepo->zRepoName, &db);
51
+ rc = sqlite3_open_v2(pRepo->zRepoName, &db, SQLITE_OPEN_READWRITE, 0);
5252
if( rc ) goto finish_repo_list;
5353
rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
5454
" WHERE name='project-name'",
5555
-1, &pStmt, 0);
5656
if( rc ) goto finish_repo_list;
@@ -164,17 +164,15 @@
164164
}
165165
x.zRepoName = zFull;
166166
remote_repo_info(&x);
167167
fossil_free(zFull);
168168
if( !x.isValid ){
169
- zAge = mprintf("...");
170
- iAge = 0;
171
- }else{
172
- iAge = (rNow - x.rMTime)*86400;
173
- if( iAge<0 ) x.rMTime = rNow;
174
- zAge = human_readable_age(rNow - x.rMTime);
169
+ continue;
175170
}
171
+ iAge = (rNow - x.rMTime)*86400;
172
+ if( iAge<0 ) x.rMTime = rNow;
173
+ zAge = human_readable_age(rNow - x.rMTime);
176174
@ <tr><td valign="top">\
177175
if( sqlite3_strglob("*.fossil", zName)!=0 ){
178176
/* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
179177
** do not work for repositories whose names do not end in ".fossil".
180178
** So do not hyperlink those cases. */
181179
--- src/repolist.c
+++ src/repolist.c
@@ -46,11 +46,11 @@
46 pRepo->isValid = 0;
47 pRepo->zProjName = 0;
48 pRepo->rMTime = 0.0;
49
50 g.dbIgnoreErrors++;
51 rc = sqlite3_open(pRepo->zRepoName, &db);
52 if( rc ) goto finish_repo_list;
53 rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
54 " WHERE name='project-name'",
55 -1, &pStmt, 0);
56 if( rc ) goto finish_repo_list;
@@ -164,17 +164,15 @@
164 }
165 x.zRepoName = zFull;
166 remote_repo_info(&x);
167 fossil_free(zFull);
168 if( !x.isValid ){
169 zAge = mprintf("...");
170 iAge = 0;
171 }else{
172 iAge = (rNow - x.rMTime)*86400;
173 if( iAge<0 ) x.rMTime = rNow;
174 zAge = human_readable_age(rNow - x.rMTime);
175 }
 
 
 
176 @ <tr><td valign="top">\
177 if( sqlite3_strglob("*.fossil", zName)!=0 ){
178 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
179 ** do not work for repositories whose names do not end in ".fossil".
180 ** So do not hyperlink those cases. */
181
--- src/repolist.c
+++ src/repolist.c
@@ -46,11 +46,11 @@
46 pRepo->isValid = 0;
47 pRepo->zProjName = 0;
48 pRepo->rMTime = 0.0;
49
50 g.dbIgnoreErrors++;
51 rc = sqlite3_open_v2(pRepo->zRepoName, &db, SQLITE_OPEN_READWRITE, 0);
52 if( rc ) goto finish_repo_list;
53 rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
54 " WHERE name='project-name'",
55 -1, &pStmt, 0);
56 if( rc ) goto finish_repo_list;
@@ -164,17 +164,15 @@
164 }
165 x.zRepoName = zFull;
166 remote_repo_info(&x);
167 fossil_free(zFull);
168 if( !x.isValid ){
169 continue;
 
 
 
 
 
170 }
171 iAge = (rNow - x.rMTime)*86400;
172 if( iAge<0 ) x.rMTime = rNow;
173 zAge = human_readable_age(rNow - x.rMTime);
174 @ <tr><td valign="top">\
175 if( sqlite3_strglob("*.fossil", zName)!=0 ){
176 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
177 ** do not work for repositories whose names do not end in ".fossil".
178 ** So do not hyperlink those cases. */
179
--- src/security_audit.c
+++ src/security_audit.c
@@ -36,12 +36,17 @@
3636
3737
3838
/*
3939
** WEBPAGE: secaudit0
4040
**
41
-** Run a security audit of the current Fossil setup.
42
-** This page requires administrator access
41
+** Run a security audit of the current Fossil setup, looking
42
+** for configuration problems that might allow unauthorized
43
+** access to the repository.
44
+**
45
+** This page requires administrator access. It is usually
46
+** accessed using the Admin/Security-Audit menu option
47
+** from any of the default skins.
4348
*/
4449
void secaudit0_page(void){
4550
const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
4651
const char *zPubPages; /* GLOB pattern for public pages */
4752
const char *zSelfCap; /* Capabilities of self-registered users */
4853
--- src/security_audit.c
+++ src/security_audit.c
@@ -36,12 +36,17 @@
36
37
38 /*
39 ** WEBPAGE: secaudit0
40 **
41 ** Run a security audit of the current Fossil setup.
42 ** This page requires administrator access
 
 
 
 
 
43 */
44 void secaudit0_page(void){
45 const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
46 const char *zPubPages; /* GLOB pattern for public pages */
47 const char *zSelfCap; /* Capabilities of self-registered users */
48
--- src/security_audit.c
+++ src/security_audit.c
@@ -36,12 +36,17 @@
36
37
38 /*
39 ** WEBPAGE: secaudit0
40 **
41 ** Run a security audit of the current Fossil setup, looking
42 ** for configuration problems that might allow unauthorized
43 ** access to the repository.
44 **
45 ** This page requires administrator access. It is usually
46 ** accessed using the Admin/Security-Audit menu option
47 ** from any of the default skins.
48 */
49 void secaudit0_page(void){
50 const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
51 const char *zPubPages; /* GLOB pattern for public pages */
52 const char *zSelfCap; /* Capabilities of self-registered users */
53
--- src/setupuser.c
+++ src/setupuser.c
@@ -297,10 +297,13 @@
297297
if( P("delete") && cgi_csrf_safe(1) ){
298298
int n;
299299
if( P("verifydelete") ){
300300
/* Verified delete user request */
301301
db_multi_exec("DELETE FROM user WHERE uid=%d", uid);
302
+ moderation_disapprove_for_missing_users();
303
+ admin_log("Deleted user [%s] (uid %d).",
304
+ PD("login","???")/*safe-for-%s*/, uid);
302305
cgi_redirect(cgi_referer("setup_ulist"));
303306
return;
304307
}
305308
n = db_int(0, "SELECT count(*) FROM event"
306309
" WHERE user=%Q AND objid NOT IN private",
307310
--- src/setupuser.c
+++ src/setupuser.c
@@ -297,10 +297,13 @@
297 if( P("delete") && cgi_csrf_safe(1) ){
298 int n;
299 if( P("verifydelete") ){
300 /* Verified delete user request */
301 db_multi_exec("DELETE FROM user WHERE uid=%d", uid);
 
 
 
302 cgi_redirect(cgi_referer("setup_ulist"));
303 return;
304 }
305 n = db_int(0, "SELECT count(*) FROM event"
306 " WHERE user=%Q AND objid NOT IN private",
307
--- src/setupuser.c
+++ src/setupuser.c
@@ -297,10 +297,13 @@
297 if( P("delete") && cgi_csrf_safe(1) ){
298 int n;
299 if( P("verifydelete") ){
300 /* Verified delete user request */
301 db_multi_exec("DELETE FROM user WHERE uid=%d", uid);
302 moderation_disapprove_for_missing_users();
303 admin_log("Deleted user [%s] (uid %d).",
304 PD("login","???")/*safe-for-%s*/, uid);
305 cgi_redirect(cgi_referer("setup_ulist"));
306 return;
307 }
308 n = db_int(0, "SELECT count(*) FROM event"
309 " WHERE user=%Q AND objid NOT IN private",
310
+1676 -17
--- src/shell.c
+++ src/shell.c
@@ -981,10 +981,11 @@
981981
982982
/*
983983
** We need several support functions from the SQLite core.
984984
*/
985985
986
+/* #include "sqlite3.h" */
986987
987988
/*
988989
** We need several things from the ANSI and MSVCRT headers.
989990
*/
990991
@@ -1334,10 +1335,11 @@
13341335
**
13351336
** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
13361337
** is used. If SIZE is included it must be one of the integers 224, 256,
13371338
** 384, or 512, to determine SHA3 hash variant that is computed.
13381339
*/
1340
+/* #include "sqlite3ext.h" */
13391341
SQLITE_EXTENSION_INIT1
13401342
#include <assert.h>
13411343
#include <string.h>
13421344
#include <stdarg.h>
13431345
/* typedef sqlite3_uint64 u64; */
@@ -2097,10 +2099,11 @@
20972099
** If a non-NULL value is specified for the optional $dir parameter and
20982100
** $path is a relative path, then $path is interpreted relative to $dir.
20992101
** And the paths returned in the "name" column of the table are also
21002102
** relative to directory $dir.
21012103
*/
2104
+/* #include "sqlite3ext.h" */
21022105
SQLITE_EXTENSION_INIT1
21032106
#include <stdio.h>
21042107
#include <string.h>
21052108
#include <assert.h>
21062109
@@ -3054,10 +3057,11 @@
30543057
** This virtual table operates at the speed of human typing, and so there
30553058
** is no attempt to make it fast. Even a slow implementation will be much
30563059
** faster than any human can type.
30573060
**
30583061
*/
3062
+/* #include "sqlite3ext.h" */
30593063
SQLITE_EXTENSION_INIT1
30603064
#include <assert.h>
30613065
#include <string.h>
30623066
#include <ctype.h>
30633067
@@ -3570,10 +3574,11 @@
35703574
** database in a separate file.
35713575
**
35723576
** If the file being opened is not an appended database, then this shim is
35733577
** a pass-through into the default underlying VFS.
35743578
**/
3579
+/* #include "sqlite3ext.h" */
35753580
SQLITE_EXTENSION_INIT1
35763581
#include <string.h>
35773582
#include <assert.h>
35783583
35793584
/* The append mark at the end of the database is:
@@ -4226,10 +4231,11 @@
42264231
** * No support for encryption
42274232
** * No support for ZIP archives spanning multiple files
42284233
** * No support for zip64 extensions
42294234
** * Only the "inflate/deflate" (zlib) compression method is supported
42304235
*/
4236
+/* #include "sqlite3ext.h" */
42314237
SQLITE_EXTENSION_INIT1
42324238
#include <stdio.h>
42334239
#include <string.h>
42344240
#include <assert.h>
42354241
@@ -6396,10 +6402,11 @@
63966402
**
63976403
** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
63986404
** for working with sqlar archives and used by the shell tool's built-in
63996405
** sqlar support.
64006406
*/
6407
+/* #include "sqlite3ext.h" */
64016408
SQLITE_EXTENSION_INIT1
64026409
#include <zlib.h>
64036410
64046411
/*
64056412
** Implementation of the "sqlar_compress(X)" SQL function.
@@ -6518,10 +6525,11 @@
65186525
**
65196526
*************************************************************************
65206527
*/
65216528
65226529
6530
+/* #include "sqlite3.h" */
65236531
65246532
typedef struct sqlite3expert sqlite3expert;
65256533
65266534
/*
65276535
** Create a new sqlite3expert object.
@@ -6686,10 +6694,11 @@
66866694
** May you find forgiveness for yourself and forgive others.
66876695
** May you share freely, never taking more than you give.
66886696
**
66896697
*************************************************************************
66906698
*/
6699
+/* #include "sqlite3expert.h" */
66916700
#include <assert.h>
66926701
#include <string.h>
66936702
#include <stdio.h>
66946703
66956704
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -8628,10 +8637,867 @@
86288637
}
86298638
86308639
#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
86318640
86328641
/************************* End ../ext/expert/sqlite3expert.c ********************/
8642
+
8643
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
8644
+/************************* Begin ../ext/misc/dbdata.c ******************/
8645
+/*
8646
+** 2019-04-17
8647
+**
8648
+** The author disclaims copyright to this source code. In place of
8649
+** a legal notice, here is a blessing:
8650
+**
8651
+** May you do good and not evil.
8652
+** May you find forgiveness for yourself and forgive others.
8653
+** May you share freely, never taking more than you give.
8654
+**
8655
+******************************************************************************
8656
+**
8657
+** This file contains an implementation of two eponymous virtual tables,
8658
+** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
8659
+** "sqlite_dbpage" eponymous virtual table be available.
8660
+**
8661
+** SQLITE_DBDATA:
8662
+** sqlite_dbdata is used to extract data directly from a database b-tree
8663
+** page and its associated overflow pages, bypassing the b-tree layer.
8664
+** The table schema is equivalent to:
8665
+**
8666
+** CREATE TABLE sqlite_dbdata(
8667
+** pgno INTEGER,
8668
+** cell INTEGER,
8669
+** field INTEGER,
8670
+** value ANY,
8671
+** schema TEXT HIDDEN
8672
+** );
8673
+**
8674
+** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
8675
+** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
8676
+** "schema".
8677
+**
8678
+** Each page of the database is inspected. If it cannot be interpreted as
8679
+** a b-tree page, or if it is a b-tree page containing 0 entries, the
8680
+** sqlite_dbdata table contains no rows for that page. Otherwise, the
8681
+** table contains one row for each field in the record associated with
8682
+** each cell on the page. For intkey b-trees, the key value is stored in
8683
+** field -1.
8684
+**
8685
+** For example, for the database:
8686
+**
8687
+** CREATE TABLE t1(a, b); -- root page is page 2
8688
+** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
8689
+** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
8690
+**
8691
+** the sqlite_dbdata table contains, as well as from entries related to
8692
+** page 1, content equivalent to:
8693
+**
8694
+** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
8695
+** (2, 0, -1, 5 ),
8696
+** (2, 0, 0, 'v' ),
8697
+** (2, 0, 1, 'five'),
8698
+** (2, 1, -1, 10 ),
8699
+** (2, 1, 0, 'x' ),
8700
+** (2, 1, 1, 'ten' );
8701
+**
8702
+** If database corruption is encountered, this module does not report an
8703
+** error. Instead, it attempts to extract as much data as possible and
8704
+** ignores the corruption.
8705
+**
8706
+** SQLITE_DBPTR:
8707
+** The sqlite_dbptr table has the following schema:
8708
+**
8709
+** CREATE TABLE sqlite_dbptr(
8710
+** pgno INTEGER,
8711
+** child INTEGER,
8712
+** schema TEXT HIDDEN
8713
+** );
8714
+**
8715
+** It contains one entry for each b-tree pointer between a parent and
8716
+** child page in the database.
8717
+*/
8718
+#if !defined(SQLITEINT_H)
8719
+/* #include "sqlite3ext.h" */
8720
+
8721
+/* typedef unsigned char u8; */
8722
+
8723
+#endif
8724
+SQLITE_EXTENSION_INIT1
8725
+#include <string.h>
8726
+#include <assert.h>
8727
+
8728
+#define DBDATA_PADDING_BYTES 100
8729
+
8730
+typedef struct DbdataTable DbdataTable;
8731
+typedef struct DbdataCursor DbdataCursor;
8732
+
8733
+/* Cursor object */
8734
+struct DbdataCursor {
8735
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
8736
+ sqlite3_stmt *pStmt; /* For fetching database pages */
8737
+
8738
+ int iPgno; /* Current page number */
8739
+ u8 *aPage; /* Buffer containing page */
8740
+ int nPage; /* Size of aPage[] in bytes */
8741
+ int nCell; /* Number of cells on aPage[] */
8742
+ int iCell; /* Current cell number */
8743
+ int bOnePage; /* True to stop after one page */
8744
+ int szDb;
8745
+ sqlite3_int64 iRowid;
8746
+
8747
+ /* Only for the sqlite_dbdata table */
8748
+ u8 *pRec; /* Buffer containing current record */
8749
+ int nRec; /* Size of pRec[] in bytes */
8750
+ int nHdr; /* Size of header in bytes */
8751
+ int iField; /* Current field number */
8752
+ u8 *pHdrPtr;
8753
+ u8 *pPtr;
8754
+
8755
+ sqlite3_int64 iIntkey; /* Integer key value */
8756
+};
8757
+
8758
+/* Table object */
8759
+struct DbdataTable {
8760
+ sqlite3_vtab base; /* Base class. Must be first */
8761
+ sqlite3 *db; /* The database connection */
8762
+ sqlite3_stmt *pStmt; /* For fetching database pages */
8763
+ int bPtr; /* True for sqlite3_dbptr table */
8764
+};
8765
+
8766
+/* Column and schema definitions for sqlite_dbdata */
8767
+#define DBDATA_COLUMN_PGNO 0
8768
+#define DBDATA_COLUMN_CELL 1
8769
+#define DBDATA_COLUMN_FIELD 2
8770
+#define DBDATA_COLUMN_VALUE 3
8771
+#define DBDATA_COLUMN_SCHEMA 4
8772
+#define DBDATA_SCHEMA \
8773
+ "CREATE TABLE x(" \
8774
+ " pgno INTEGER," \
8775
+ " cell INTEGER," \
8776
+ " field INTEGER," \
8777
+ " value ANY," \
8778
+ " schema TEXT HIDDEN" \
8779
+ ")"
8780
+
8781
+/* Column and schema definitions for sqlite_dbptr */
8782
+#define DBPTR_COLUMN_PGNO 0
8783
+#define DBPTR_COLUMN_CHILD 1
8784
+#define DBPTR_COLUMN_SCHEMA 2
8785
+#define DBPTR_SCHEMA \
8786
+ "CREATE TABLE x(" \
8787
+ " pgno INTEGER," \
8788
+ " child INTEGER," \
8789
+ " schema TEXT HIDDEN" \
8790
+ ")"
8791
+
8792
+/*
8793
+** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual
8794
+** table.
8795
+*/
8796
+static int dbdataConnect(
8797
+ sqlite3 *db,
8798
+ void *pAux,
8799
+ int argc, const char *const*argv,
8800
+ sqlite3_vtab **ppVtab,
8801
+ char **pzErr
8802
+){
8803
+ DbdataTable *pTab = 0;
8804
+ int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
8805
+
8806
+ if( rc==SQLITE_OK ){
8807
+ pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
8808
+ if( pTab==0 ){
8809
+ rc = SQLITE_NOMEM;
8810
+ }else{
8811
+ memset(pTab, 0, sizeof(DbdataTable));
8812
+ pTab->db = db;
8813
+ pTab->bPtr = (pAux!=0);
8814
+ }
8815
+ }
8816
+
8817
+ *ppVtab = (sqlite3_vtab*)pTab;
8818
+ return rc;
8819
+}
8820
+
8821
+/*
8822
+** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
8823
+*/
8824
+static int dbdataDisconnect(sqlite3_vtab *pVtab){
8825
+ DbdataTable *pTab = (DbdataTable*)pVtab;
8826
+ if( pTab ){
8827
+ sqlite3_finalize(pTab->pStmt);
8828
+ sqlite3_free(pVtab);
8829
+ }
8830
+ return SQLITE_OK;
8831
+}
8832
+
8833
+/*
8834
+** This function interprets two types of constraints:
8835
+**
8836
+** schema=?
8837
+** pgno=?
8838
+**
8839
+** If neither are present, idxNum is set to 0. If schema=? is present,
8840
+** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
8841
+** in idxNum is set.
8842
+**
8843
+** If both parameters are present, schema is in position 0 and pgno in
8844
+** position 1.
8845
+*/
8846
+static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
8847
+ DbdataTable *pTab = (DbdataTable*)tab;
8848
+ int i;
8849
+ int iSchema = -1;
8850
+ int iPgno = -1;
8851
+ int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
8852
+
8853
+ for(i=0; i<pIdx->nConstraint; i++){
8854
+ struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
8855
+ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
8856
+ if( p->iColumn==colSchema ){
8857
+ if( p->usable==0 ) return SQLITE_CONSTRAINT;
8858
+ iSchema = i;
8859
+ }
8860
+ if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
8861
+ iPgno = i;
8862
+ }
8863
+ }
8864
+ }
8865
+
8866
+ if( iSchema>=0 ){
8867
+ pIdx->aConstraintUsage[iSchema].argvIndex = 1;
8868
+ pIdx->aConstraintUsage[iSchema].omit = 1;
8869
+ }
8870
+ if( iPgno>=0 ){
8871
+ pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
8872
+ pIdx->aConstraintUsage[iPgno].omit = 1;
8873
+ pIdx->estimatedCost = 100;
8874
+ pIdx->estimatedRows = 50;
8875
+
8876
+ if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
8877
+ int iCol = pIdx->aOrderBy[0].iColumn;
8878
+ if( pIdx->nOrderBy==1 ){
8879
+ pIdx->orderByConsumed = (iCol==0 || iCol==1);
8880
+ }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
8881
+ pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
8882
+ }
8883
+ }
8884
+
8885
+ }else{
8886
+ pIdx->estimatedCost = 100000000;
8887
+ pIdx->estimatedRows = 1000000000;
8888
+ }
8889
+ pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
8890
+ return SQLITE_OK;
8891
+}
8892
+
8893
+/*
8894
+** Open a new sqlite_dbdata or sqlite_dbptr cursor.
8895
+*/
8896
+static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
8897
+ DbdataCursor *pCsr;
8898
+
8899
+ pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
8900
+ if( pCsr==0 ){
8901
+ return SQLITE_NOMEM;
8902
+ }else{
8903
+ memset(pCsr, 0, sizeof(DbdataCursor));
8904
+ pCsr->base.pVtab = pVTab;
8905
+ }
8906
+
8907
+ *ppCursor = (sqlite3_vtab_cursor *)pCsr;
8908
+ return SQLITE_OK;
8909
+}
8910
+
8911
+/*
8912
+** Restore a cursor object to the state it was in when first allocated
8913
+** by dbdataOpen().
8914
+*/
8915
+static void dbdataResetCursor(DbdataCursor *pCsr){
8916
+ DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
8917
+ if( pTab->pStmt==0 ){
8918
+ pTab->pStmt = pCsr->pStmt;
8919
+ }else{
8920
+ sqlite3_finalize(pCsr->pStmt);
8921
+ }
8922
+ pCsr->pStmt = 0;
8923
+ pCsr->iPgno = 1;
8924
+ pCsr->iCell = 0;
8925
+ pCsr->iField = 0;
8926
+ pCsr->bOnePage = 0;
8927
+ sqlite3_free(pCsr->aPage);
8928
+ sqlite3_free(pCsr->pRec);
8929
+ pCsr->pRec = 0;
8930
+ pCsr->aPage = 0;
8931
+}
8932
+
8933
+/*
8934
+** Close an sqlite_dbdata or sqlite_dbptr cursor.
8935
+*/
8936
+static int dbdataClose(sqlite3_vtab_cursor *pCursor){
8937
+ DbdataCursor *pCsr = (DbdataCursor*)pCursor;
8938
+ dbdataResetCursor(pCsr);
8939
+ sqlite3_free(pCsr);
8940
+ return SQLITE_OK;
8941
+}
8942
+
8943
+/*
8944
+** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
8945
+*/
8946
+static unsigned int get_uint16(unsigned char *a){
8947
+ return (a[0]<<8)|a[1];
8948
+}
8949
+static unsigned int get_uint32(unsigned char *a){
8950
+ return ((unsigned int)a[0]<<24)
8951
+ | ((unsigned int)a[1]<<16)
8952
+ | ((unsigned int)a[2]<<8)
8953
+ | ((unsigned int)a[3]);
8954
+}
8955
+
8956
+/*
8957
+** Load page pgno from the database via the sqlite_dbpage virtual table.
8958
+** If successful, set (*ppPage) to point to a buffer containing the page
8959
+** data, (*pnPage) to the size of that buffer in bytes and return
8960
+** SQLITE_OK. In this case it is the responsibility of the caller to
8961
+** eventually free the buffer using sqlite3_free().
8962
+**
8963
+** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
8964
+** return an SQLite error code.
8965
+*/
8966
+static int dbdataLoadPage(
8967
+ DbdataCursor *pCsr, /* Cursor object */
8968
+ unsigned int pgno, /* Page number of page to load */
8969
+ u8 **ppPage, /* OUT: pointer to page buffer */
8970
+ int *pnPage /* OUT: Size of (*ppPage) in bytes */
8971
+){
8972
+ int rc2;
8973
+ int rc = SQLITE_OK;
8974
+ sqlite3_stmt *pStmt = pCsr->pStmt;
8975
+
8976
+ *ppPage = 0;
8977
+ *pnPage = 0;
8978
+ sqlite3_bind_int64(pStmt, 2, pgno);
8979
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
8980
+ int nCopy = sqlite3_column_bytes(pStmt, 0);
8981
+ if( nCopy>0 ){
8982
+ u8 *pPage;
8983
+ pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
8984
+ if( pPage==0 ){
8985
+ rc = SQLITE_NOMEM;
8986
+ }else{
8987
+ const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
8988
+ memcpy(pPage, pCopy, nCopy);
8989
+ memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
8990
+ }
8991
+ *ppPage = pPage;
8992
+ *pnPage = nCopy;
8993
+ }
8994
+ }
8995
+ rc2 = sqlite3_reset(pStmt);
8996
+ if( rc==SQLITE_OK ) rc = rc2;
8997
+
8998
+ return rc;
8999
+}
9000
+
9001
+/*
9002
+** Read a varint. Put the value in *pVal and return the number of bytes.
9003
+*/
9004
+static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
9005
+ sqlite3_int64 v = 0;
9006
+ int i;
9007
+ for(i=0; i<8; i++){
9008
+ v = (v<<7) + (z[i]&0x7f);
9009
+ if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
9010
+ }
9011
+ v = (v<<8) + (z[i]&0xff);
9012
+ *pVal = v;
9013
+ return 9;
9014
+}
9015
+
9016
+/*
9017
+** Return the number of bytes of space used by an SQLite value of type
9018
+** eType.
9019
+*/
9020
+static int dbdataValueBytes(int eType){
9021
+ switch( eType ){
9022
+ case 0: case 8: case 9:
9023
+ case 10: case 11:
9024
+ return 0;
9025
+ case 1:
9026
+ return 1;
9027
+ case 2:
9028
+ return 2;
9029
+ case 3:
9030
+ return 3;
9031
+ case 4:
9032
+ return 4;
9033
+ case 5:
9034
+ return 6;
9035
+ case 6:
9036
+ case 7:
9037
+ return 8;
9038
+ default:
9039
+ if( eType>0 ){
9040
+ return ((eType-12) / 2);
9041
+ }
9042
+ return 0;
9043
+ }
9044
+}
9045
+
9046
+/*
9047
+** Load a value of type eType from buffer pData and use it to set the
9048
+** result of context object pCtx.
9049
+*/
9050
+static void dbdataValue(
9051
+ sqlite3_context *pCtx,
9052
+ int eType,
9053
+ u8 *pData,
9054
+ int nData
9055
+){
9056
+ if( eType>=0 && dbdataValueBytes(eType)<=nData ){
9057
+ switch( eType ){
9058
+ case 0:
9059
+ case 10:
9060
+ case 11:
9061
+ sqlite3_result_null(pCtx);
9062
+ break;
9063
+
9064
+ case 8:
9065
+ sqlite3_result_int(pCtx, 0);
9066
+ break;
9067
+ case 9:
9068
+ sqlite3_result_int(pCtx, 1);
9069
+ break;
9070
+
9071
+ case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
9072
+ sqlite3_uint64 v = (signed char)pData[0];
9073
+ pData++;
9074
+ switch( eType ){
9075
+ case 7:
9076
+ case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
9077
+ case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
9078
+ case 4: v = (v<<8) + pData[0]; pData++;
9079
+ case 3: v = (v<<8) + pData[0]; pData++;
9080
+ case 2: v = (v<<8) + pData[0]; pData++;
9081
+ }
9082
+
9083
+ if( eType==7 ){
9084
+ double r;
9085
+ memcpy(&r, &v, sizeof(r));
9086
+ sqlite3_result_double(pCtx, r);
9087
+ }else{
9088
+ sqlite3_result_int64(pCtx, (sqlite3_int64)v);
9089
+ }
9090
+ break;
9091
+ }
9092
+
9093
+ default: {
9094
+ int n = ((eType-12) / 2);
9095
+ if( eType % 2 ){
9096
+ sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
9097
+ }else{
9098
+ sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
9099
+ }
9100
+ }
9101
+ }
9102
+ }
9103
+}
9104
+
9105
+/*
9106
+** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
9107
+*/
9108
+static int dbdataNext(sqlite3_vtab_cursor *pCursor){
9109
+ DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9110
+ DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
9111
+
9112
+ pCsr->iRowid++;
9113
+ while( 1 ){
9114
+ int rc;
9115
+ int iOff = (pCsr->iPgno==1 ? 100 : 0);
9116
+ int bNextPage = 0;
9117
+
9118
+ if( pCsr->aPage==0 ){
9119
+ while( 1 ){
9120
+ if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
9121
+ rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
9122
+ if( rc!=SQLITE_OK ) return rc;
9123
+ if( pCsr->aPage ) break;
9124
+ pCsr->iPgno++;
9125
+ }
9126
+ pCsr->iCell = pTab->bPtr ? -2 : 0;
9127
+ pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
9128
+ }
9129
+
9130
+ if( pTab->bPtr ){
9131
+ if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
9132
+ pCsr->iCell = pCsr->nCell;
9133
+ }
9134
+ pCsr->iCell++;
9135
+ if( pCsr->iCell>=pCsr->nCell ){
9136
+ sqlite3_free(pCsr->aPage);
9137
+ pCsr->aPage = 0;
9138
+ if( pCsr->bOnePage ) return SQLITE_OK;
9139
+ pCsr->iPgno++;
9140
+ }else{
9141
+ return SQLITE_OK;
9142
+ }
9143
+ }else{
9144
+ /* If there is no record loaded, load it now. */
9145
+ if( pCsr->pRec==0 ){
9146
+ int bHasRowid = 0;
9147
+ int nPointer = 0;
9148
+ sqlite3_int64 nPayload = 0;
9149
+ sqlite3_int64 nHdr = 0;
9150
+ int iHdr;
9151
+ int U, X;
9152
+ int nLocal;
9153
+
9154
+ switch( pCsr->aPage[iOff] ){
9155
+ case 0x02:
9156
+ nPointer = 4;
9157
+ break;
9158
+ case 0x0a:
9159
+ break;
9160
+ case 0x0d:
9161
+ bHasRowid = 1;
9162
+ break;
9163
+ default:
9164
+ /* This is not a b-tree page with records on it. Continue. */
9165
+ pCsr->iCell = pCsr->nCell;
9166
+ break;
9167
+ }
9168
+
9169
+ if( pCsr->iCell>=pCsr->nCell ){
9170
+ bNextPage = 1;
9171
+ }else{
9172
+
9173
+ iOff += 8 + nPointer + pCsr->iCell*2;
9174
+ if( iOff>pCsr->nPage ){
9175
+ bNextPage = 1;
9176
+ }else{
9177
+ iOff = get_uint16(&pCsr->aPage[iOff]);
9178
+ }
9179
+
9180
+ /* For an interior node cell, skip past the child-page number */
9181
+ iOff += nPointer;
9182
+
9183
+ /* Load the "byte of payload including overflow" field */
9184
+ if( bNextPage || iOff>pCsr->nPage ){
9185
+ bNextPage = 1;
9186
+ }else{
9187
+ iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
9188
+ }
9189
+
9190
+ /* If this is a leaf intkey cell, load the rowid */
9191
+ if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
9192
+ iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
9193
+ }
9194
+
9195
+ /* Figure out how much data to read from the local page */
9196
+ U = pCsr->nPage;
9197
+ if( bHasRowid ){
9198
+ X = U-35;
9199
+ }else{
9200
+ X = ((U-12)*64/255)-23;
9201
+ }
9202
+ if( nPayload<=X ){
9203
+ nLocal = nPayload;
9204
+ }else{
9205
+ int M, K;
9206
+ M = ((U-12)*32/255)-23;
9207
+ K = M+((nPayload-M)%(U-4));
9208
+ if( K<=X ){
9209
+ nLocal = K;
9210
+ }else{
9211
+ nLocal = M;
9212
+ }
9213
+ }
9214
+
9215
+ if( bNextPage || nLocal+iOff>pCsr->nPage ){
9216
+ bNextPage = 1;
9217
+ }else{
9218
+
9219
+ /* Allocate space for payload. And a bit more to catch small buffer
9220
+ ** overruns caused by attempting to read a varint or similar from
9221
+ ** near the end of a corrupt record. */
9222
+ pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
9223
+ if( pCsr->pRec==0 ) return SQLITE_NOMEM;
9224
+ memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
9225
+ pCsr->nRec = nPayload;
9226
+
9227
+ /* Load the nLocal bytes of payload */
9228
+ memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
9229
+ iOff += nLocal;
9230
+
9231
+ /* Load content from overflow pages */
9232
+ if( nPayload>nLocal ){
9233
+ sqlite3_int64 nRem = nPayload - nLocal;
9234
+ unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
9235
+ while( nRem>0 ){
9236
+ u8 *aOvfl = 0;
9237
+ int nOvfl = 0;
9238
+ int nCopy;
9239
+ rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
9240
+ assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
9241
+ if( rc!=SQLITE_OK ) return rc;
9242
+ if( aOvfl==0 ) break;
9243
+
9244
+ nCopy = U-4;
9245
+ if( nCopy>nRem ) nCopy = nRem;
9246
+ memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
9247
+ nRem -= nCopy;
9248
+
9249
+ pgnoOvfl = get_uint32(aOvfl);
9250
+ sqlite3_free(aOvfl);
9251
+ }
9252
+ }
9253
+
9254
+ iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
9255
+ pCsr->nHdr = nHdr;
9256
+ pCsr->pHdrPtr = &pCsr->pRec[iHdr];
9257
+ pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
9258
+ pCsr->iField = (bHasRowid ? -1 : 0);
9259
+ }
9260
+ }
9261
+ }else{
9262
+ pCsr->iField++;
9263
+ if( pCsr->iField>0 ){
9264
+ sqlite3_int64 iType;
9265
+ if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
9266
+ bNextPage = 1;
9267
+ }else{
9268
+ pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
9269
+ pCsr->pPtr += dbdataValueBytes(iType);
9270
+ }
9271
+ }
9272
+ }
9273
+
9274
+ if( bNextPage ){
9275
+ sqlite3_free(pCsr->aPage);
9276
+ sqlite3_free(pCsr->pRec);
9277
+ pCsr->aPage = 0;
9278
+ pCsr->pRec = 0;
9279
+ if( pCsr->bOnePage ) return SQLITE_OK;
9280
+ pCsr->iPgno++;
9281
+ }else{
9282
+ if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
9283
+ return SQLITE_OK;
9284
+ }
9285
+
9286
+ /* Advance to the next cell. The next iteration of the loop will load
9287
+ ** the record and so on. */
9288
+ sqlite3_free(pCsr->pRec);
9289
+ pCsr->pRec = 0;
9290
+ pCsr->iCell++;
9291
+ }
9292
+ }
9293
+ }
9294
+
9295
+ assert( !"can't get here" );
9296
+ return SQLITE_OK;
9297
+}
9298
+
9299
+/*
9300
+** Return true if the cursor is at EOF.
9301
+*/
9302
+static int dbdataEof(sqlite3_vtab_cursor *pCursor){
9303
+ DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9304
+ return pCsr->aPage==0;
9305
+}
9306
+
9307
+/*
9308
+** Determine the size in pages of database zSchema (where zSchema is
9309
+** "main", "temp" or the name of an attached database) and set
9310
+** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
9311
+** an SQLite error code.
9312
+*/
9313
+static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
9314
+ DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
9315
+ char *zSql = 0;
9316
+ int rc, rc2;
9317
+ sqlite3_stmt *pStmt = 0;
9318
+
9319
+ zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
9320
+ if( zSql==0 ) return SQLITE_NOMEM;
9321
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
9322
+ sqlite3_free(zSql);
9323
+ if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
9324
+ pCsr->szDb = sqlite3_column_int(pStmt, 0);
9325
+ }
9326
+ rc2 = sqlite3_finalize(pStmt);
9327
+ if( rc==SQLITE_OK ) rc = rc2;
9328
+ return rc;
9329
+}
9330
+
9331
+/*
9332
+** xFilter method for sqlite_dbdata and sqlite_dbptr.
9333
+*/
9334
+static int dbdataFilter(
9335
+ sqlite3_vtab_cursor *pCursor,
9336
+ int idxNum, const char *idxStr,
9337
+ int argc, sqlite3_value **argv
9338
+){
9339
+ DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9340
+ DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
9341
+ int rc = SQLITE_OK;
9342
+ const char *zSchema = "main";
9343
+
9344
+ dbdataResetCursor(pCsr);
9345
+ assert( pCsr->iPgno==1 );
9346
+ if( idxNum & 0x01 ){
9347
+ zSchema = (const char*)sqlite3_value_text(argv[0]);
9348
+ }
9349
+ if( idxNum & 0x02 ){
9350
+ pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
9351
+ pCsr->bOnePage = 1;
9352
+ }else{
9353
+ pCsr->nPage = dbdataDbsize(pCsr, zSchema);
9354
+ rc = dbdataDbsize(pCsr, zSchema);
9355
+ }
9356
+
9357
+ if( rc==SQLITE_OK ){
9358
+ if( pTab->pStmt ){
9359
+ pCsr->pStmt = pTab->pStmt;
9360
+ pTab->pStmt = 0;
9361
+ }else{
9362
+ rc = sqlite3_prepare_v2(pTab->db,
9363
+ "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
9364
+ &pCsr->pStmt, 0
9365
+ );
9366
+ }
9367
+ }
9368
+ if( rc==SQLITE_OK ){
9369
+ rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
9370
+ }else{
9371
+ pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
9372
+ }
9373
+ if( rc==SQLITE_OK ){
9374
+ rc = dbdataNext(pCursor);
9375
+ }
9376
+ return rc;
9377
+}
9378
+
9379
+/*
9380
+** Return a column for the sqlite_dbdata or sqlite_dbptr table.
9381
+*/
9382
+static int dbdataColumn(
9383
+ sqlite3_vtab_cursor *pCursor,
9384
+ sqlite3_context *ctx,
9385
+ int i
9386
+){
9387
+ DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9388
+ DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
9389
+ if( pTab->bPtr ){
9390
+ switch( i ){
9391
+ case DBPTR_COLUMN_PGNO:
9392
+ sqlite3_result_int64(ctx, pCsr->iPgno);
9393
+ break;
9394
+ case DBPTR_COLUMN_CHILD: {
9395
+ int iOff = pCsr->iPgno==1 ? 100 : 0;
9396
+ if( pCsr->iCell<0 ){
9397
+ iOff += 8;
9398
+ }else{
9399
+ iOff += 12 + pCsr->iCell*2;
9400
+ if( iOff>pCsr->nPage ) return SQLITE_OK;
9401
+ iOff = get_uint16(&pCsr->aPage[iOff]);
9402
+ }
9403
+ if( iOff<=pCsr->nPage ){
9404
+ sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
9405
+ }
9406
+ break;
9407
+ }
9408
+ }
9409
+ }else{
9410
+ switch( i ){
9411
+ case DBDATA_COLUMN_PGNO:
9412
+ sqlite3_result_int64(ctx, pCsr->iPgno);
9413
+ break;
9414
+ case DBDATA_COLUMN_CELL:
9415
+ sqlite3_result_int(ctx, pCsr->iCell);
9416
+ break;
9417
+ case DBDATA_COLUMN_FIELD:
9418
+ sqlite3_result_int(ctx, pCsr->iField);
9419
+ break;
9420
+ case DBDATA_COLUMN_VALUE: {
9421
+ if( pCsr->iField<0 ){
9422
+ sqlite3_result_int64(ctx, pCsr->iIntkey);
9423
+ }else{
9424
+ sqlite3_int64 iType;
9425
+ dbdataGetVarint(pCsr->pHdrPtr, &iType);
9426
+ dbdataValue(
9427
+ ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
9428
+ );
9429
+ }
9430
+ break;
9431
+ }
9432
+ }
9433
+ }
9434
+ return SQLITE_OK;
9435
+}
9436
+
9437
+/*
9438
+** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
9439
+*/
9440
+static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
9441
+ DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9442
+ *pRowid = pCsr->iRowid;
9443
+ return SQLITE_OK;
9444
+}
9445
+
9446
+
9447
+/*
9448
+** Invoke this routine to register the "sqlite_dbdata" virtual table module
9449
+*/
9450
+static int sqlite3DbdataRegister(sqlite3 *db){
9451
+ static sqlite3_module dbdata_module = {
9452
+ 0, /* iVersion */
9453
+ 0, /* xCreate */
9454
+ dbdataConnect, /* xConnect */
9455
+ dbdataBestIndex, /* xBestIndex */
9456
+ dbdataDisconnect, /* xDisconnect */
9457
+ 0, /* xDestroy */
9458
+ dbdataOpen, /* xOpen - open a cursor */
9459
+ dbdataClose, /* xClose - close a cursor */
9460
+ dbdataFilter, /* xFilter - configure scan constraints */
9461
+ dbdataNext, /* xNext - advance a cursor */
9462
+ dbdataEof, /* xEof - check for end of scan */
9463
+ dbdataColumn, /* xColumn - read data */
9464
+ dbdataRowid, /* xRowid - read data */
9465
+ 0, /* xUpdate */
9466
+ 0, /* xBegin */
9467
+ 0, /* xSync */
9468
+ 0, /* xCommit */
9469
+ 0, /* xRollback */
9470
+ 0, /* xFindMethod */
9471
+ 0, /* xRename */
9472
+ 0, /* xSavepoint */
9473
+ 0, /* xRelease */
9474
+ 0, /* xRollbackTo */
9475
+ 0 /* xShadowName */
9476
+ };
9477
+
9478
+ int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
9479
+ if( rc==SQLITE_OK ){
9480
+ rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
9481
+ }
9482
+ return rc;
9483
+}
9484
+
9485
+#ifdef _WIN32
9486
+
9487
+#endif
9488
+int sqlite3_dbdata_init(
9489
+ sqlite3 *db,
9490
+ char **pzErrMsg,
9491
+ const sqlite3_api_routines *pApi
9492
+){
9493
+ SQLITE_EXTENSION_INIT2(pApi);
9494
+ return sqlite3DbdataRegister(db);
9495
+}
9496
+
9497
+/************************* End ../ext/misc/dbdata.c ********************/
9498
+#endif
86339499
86349500
#if defined(SQLITE_ENABLE_SESSION)
86359501
/*
86369502
** State information for a single open session
86379503
*/
@@ -9358,10 +10224,12 @@
935810224
**
935910225
** This routine converts some CREATE TABLE statements for shadow tables
936010226
** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
936110227
*/
936210228
static void printSchemaLine(FILE *out, const char *z, const char *zTail){
10229
+ if( z==0 ) return;
10230
+ if( zTail==0 ) return;
936310231
if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
936410232
utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
936510233
}else{
936610234
utf8_printf(out, "%s%s", z, zTail);
936710235
}
@@ -11170,11 +12038,11 @@
1117012038
".dbinfo ?DB? Show status information about the database",
1117112039
".dump ?TABLE? ... Render all database content as SQL",
1117212040
" Options:",
1117312041
" --preserve-rowids Include ROWID values in the output",
1117412042
" --newlines Allow unescaped newline characters in output",
11175
- " TABLE is LIKE pattern for the tables to dump",
12043
+ " TABLE is a LIKE pattern for the tables to dump",
1117612044
".echo on|off Turn command echo on or off",
1117712045
".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
1117812046
" Other Modes:",
1117912047
#ifdef SQLITE_DEBUG
1118012048
" test Show raw EXPLAIN QUERY PLAN output",
@@ -11255,10 +12123,13 @@
1125512123
" --reset Reset the count for each input and interrupt",
1125612124
#endif
1125712125
".prompt MAIN CONTINUE Replace the standard prompts",
1125812126
".quit Exit this program",
1125912127
".read FILE Read input from FILE",
12128
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
12129
+ ".recover Recover as much data as possible from corrupt db.",
12130
+#endif
1126012131
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
1126112132
".save FILE Write in-memory database into FILE",
1126212133
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
1126312134
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
1126412135
" Options:",
@@ -11539,11 +12410,11 @@
1153912410
int pgsz = 0;
1154012411
int iOffset = 0;
1154112412
int j, k;
1154212413
int rc;
1154312414
FILE *in;
11544
- unsigned char x[16];
12415
+ unsigned int x[16];
1154512416
char zLine[1000];
1154612417
if( p->zDbFilename ){
1154712418
in = fopen(p->zDbFilename, "r");
1154812419
if( in==0 ){
1154912420
utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
@@ -11551,18 +12422,19 @@
1155112422
}
1155212423
nLine = 0;
1155312424
}else{
1155412425
in = p->in;
1155512426
nLine = p->lineno;
12427
+ if( in==0 ) in = stdin;
1155612428
}
1155712429
*pnData = 0;
1155812430
nLine++;
1155912431
if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
1156012432
rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
1156112433
if( rc!=2 ) goto readHexDb_error;
11562
- if( n<=0 ) goto readHexDb_error;
11563
- a = sqlite3_malloc( n );
12434
+ if( n<0 ) goto readHexDb_error;
12435
+ a = sqlite3_malloc( n ? n : 1 );
1156412436
if( a==0 ){
1156512437
utf8_printf(stderr, "Out of memory!\n");
1156612438
goto readHexDb_error;
1156712439
}
1156812440
memset(a, 0, n);
@@ -11577,18 +12449,18 @@
1157712449
continue;
1157812450
}
1157912451
if( strncmp(zLine, "| end ", 6)==0 ){
1158012452
break;
1158112453
}
11582
- rc = sscanf(zLine,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
11583
- " %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
12454
+ rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
1158412455
&j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
1158512456
&x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
1158612457
if( rc==17 ){
1158712458
k = iOffset+j;
1158812459
if( k+16<=n ){
11589
- memcpy(a+k, x, 16);
12460
+ int ii;
12461
+ for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
1159012462
}
1159112463
}
1159212464
}
1159312465
*pnData = n;
1159412466
if( in!=p->in ){
@@ -11597,11 +12469,11 @@
1159712469
p->lineno = nLine;
1159812470
}
1159912471
return a;
1160012472
1160112473
readHexDb_error:
11602
- if( in!=stdin ){
12474
+ if( in!=p->in ){
1160312475
fclose(in);
1160412476
}else{
1160512477
while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
1160612478
nLine++;
1160712479
if(strncmp(zLine, "| end ", 6)==0 ) break;
@@ -11611,10 +12483,131 @@
1161112483
sqlite3_free(a);
1161212484
utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
1161312485
return 0;
1161412486
}
1161512487
#endif /* SQLITE_ENABLE_DESERIALIZE */
12488
+
12489
+/*
12490
+** Scalar function "shell_int32". The first argument to this function
12491
+** must be a blob. The second a non-negative integer. This function
12492
+** reads and returns a 32-bit big-endian integer from byte
12493
+** offset (4*<arg2>) of the blob.
12494
+*/
12495
+static void shellInt32(
12496
+ sqlite3_context *context,
12497
+ int argc,
12498
+ sqlite3_value **argv
12499
+){
12500
+ const unsigned char *pBlob;
12501
+ int nBlob;
12502
+ int iInt;
12503
+
12504
+ UNUSED_PARAMETER(argc);
12505
+ nBlob = sqlite3_value_bytes(argv[0]);
12506
+ pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
12507
+ iInt = sqlite3_value_int(argv[1]);
12508
+
12509
+ if( iInt>=0 && (iInt+1)*4<=nBlob ){
12510
+ const unsigned char *a = &pBlob[iInt*4];
12511
+ sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
12512
+ + ((sqlite3_int64)a[1]<<16)
12513
+ + ((sqlite3_int64)a[2]<< 8)
12514
+ + ((sqlite3_int64)a[3]<< 0);
12515
+ sqlite3_result_int64(context, iVal);
12516
+ }
12517
+}
12518
+
12519
+/*
12520
+** Scalar function "shell_escape_crnl" used by the .recover command.
12521
+** The argument passed to this function is the output of built-in
12522
+** function quote(). If the first character of the input is "'",
12523
+** indicating that the value passed to quote() was a text value,
12524
+** then this function searches the input for "\n" and "\r" characters
12525
+** and adds a wrapper similar to the following:
12526
+**
12527
+** replace(replace(<input>, '\n', char(10), '\r', char(13));
12528
+**
12529
+** Or, if the first character of the input is not "'", then a copy
12530
+** of the input is returned.
12531
+*/
12532
+static void shellEscapeCrnl(
12533
+ sqlite3_context *context,
12534
+ int argc,
12535
+ sqlite3_value **argv
12536
+){
12537
+ const char *zText = (const char*)sqlite3_value_text(argv[0]);
12538
+ UNUSED_PARAMETER(argc);
12539
+ if( zText[0]=='\'' ){
12540
+ int nText = sqlite3_value_bytes(argv[0]);
12541
+ int i;
12542
+ char zBuf1[20];
12543
+ char zBuf2[20];
12544
+ const char *zNL = 0;
12545
+ const char *zCR = 0;
12546
+ int nCR = 0;
12547
+ int nNL = 0;
12548
+
12549
+ for(i=0; zText[i]; i++){
12550
+ if( zNL==0 && zText[i]=='\n' ){
12551
+ zNL = unused_string(zText, "\\n", "\\012", zBuf1);
12552
+ nNL = (int)strlen(zNL);
12553
+ }
12554
+ if( zCR==0 && zText[i]=='\r' ){
12555
+ zCR = unused_string(zText, "\\r", "\\015", zBuf2);
12556
+ nCR = (int)strlen(zCR);
12557
+ }
12558
+ }
12559
+
12560
+ if( zNL || zCR ){
12561
+ int iOut = 0;
12562
+ i64 nMax = (nNL > nCR) ? nNL : nCR;
12563
+ i64 nAlloc = nMax * nText + (nMax+64)*2;
12564
+ char *zOut = (char*)sqlite3_malloc64(nAlloc);
12565
+ if( zOut==0 ){
12566
+ sqlite3_result_error_nomem(context);
12567
+ return;
12568
+ }
12569
+
12570
+ if( zNL && zCR ){
12571
+ memcpy(&zOut[iOut], "replace(replace(", 16);
12572
+ iOut += 16;
12573
+ }else{
12574
+ memcpy(&zOut[iOut], "replace(", 8);
12575
+ iOut += 8;
12576
+ }
12577
+ for(i=0; zText[i]; i++){
12578
+ if( zText[i]=='\n' ){
12579
+ memcpy(&zOut[iOut], zNL, nNL);
12580
+ iOut += nNL;
12581
+ }else if( zText[i]=='\r' ){
12582
+ memcpy(&zOut[iOut], zCR, nCR);
12583
+ iOut += nCR;
12584
+ }else{
12585
+ zOut[iOut] = zText[i];
12586
+ iOut++;
12587
+ }
12588
+ }
12589
+
12590
+ if( zNL ){
12591
+ memcpy(&zOut[iOut], ",'", 2); iOut += 2;
12592
+ memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
12593
+ memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
12594
+ }
12595
+ if( zCR ){
12596
+ memcpy(&zOut[iOut], ",'", 2); iOut += 2;
12597
+ memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
12598
+ memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
12599
+ }
12600
+
12601
+ sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
12602
+ sqlite3_free(zOut);
12603
+ return;
12604
+ }
12605
+ }
12606
+
12607
+ sqlite3_result_value(context, argv[0]);
12608
+}
1161612609
1161712610
/* Flags for open_db().
1161812611
**
1161912612
** The default behavior of open_db() is to exit(1) if the database fails to
1162012613
** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
@@ -11680,10 +12673,13 @@
1168012673
sqlite3_enable_load_extension(p->db, 1);
1168112674
#endif
1168212675
sqlite3_fileio_init(p->db, 0, 0);
1168312676
sqlite3_shathree_init(p->db, 0, 0);
1168412677
sqlite3_completion_init(p->db, 0, 0);
12678
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
12679
+ sqlite3_dbdata_init(p->db, 0, 0);
12680
+#endif
1168512681
#ifdef SQLITE_HAVE_ZLIB
1168612682
sqlite3_zipfile_init(p->db, 0, 0);
1168712683
sqlite3_sqlar_init(p->db, 0, 0);
1168812684
#endif
1168912685
sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
@@ -11690,10 +12686,14 @@
1169012686
shellAddSchemaName, 0, 0);
1169112687
sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
1169212688
shellModuleSchema, 0, 0);
1169312689
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
1169412690
shellPutsFunc, 0, 0);
12691
+ sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
12692
+ shellEscapeCrnl, 0, 0);
12693
+ sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
12694
+ shellInt32, 0, 0);
1169512695
#ifndef SQLITE_NOHAVE_SYSTEM
1169612696
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
1169712697
editFunc, 0, 0);
1169812698
sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
1169912699
editFunc, 0, 0);
@@ -11713,11 +12713,10 @@
1171312713
if( p->openMode==SHELL_OPEN_DESERIALIZE ){
1171412714
aData = (unsigned char*)readFile(p->zDbFilename, &nData);
1171512715
}else{
1171612716
aData = readHexDb(p, &nData);
1171712717
if( aData==0 ){
11718
- utf8_printf(stderr, "Error in hexdb input\n");
1171912718
return;
1172012719
}
1172112720
}
1172212721
rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
1172312722
SQLITE_DESERIALIZE_RESIZEABLE |
@@ -12944,14 +13943,11 @@
1294413943
raw_printf(stderr, "Where sub-commands are:\n");
1294513944
raw_printf(stderr, " fkey-indexes\n");
1294613945
return SQLITE_ERROR;
1294713946
}
1294813947
12949
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
12950
-/*********************************************************************************
12951
-** The ".archive" or ".ar" command.
12952
-*/
13948
+#if !defined SQLITE_OMIT_VIRTUALTABLE
1295313949
static void shellPrepare(
1295413950
sqlite3 *db,
1295513951
int *pRc,
1295613952
const char *zSql,
1295713953
sqlite3_stmt **ppStmt
@@ -12966,11 +13962,18 @@
1296613962
*pRc = rc;
1296713963
}
1296813964
}
1296913965
}
1297013966
12971
-static void shellPreparePrintf(
13967
+/*
13968
+** Create a prepared statement using printf-style arguments for the SQL.
13969
+**
13970
+** This routine is could be marked "static". But it is not always used,
13971
+** depending on compile-time options. By omitting the "static", we avoid
13972
+** nuisance compiler warnings about "defined but not used".
13973
+*/
13974
+void shellPreparePrintf(
1297213975
sqlite3 *db,
1297313976
int *pRc,
1297413977
sqlite3_stmt **ppStmt,
1297513978
const char *zFmt,
1297613979
...
@@ -12989,11 +13992,17 @@
1298913992
sqlite3_free(z);
1299013993
}
1299113994
}
1299213995
}
1299313996
12994
-static void shellFinalize(
13997
+/* Finalize the prepared statement created using shellPreparePrintf().
13998
+**
13999
+** This routine is could be marked "static". But it is not always used,
14000
+** depending on compile-time options. By omitting the "static", we avoid
14001
+** nuisance compiler warnings about "defined but not used".
14002
+*/
14003
+void shellFinalize(
1299514004
int *pRc,
1299614005
sqlite3_stmt *pStmt
1299714006
){
1299814007
if( pStmt ){
1299914008
sqlite3 *db = sqlite3_db_handle(pStmt);
@@ -13005,11 +14014,17 @@
1300514014
*pRc = rc;
1300614015
}
1300714016
}
1300814017
}
1300914018
13010
-static void shellReset(
14019
+/* Reset the prepared statement created using shellPreparePrintf().
14020
+**
14021
+** This routine is could be marked "static". But it is not always used,
14022
+** depending on compile-time options. By omitting the "static", we avoid
14023
+** nuisance compiler warnings about "defined but not used".
14024
+*/
14025
+void shellReset(
1301114026
int *pRc,
1301214027
sqlite3_stmt *pStmt
1301314028
){
1301414029
int rc = sqlite3_reset(pStmt);
1301514030
if( *pRc==SQLITE_OK ){
@@ -13018,10 +14033,16 @@
1301814033
raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
1301914034
}
1302014035
*pRc = rc;
1302114036
}
1302214037
}
14038
+#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
14039
+
14040
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
14041
+/*********************************************************************************
14042
+** The ".archive" or ".ar" command.
14043
+*/
1302314044
/*
1302414045
** Structure representing a single ".ar" command.
1302514046
*/
1302614047
typedef struct ArCommand ArCommand;
1302714048
struct ArCommand {
@@ -13707,10 +14728,639 @@
1370714728
}
1370814729
/* End of the ".archive" or ".ar" command logic
1370914730
**********************************************************************************/
1371014731
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
1371114732
14733
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
14734
+/*
14735
+** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op.
14736
+** Otherwise, the SQL statement or statements in zSql are executed using
14737
+** database connection db and the error code written to *pRc before
14738
+** this function returns.
14739
+*/
14740
+static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
14741
+ int rc = *pRc;
14742
+ if( rc==SQLITE_OK ){
14743
+ char *zErr = 0;
14744
+ rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
14745
+ if( rc!=SQLITE_OK ){
14746
+ raw_printf(stderr, "SQL error: %s\n", zErr);
14747
+ }
14748
+ *pRc = rc;
14749
+ }
14750
+}
14751
+
14752
+/*
14753
+** Like shellExec(), except that zFmt is a printf() style format string.
14754
+*/
14755
+static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){
14756
+ char *z = 0;
14757
+ if( *pRc==SQLITE_OK ){
14758
+ va_list ap;
14759
+ va_start(ap, zFmt);
14760
+ z = sqlite3_vmprintf(zFmt, ap);
14761
+ va_end(ap);
14762
+ if( z==0 ){
14763
+ *pRc = SQLITE_NOMEM;
14764
+ }else{
14765
+ shellExec(db, pRc, z);
14766
+ }
14767
+ sqlite3_free(z);
14768
+ }
14769
+}
14770
+
14771
+/*
14772
+** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
14773
+** Otherwise, an attempt is made to allocate, zero and return a pointer
14774
+** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set
14775
+** to SQLITE_NOMEM and NULL returned.
14776
+*/
14777
+static void *shellMalloc(int *pRc, sqlite3_int64 nByte){
14778
+ void *pRet = 0;
14779
+ if( *pRc==SQLITE_OK ){
14780
+ pRet = sqlite3_malloc64(nByte);
14781
+ if( pRet==0 ){
14782
+ *pRc = SQLITE_NOMEM;
14783
+ }else{
14784
+ memset(pRet, 0, nByte);
14785
+ }
14786
+ }
14787
+ return pRet;
14788
+}
14789
+
14790
+/*
14791
+** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
14792
+** Otherwise, zFmt is treated as a printf() style string. The result of
14793
+** formatting it along with any trailing arguments is written into a
14794
+** buffer obtained from sqlite3_malloc(), and pointer to which is returned.
14795
+** It is the responsibility of the caller to eventually free this buffer
14796
+** using a call to sqlite3_free().
14797
+**
14798
+** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL
14799
+** pointer returned.
14800
+*/
14801
+static char *shellMPrintf(int *pRc, const char *zFmt, ...){
14802
+ char *z = 0;
14803
+ if( *pRc==SQLITE_OK ){
14804
+ va_list ap;
14805
+ va_start(ap, zFmt);
14806
+ z = sqlite3_vmprintf(zFmt, ap);
14807
+ va_end(ap);
14808
+ if( z==0 ){
14809
+ *pRc = SQLITE_NOMEM;
14810
+ }
14811
+ }
14812
+ return z;
14813
+}
14814
+
14815
+/*
14816
+** When running the ".recover" command, each output table, and the special
14817
+** orphaned row table if it is required, is represented by an instance
14818
+** of the following struct.
14819
+*/
14820
+typedef struct RecoverTable RecoverTable;
14821
+struct RecoverTable {
14822
+ char *zQuoted; /* Quoted version of table name */
14823
+ int nCol; /* Number of columns in table */
14824
+ char **azlCol; /* Array of column lists */
14825
+ int iPk; /* Index of IPK column */
14826
+};
14827
+
14828
+/*
14829
+** Free a RecoverTable object allocated by recoverFindTable() or
14830
+** recoverOrphanTable().
14831
+*/
14832
+static void recoverFreeTable(RecoverTable *pTab){
14833
+ if( pTab ){
14834
+ sqlite3_free(pTab->zQuoted);
14835
+ if( pTab->azlCol ){
14836
+ int i;
14837
+ for(i=0; i<=pTab->nCol; i++){
14838
+ sqlite3_free(pTab->azlCol[i]);
14839
+ }
14840
+ sqlite3_free(pTab->azlCol);
14841
+ }
14842
+ sqlite3_free(pTab);
14843
+ }
14844
+}
14845
+
14846
+/*
14847
+** This function is a no-op if (*pRc) is not SQLITE_OK when it is called.
14848
+** Otherwise, it allocates and returns a RecoverTable object based on the
14849
+** final four arguments passed to this function. It is the responsibility
14850
+** of the caller to eventually free the returned object using
14851
+** recoverFreeTable().
14852
+*/
14853
+static RecoverTable *recoverNewTable(
14854
+ int *pRc, /* IN/OUT: Error code */
14855
+ const char *zName, /* Name of table */
14856
+ const char *zSql, /* CREATE TABLE statement */
14857
+ int bIntkey,
14858
+ int nCol
14859
+){
14860
+ sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */
14861
+ int rc = *pRc;
14862
+ RecoverTable *pTab = 0;
14863
+
14864
+ pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable));
14865
+ if( rc==SQLITE_OK ){
14866
+ int nSqlCol = 0;
14867
+ int bSqlIntkey = 0;
14868
+ sqlite3_stmt *pStmt = 0;
14869
+
14870
+ rc = sqlite3_open("", &dbtmp);
14871
+ if( rc==SQLITE_OK ){
14872
+ rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
14873
+ }
14874
+ if( rc==SQLITE_OK ){
14875
+ rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0);
14876
+ if( rc==SQLITE_ERROR ){
14877
+ rc = SQLITE_OK;
14878
+ goto finished;
14879
+ }
14880
+ }
14881
+ shellPreparePrintf(dbtmp, &rc, &pStmt,
14882
+ "SELECT count(*) FROM pragma_table_info(%Q)", zName
14883
+ );
14884
+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
14885
+ nSqlCol = sqlite3_column_int(pStmt, 0);
14886
+ }
14887
+ shellFinalize(&rc, pStmt);
14888
+
14889
+ if( rc!=SQLITE_OK || nSqlCol<nCol ){
14890
+ goto finished;
14891
+ }
14892
+
14893
+ shellPreparePrintf(dbtmp, &rc, &pStmt,
14894
+ "SELECT ("
14895
+ " SELECT substr(data,1,1)==X'0D' FROM sqlite_dbpage WHERE pgno=rootpage"
14896
+ ") FROM sqlite_master WHERE name = %Q", zName
14897
+ );
14898
+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
14899
+ bSqlIntkey = sqlite3_column_int(pStmt, 0);
14900
+ }
14901
+ shellFinalize(&rc, pStmt);
14902
+
14903
+ if( bIntkey==bSqlIntkey ){
14904
+ int i;
14905
+ const char *zPk = "_rowid_";
14906
+ sqlite3_stmt *pPkFinder = 0;
14907
+
14908
+ /* If this is an intkey table and there is an INTEGER PRIMARY KEY,
14909
+ ** set zPk to the name of the PK column, and pTab->iPk to the index
14910
+ ** of the column, where columns are 0-numbered from left to right.
14911
+ ** Or, if this is a WITHOUT ROWID table or if there is no IPK column,
14912
+ ** leave zPk as "_rowid_" and pTab->iPk at -2. */
14913
+ pTab->iPk = -2;
14914
+ if( bIntkey ){
14915
+ shellPreparePrintf(dbtmp, &rc, &pPkFinder,
14916
+ "SELECT cid, name FROM pragma_table_info(%Q) "
14917
+ " WHERE pk=1 AND type='integer' COLLATE nocase"
14918
+ " AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)"
14919
+ , zName, zName
14920
+ );
14921
+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){
14922
+ pTab->iPk = sqlite3_column_int(pPkFinder, 0);
14923
+ zPk = (const char*)sqlite3_column_text(pPkFinder, 1);
14924
+ }
14925
+ }
14926
+
14927
+ pTab->zQuoted = shellMPrintf(&rc, "%Q", zName);
14928
+ pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
14929
+ pTab->nCol = nSqlCol;
14930
+
14931
+ if( bIntkey ){
14932
+ pTab->azlCol[0] = shellMPrintf(&rc, "%Q", zPk);
14933
+ }else{
14934
+ pTab->azlCol[0] = shellMPrintf(&rc, "");
14935
+ }
14936
+ i = 1;
14937
+ shellPreparePrintf(dbtmp, &rc, &pStmt,
14938
+ "SELECT %Q || group_concat(name, ', ') "
14939
+ " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
14940
+ "FROM pragma_table_info(%Q)",
14941
+ bIntkey ? ", " : "", pTab->iPk,
14942
+ bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ",
14943
+ zName
14944
+ );
14945
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
14946
+ const char *zText = (const char*)sqlite3_column_text(pStmt, 0);
14947
+ pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText);
14948
+ i++;
14949
+ }
14950
+ shellFinalize(&rc, pStmt);
14951
+
14952
+ shellFinalize(&rc, pPkFinder);
14953
+ }
14954
+ }
14955
+
14956
+ finished:
14957
+ sqlite3_close(dbtmp);
14958
+ *pRc = rc;
14959
+ if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
14960
+ recoverFreeTable(pTab);
14961
+ pTab = 0;
14962
+ }
14963
+ return pTab;
14964
+}
14965
+
14966
+/*
14967
+** This function is called to search the schema recovered from the
14968
+** sqlite_master table of the (possibly) corrupt database as part
14969
+** of a ".recover" command. Specifically, for a table with root page
14970
+** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the
14971
+** table must be a WITHOUT ROWID table, or if non-zero, not one of
14972
+** those.
14973
+**
14974
+** If a table is found, a (RecoverTable*) object is returned. Or, if
14975
+** no such table is found, but bIntkey is false and iRoot is the
14976
+** root page of an index in the recovered schema, then (*pbNoop) is
14977
+** set to true and NULL returned. Or, if there is no such table or
14978
+** index, NULL is returned and (*pbNoop) set to 0, indicating that
14979
+** the caller should write data to the orphans table.
14980
+*/
14981
+static RecoverTable *recoverFindTable(
14982
+ ShellState *pState, /* Shell state object */
14983
+ int *pRc, /* IN/OUT: Error code */
14984
+ int iRoot, /* Root page of table */
14985
+ int bIntkey, /* True for an intkey table */
14986
+ int nCol, /* Number of columns in table */
14987
+ int *pbNoop /* OUT: True if iRoot is root of index */
14988
+){
14989
+ sqlite3_stmt *pStmt = 0;
14990
+ RecoverTable *pRet = 0;
14991
+ int bNoop = 0;
14992
+ const char *zSql = 0;
14993
+ const char *zName = 0;
14994
+
14995
+ /* Search the recovered schema for an object with root page iRoot. */
14996
+ shellPreparePrintf(pState->db, pRc, &pStmt,
14997
+ "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot
14998
+ );
14999
+ while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
15000
+ const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
15001
+ if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){
15002
+ bNoop = 1;
15003
+ break;
15004
+ }
15005
+ if( sqlite3_stricmp(zType, "table")==0 ){
15006
+ zName = (const char*)sqlite3_column_text(pStmt, 1);
15007
+ zSql = (const char*)sqlite3_column_text(pStmt, 2);
15008
+ pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol);
15009
+ break;
15010
+ }
15011
+ }
15012
+
15013
+ shellFinalize(pRc, pStmt);
15014
+ *pbNoop = bNoop;
15015
+ return pRet;
15016
+}
15017
+
15018
+/*
15019
+** Return a RecoverTable object representing the orphans table.
15020
+*/
15021
+static RecoverTable *recoverOrphanTable(
15022
+ ShellState *pState, /* Shell state object */
15023
+ int *pRc, /* IN/OUT: Error code */
15024
+ const char *zLostAndFound, /* Base name for orphans table */
15025
+ int nCol /* Number of user data columns */
15026
+){
15027
+ RecoverTable *pTab = 0;
15028
+ if( nCol>=0 && *pRc==SQLITE_OK ){
15029
+ int i;
15030
+
15031
+ /* This block determines the name of the orphan table. The prefered
15032
+ ** name is zLostAndFound. But if that clashes with another name
15033
+ ** in the recovered schema, try zLostAndFound_0, zLostAndFound_1
15034
+ ** and so on until a non-clashing name is found. */
15035
+ int iTab = 0;
15036
+ char *zTab = shellMPrintf(pRc, "%s", zLostAndFound);
15037
+ sqlite3_stmt *pTest = 0;
15038
+ shellPrepare(pState->db, pRc,
15039
+ "SELECT 1 FROM recovery.schema WHERE name=?", &pTest
15040
+ );
15041
+ if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
15042
+ while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){
15043
+ shellReset(pRc, pTest);
15044
+ sqlite3_free(zTab);
15045
+ zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++);
15046
+ sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
15047
+ }
15048
+ shellFinalize(pRc, pTest);
15049
+
15050
+ pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
15051
+ if( pTab ){
15052
+ pTab->zQuoted = shellMPrintf(pRc, "%Q", zTab);
15053
+ pTab->nCol = nCol;
15054
+ pTab->iPk = -2;
15055
+ if( nCol>0 ){
15056
+ pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1));
15057
+ if( pTab->azlCol ){
15058
+ pTab->azlCol[nCol] = shellMPrintf(pRc, "");
15059
+ for(i=nCol-1; i>=0; i--){
15060
+ pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]);
15061
+ }
15062
+ }
15063
+ }
15064
+
15065
+ if( *pRc!=SQLITE_OK ){
15066
+ recoverFreeTable(pTab);
15067
+ pTab = 0;
15068
+ }else{
15069
+ raw_printf(pState->out,
15070
+ "CREATE TABLE %s(rootpgno INTEGER, "
15071
+ "pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted
15072
+ );
15073
+ for(i=0; i<nCol; i++){
15074
+ raw_printf(pState->out, ", c%d", i);
15075
+ }
15076
+ raw_printf(pState->out, ");\n");
15077
+ }
15078
+ }
15079
+ sqlite3_free(zTab);
15080
+ }
15081
+ return pTab;
15082
+}
15083
+
15084
+/*
15085
+** This function is called to recover data from the database. A script
15086
+** to construct a new database containing all recovered data is output
15087
+** on stream pState->out.
15088
+*/
15089
+static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
15090
+ int rc = SQLITE_OK;
15091
+ sqlite3_stmt *pLoop = 0; /* Loop through all root pages */
15092
+ sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */
15093
+ sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */
15094
+ const char *zRecoveryDb = ""; /* Name of "recovery" database */
15095
+ const char *zLostAndFound = "lost_and_found";
15096
+ int i;
15097
+ int nOrphan = -1;
15098
+ RecoverTable *pOrphan = 0;
15099
+
15100
+ int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
15101
+ for(i=1; i<nArg; i++){
15102
+ char *z = azArg[i];
15103
+ int n;
15104
+ if( z[0]=='-' && z[1]=='-' ) z++;
15105
+ n = strlen(z);
15106
+ if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
15107
+ bFreelist = 0;
15108
+ }else
15109
+ if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
15110
+ i++;
15111
+ zRecoveryDb = azArg[i];
15112
+ }else
15113
+ if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
15114
+ i++;
15115
+ zLostAndFound = azArg[i];
15116
+ }
15117
+ else{
15118
+ raw_printf(stderr, "unexpected option: %s\n", azArg[i]);
15119
+ raw_printf(stderr, "options are:\n");
15120
+ raw_printf(stderr, " --freelist-corrupt\n");
15121
+ raw_printf(stderr, " --recovery-db DATABASE\n");
15122
+ raw_printf(stderr, " --lost-and-found TABLE-NAME\n");
15123
+ return 1;
15124
+ }
15125
+ }
15126
+
15127
+ shellExecPrintf(pState->db, &rc,
15128
+ /* Attach an in-memory database named 'recovery'. Create an indexed
15129
+ ** cache of the sqlite_dbptr virtual table. */
15130
+ "ATTACH %Q AS recovery;"
15131
+ "DROP TABLE IF EXISTS recovery.dbptr;"
15132
+ "DROP TABLE IF EXISTS recovery.freelist;"
15133
+ "DROP TABLE IF EXISTS recovery.map;"
15134
+ "DROP TABLE IF EXISTS recovery.schema;"
15135
+ "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
15136
+ );
15137
+
15138
+ if( bFreelist ){
15139
+ shellExec(pState->db, &rc,
15140
+ "WITH trunk(pgno) AS ("
15141
+ " SELECT shell_int32("
15142
+ " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
15143
+ " WHERE x>0"
15144
+ " UNION"
15145
+ " SELECT shell_int32("
15146
+ " (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
15147
+ " FROM trunk WHERE x>0"
15148
+ "),"
15149
+ "freelist(data, n, freepgno) AS ("
15150
+ " SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
15151
+ " FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
15152
+ " UNION ALL"
15153
+ " SELECT data, n-1, shell_int32(data, 2+n) "
15154
+ " FROM freelist WHERE n>=0"
15155
+ ")"
15156
+ "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
15157
+ );
15158
+ }
15159
+
15160
+ shellExec(pState->db, &rc,
15161
+ "CREATE TABLE recovery.dbptr("
15162
+ " pgno, child, PRIMARY KEY(child, pgno)"
15163
+ ") WITHOUT ROWID;"
15164
+ "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
15165
+ " SELECT * FROM sqlite_dbptr"
15166
+ " WHERE pgno NOT IN freelist AND child NOT IN freelist;"
15167
+
15168
+ /* Delete any pointer to page 1. This ensures that page 1 is considered
15169
+ ** a root page, regardless of how corrupt the db is. */
15170
+ "DELETE FROM recovery.dbptr WHERE child = 1;"
15171
+
15172
+ /* Delete all pointers to any pages that have more than one pointer
15173
+ ** to them. Such pages will be treated as root pages when recovering
15174
+ ** data. */
15175
+ "DELETE FROM recovery.dbptr WHERE child IN ("
15176
+ " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
15177
+ ");"
15178
+
15179
+ /* Create the "map" table that will (eventually) contain instructions
15180
+ ** for dealing with each page in the db that contains one or more
15181
+ ** records. */
15182
+ "CREATE TABLE recovery.map("
15183
+ "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
15184
+ ");"
15185
+
15186
+ /* Populate table [map]. If there are circular loops of pages in the
15187
+ ** database, the following adds all pages in such a loop to the map
15188
+ ** as individual root pages. This could be handled better. */
15189
+ "WITH pages(i, maxlen) AS ("
15190
+ " SELECT page_count, ("
15191
+ " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
15192
+ " ) FROM pragma_page_count WHERE page_count>0"
15193
+ " UNION ALL"
15194
+ " SELECT i-1, ("
15195
+ " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
15196
+ " ) FROM pages WHERE i>=2"
15197
+ ")"
15198
+ "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
15199
+ " SELECT i, maxlen, NULL, ("
15200
+ " WITH p(orig, pgno, parent) AS ("
15201
+ " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
15202
+ " UNION "
15203
+ " SELECT i, p.parent, "
15204
+ " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
15205
+ " )"
15206
+ " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
15207
+ ") "
15208
+ "FROM pages WHERE maxlen > 0 AND i NOT IN freelist;"
15209
+ "UPDATE recovery.map AS o SET intkey = ("
15210
+ " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
15211
+ ");"
15212
+
15213
+ /* Extract data from page 1 and any linked pages into table
15214
+ ** recovery.schema. With the same schema as an sqlite_master table. */
15215
+ "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
15216
+ "INSERT INTO recovery.schema SELECT "
15217
+ " max(CASE WHEN field=0 THEN value ELSE NULL END),"
15218
+ " max(CASE WHEN field=1 THEN value ELSE NULL END),"
15219
+ " max(CASE WHEN field=2 THEN value ELSE NULL END),"
15220
+ " max(CASE WHEN field=3 THEN value ELSE NULL END),"
15221
+ " max(CASE WHEN field=4 THEN value ELSE NULL END)"
15222
+ "FROM sqlite_dbdata WHERE pgno IN ("
15223
+ " SELECT pgno FROM recovery.map WHERE root=1"
15224
+ ")"
15225
+ "GROUP BY pgno, cell;"
15226
+ "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
15227
+ );
15228
+
15229
+ /* Open a transaction, then print out all non-virtual, non-"sqlite_%"
15230
+ ** CREATE TABLE statements that extracted from the existing schema. */
15231
+ if( rc==SQLITE_OK ){
15232
+ sqlite3_stmt *pStmt = 0;
15233
+ raw_printf(pState->out, "BEGIN;\n");
15234
+ raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
15235
+ shellPrepare(pState->db, &rc,
15236
+ "SELECT sql FROM recovery.schema "
15237
+ "WHERE type='table' AND sql LIKE 'create table%'", &pStmt
15238
+ );
15239
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
15240
+ const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
15241
+ raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n",
15242
+ &zCreateTable[12]
15243
+ );
15244
+ }
15245
+ shellFinalize(&rc, pStmt);
15246
+ }
15247
+
15248
+ /* Figure out if an orphan table will be required. And if so, how many
15249
+ ** user columns it should contain */
15250
+ shellPrepare(pState->db, &rc,
15251
+ "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
15252
+ , &pLoop
15253
+ );
15254
+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
15255
+ nOrphan = sqlite3_column_int(pLoop, 0);
15256
+ }
15257
+ shellFinalize(&rc, pLoop);
15258
+ pLoop = 0;
15259
+
15260
+ shellPrepare(pState->db, &rc,
15261
+ "SELECT pgno FROM recovery.map WHERE root=?", &pPages
15262
+ );
15263
+ shellPrepare(pState->db, &rc,
15264
+ "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
15265
+ "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
15266
+ "GROUP BY cell", &pCells
15267
+ );
15268
+
15269
+ /* Loop through each root page. */
15270
+ shellPrepare(pState->db, &rc,
15271
+ "SELECT root, intkey, max(maxlen) FROM recovery.map"
15272
+ " WHERE root>1 GROUP BY root, intkey ORDER BY root=("
15273
+ " SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
15274
+ ")", &pLoop
15275
+ );
15276
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
15277
+ int iRoot = sqlite3_column_int(pLoop, 0);
15278
+ int bIntkey = sqlite3_column_int(pLoop, 1);
15279
+ int nCol = sqlite3_column_int(pLoop, 2);
15280
+ int bNoop = 0;
15281
+ RecoverTable *pTab;
15282
+
15283
+ pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
15284
+ if( bNoop || rc ) continue;
15285
+ if( pTab==0 ){
15286
+ if( pOrphan==0 ){
15287
+ pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
15288
+ }
15289
+ pTab = pOrphan;
15290
+ if( pTab==0 ) break;
15291
+ }
15292
+
15293
+ if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){
15294
+ raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
15295
+ }
15296
+ sqlite3_bind_int(pPages, 1, iRoot);
15297
+ sqlite3_bind_int(pCells, 2, pTab->iPk);
15298
+
15299
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
15300
+ int iPgno = sqlite3_column_int(pPages, 0);
15301
+ sqlite3_bind_int(pCells, 1, iPgno);
15302
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
15303
+ int nField = sqlite3_column_int(pCells, 0);
15304
+ const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
15305
+
15306
+ nField = nField+1;
15307
+ if( pTab==pOrphan ){
15308
+ raw_printf(pState->out,
15309
+ "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
15310
+ pTab->zQuoted, iRoot, iPgno, nField,
15311
+ bIntkey ? "" : "NULL, ", zVal, pTab->azlCol[nField]
15312
+ );
15313
+ }else{
15314
+ raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
15315
+ pTab->zQuoted, pTab->azlCol[nField], zVal
15316
+ );
15317
+ }
15318
+ }
15319
+ shellReset(&rc, pCells);
15320
+ }
15321
+ shellReset(&rc, pPages);
15322
+ if( pTab!=pOrphan ) recoverFreeTable(pTab);
15323
+ }
15324
+ shellFinalize(&rc, pLoop);
15325
+ shellFinalize(&rc, pPages);
15326
+ shellFinalize(&rc, pCells);
15327
+ recoverFreeTable(pOrphan);
15328
+
15329
+ /* The rest of the schema */
15330
+ if( rc==SQLITE_OK ){
15331
+ sqlite3_stmt *pStmt = 0;
15332
+ shellPrepare(pState->db, &rc,
15333
+ "SELECT sql, name FROM recovery.schema "
15334
+ "WHERE sql NOT LIKE 'create table%'", &pStmt
15335
+ );
15336
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
15337
+ const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
15338
+ if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
15339
+ const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
15340
+ char *zPrint = shellMPrintf(&rc,
15341
+ "INSERT INTO sqlite_master VALUES('table', %Q, %Q, 0, %Q)",
15342
+ zName, zName, zSql
15343
+ );
15344
+ raw_printf(pState->out, "%s;\n", zPrint);
15345
+ sqlite3_free(zPrint);
15346
+ }else{
15347
+ raw_printf(pState->out, "%s;\n", zSql);
15348
+ }
15349
+ }
15350
+ shellFinalize(&rc, pStmt);
15351
+ }
15352
+
15353
+ if( rc==SQLITE_OK ){
15354
+ raw_printf(pState->out, "PRAGMA writable_schema = off;\n");
15355
+ raw_printf(pState->out, "COMMIT;\n");
15356
+ }
15357
+ sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
15358
+ return rc;
15359
+}
15360
+#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
15361
+
1371215362
1371315363
/*
1371415364
** If an input line begins with "." then invoke this routine to
1371515365
** process that line.
1371615366
**
@@ -13994,10 +15644,17 @@
1399415644
1399515645
if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
1399615646
rc = shell_dbinfo_command(p, nArg, azArg);
1399715647
}else
1399815648
15649
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
15650
+ if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
15651
+ open_db(p, 0);
15652
+ rc = recoverDatabaseCmd(p, nArg, azArg);
15653
+ }else
15654
+#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
15655
+
1399915656
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1400015657
const char *zLike = 0;
1400115658
int i;
1400215659
int savedShowHeader = p->showHeader;
1400315660
int savedShellFlags = p->shellFlgs;
@@ -14031,11 +15688,13 @@
1403115688
goto meta_command_exit;
1403215689
}else{
1403315690
zLike = azArg[i];
1403415691
}
1403515692
}
15693
+
1403615694
open_db(p, 0);
15695
+
1403715696
/* When playing back a "dump", the content might appear in an order
1403815697
** which causes immediate foreign key constraints to be violated.
1403915698
** So disable foreign-key constraint enforcement to prevent problems. */
1404015699
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
1404115700
raw_printf(p->out, "BEGIN TRANSACTION;\n");
@@ -14079,11 +15738,11 @@
1407915738
raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
1408015739
p->writableSchema = 0;
1408115740
}
1408215741
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1408315742
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
14084
- raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
15743
+ raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
1408515744
p->showHeader = savedShowHeader;
1408615745
p->shellFlgs = savedShellFlags;
1408715746
}else
1408815747
1408915748
if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
1409015749
--- src/shell.c
+++ src/shell.c
@@ -981,10 +981,11 @@
981
982 /*
983 ** We need several support functions from the SQLite core.
984 */
985
 
986
987 /*
988 ** We need several things from the ANSI and MSVCRT headers.
989 */
990
@@ -1334,10 +1335,11 @@
1334 **
1335 ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
1336 ** is used. If SIZE is included it must be one of the integers 224, 256,
1337 ** 384, or 512, to determine SHA3 hash variant that is computed.
1338 */
 
1339 SQLITE_EXTENSION_INIT1
1340 #include <assert.h>
1341 #include <string.h>
1342 #include <stdarg.h>
1343 /* typedef sqlite3_uint64 u64; */
@@ -2097,10 +2099,11 @@
2097 ** If a non-NULL value is specified for the optional $dir parameter and
2098 ** $path is a relative path, then $path is interpreted relative to $dir.
2099 ** And the paths returned in the "name" column of the table are also
2100 ** relative to directory $dir.
2101 */
 
2102 SQLITE_EXTENSION_INIT1
2103 #include <stdio.h>
2104 #include <string.h>
2105 #include <assert.h>
2106
@@ -3054,10 +3057,11 @@
3054 ** This virtual table operates at the speed of human typing, and so there
3055 ** is no attempt to make it fast. Even a slow implementation will be much
3056 ** faster than any human can type.
3057 **
3058 */
 
3059 SQLITE_EXTENSION_INIT1
3060 #include <assert.h>
3061 #include <string.h>
3062 #include <ctype.h>
3063
@@ -3570,10 +3574,11 @@
3570 ** database in a separate file.
3571 **
3572 ** If the file being opened is not an appended database, then this shim is
3573 ** a pass-through into the default underlying VFS.
3574 **/
 
3575 SQLITE_EXTENSION_INIT1
3576 #include <string.h>
3577 #include <assert.h>
3578
3579 /* The append mark at the end of the database is:
@@ -4226,10 +4231,11 @@
4226 ** * No support for encryption
4227 ** * No support for ZIP archives spanning multiple files
4228 ** * No support for zip64 extensions
4229 ** * Only the "inflate/deflate" (zlib) compression method is supported
4230 */
 
4231 SQLITE_EXTENSION_INIT1
4232 #include <stdio.h>
4233 #include <string.h>
4234 #include <assert.h>
4235
@@ -6396,10 +6402,11 @@
6396 **
6397 ** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
6398 ** for working with sqlar archives and used by the shell tool's built-in
6399 ** sqlar support.
6400 */
 
6401 SQLITE_EXTENSION_INIT1
6402 #include <zlib.h>
6403
6404 /*
6405 ** Implementation of the "sqlar_compress(X)" SQL function.
@@ -6518,10 +6525,11 @@
6518 **
6519 *************************************************************************
6520 */
6521
6522
 
6523
6524 typedef struct sqlite3expert sqlite3expert;
6525
6526 /*
6527 ** Create a new sqlite3expert object.
@@ -6686,10 +6694,11 @@
6686 ** May you find forgiveness for yourself and forgive others.
6687 ** May you share freely, never taking more than you give.
6688 **
6689 *************************************************************************
6690 */
 
6691 #include <assert.h>
6692 #include <string.h>
6693 #include <stdio.h>
6694
6695 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -8628,10 +8637,867 @@
8628 }
8629
8630 #endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
8631
8632 /************************* End ../ext/expert/sqlite3expert.c ********************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8633
8634 #if defined(SQLITE_ENABLE_SESSION)
8635 /*
8636 ** State information for a single open session
8637 */
@@ -9358,10 +10224,12 @@
9358 **
9359 ** This routine converts some CREATE TABLE statements for shadow tables
9360 ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
9361 */
9362 static void printSchemaLine(FILE *out, const char *z, const char *zTail){
 
 
9363 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
9364 utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
9365 }else{
9366 utf8_printf(out, "%s%s", z, zTail);
9367 }
@@ -11170,11 +12038,11 @@
11170 ".dbinfo ?DB? Show status information about the database",
11171 ".dump ?TABLE? ... Render all database content as SQL",
11172 " Options:",
11173 " --preserve-rowids Include ROWID values in the output",
11174 " --newlines Allow unescaped newline characters in output",
11175 " TABLE is LIKE pattern for the tables to dump",
11176 ".echo on|off Turn command echo on or off",
11177 ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
11178 " Other Modes:",
11179 #ifdef SQLITE_DEBUG
11180 " test Show raw EXPLAIN QUERY PLAN output",
@@ -11255,10 +12123,13 @@
11255 " --reset Reset the count for each input and interrupt",
11256 #endif
11257 ".prompt MAIN CONTINUE Replace the standard prompts",
11258 ".quit Exit this program",
11259 ".read FILE Read input from FILE",
 
 
 
11260 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
11261 ".save FILE Write in-memory database into FILE",
11262 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
11263 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
11264 " Options:",
@@ -11539,11 +12410,11 @@
11539 int pgsz = 0;
11540 int iOffset = 0;
11541 int j, k;
11542 int rc;
11543 FILE *in;
11544 unsigned char x[16];
11545 char zLine[1000];
11546 if( p->zDbFilename ){
11547 in = fopen(p->zDbFilename, "r");
11548 if( in==0 ){
11549 utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
@@ -11551,18 +12422,19 @@
11551 }
11552 nLine = 0;
11553 }else{
11554 in = p->in;
11555 nLine = p->lineno;
 
11556 }
11557 *pnData = 0;
11558 nLine++;
11559 if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
11560 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
11561 if( rc!=2 ) goto readHexDb_error;
11562 if( n<=0 ) goto readHexDb_error;
11563 a = sqlite3_malloc( n );
11564 if( a==0 ){
11565 utf8_printf(stderr, "Out of memory!\n");
11566 goto readHexDb_error;
11567 }
11568 memset(a, 0, n);
@@ -11577,18 +12449,18 @@
11577 continue;
11578 }
11579 if( strncmp(zLine, "| end ", 6)==0 ){
11580 break;
11581 }
11582 rc = sscanf(zLine,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
11583 " %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
11584 &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
11585 &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
11586 if( rc==17 ){
11587 k = iOffset+j;
11588 if( k+16<=n ){
11589 memcpy(a+k, x, 16);
 
11590 }
11591 }
11592 }
11593 *pnData = n;
11594 if( in!=p->in ){
@@ -11597,11 +12469,11 @@
11597 p->lineno = nLine;
11598 }
11599 return a;
11600
11601 readHexDb_error:
11602 if( in!=stdin ){
11603 fclose(in);
11604 }else{
11605 while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
11606 nLine++;
11607 if(strncmp(zLine, "| end ", 6)==0 ) break;
@@ -11611,10 +12483,131 @@
11611 sqlite3_free(a);
11612 utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
11613 return 0;
11614 }
11615 #endif /* SQLITE_ENABLE_DESERIALIZE */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11616
11617 /* Flags for open_db().
11618 **
11619 ** The default behavior of open_db() is to exit(1) if the database fails to
11620 ** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
@@ -11680,10 +12673,13 @@
11680 sqlite3_enable_load_extension(p->db, 1);
11681 #endif
11682 sqlite3_fileio_init(p->db, 0, 0);
11683 sqlite3_shathree_init(p->db, 0, 0);
11684 sqlite3_completion_init(p->db, 0, 0);
 
 
 
11685 #ifdef SQLITE_HAVE_ZLIB
11686 sqlite3_zipfile_init(p->db, 0, 0);
11687 sqlite3_sqlar_init(p->db, 0, 0);
11688 #endif
11689 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
@@ -11690,10 +12686,14 @@
11690 shellAddSchemaName, 0, 0);
11691 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
11692 shellModuleSchema, 0, 0);
11693 sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
11694 shellPutsFunc, 0, 0);
 
 
 
 
11695 #ifndef SQLITE_NOHAVE_SYSTEM
11696 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
11697 editFunc, 0, 0);
11698 sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
11699 editFunc, 0, 0);
@@ -11713,11 +12713,10 @@
11713 if( p->openMode==SHELL_OPEN_DESERIALIZE ){
11714 aData = (unsigned char*)readFile(p->zDbFilename, &nData);
11715 }else{
11716 aData = readHexDb(p, &nData);
11717 if( aData==0 ){
11718 utf8_printf(stderr, "Error in hexdb input\n");
11719 return;
11720 }
11721 }
11722 rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
11723 SQLITE_DESERIALIZE_RESIZEABLE |
@@ -12944,14 +13943,11 @@
12944 raw_printf(stderr, "Where sub-commands are:\n");
12945 raw_printf(stderr, " fkey-indexes\n");
12946 return SQLITE_ERROR;
12947 }
12948
12949 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
12950 /*********************************************************************************
12951 ** The ".archive" or ".ar" command.
12952 */
12953 static void shellPrepare(
12954 sqlite3 *db,
12955 int *pRc,
12956 const char *zSql,
12957 sqlite3_stmt **ppStmt
@@ -12966,11 +13962,18 @@
12966 *pRc = rc;
12967 }
12968 }
12969 }
12970
12971 static void shellPreparePrintf(
 
 
 
 
 
 
 
12972 sqlite3 *db,
12973 int *pRc,
12974 sqlite3_stmt **ppStmt,
12975 const char *zFmt,
12976 ...
@@ -12989,11 +13992,17 @@
12989 sqlite3_free(z);
12990 }
12991 }
12992 }
12993
12994 static void shellFinalize(
 
 
 
 
 
 
12995 int *pRc,
12996 sqlite3_stmt *pStmt
12997 ){
12998 if( pStmt ){
12999 sqlite3 *db = sqlite3_db_handle(pStmt);
@@ -13005,11 +14014,17 @@
13005 *pRc = rc;
13006 }
13007 }
13008 }
13009
13010 static void shellReset(
 
 
 
 
 
 
13011 int *pRc,
13012 sqlite3_stmt *pStmt
13013 ){
13014 int rc = sqlite3_reset(pStmt);
13015 if( *pRc==SQLITE_OK ){
@@ -13018,10 +14033,16 @@
13018 raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
13019 }
13020 *pRc = rc;
13021 }
13022 }
 
 
 
 
 
 
13023 /*
13024 ** Structure representing a single ".ar" command.
13025 */
13026 typedef struct ArCommand ArCommand;
13027 struct ArCommand {
@@ -13707,10 +14728,639 @@
13707 }
13708 /* End of the ".archive" or ".ar" command logic
13709 **********************************************************************************/
13710 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
13711
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13712
13713 /*
13714 ** If an input line begins with "." then invoke this routine to
13715 ** process that line.
13716 **
@@ -13994,10 +15644,17 @@
13994
13995 if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
13996 rc = shell_dbinfo_command(p, nArg, azArg);
13997 }else
13998
 
 
 
 
 
 
 
13999 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
14000 const char *zLike = 0;
14001 int i;
14002 int savedShowHeader = p->showHeader;
14003 int savedShellFlags = p->shellFlgs;
@@ -14031,11 +15688,13 @@
14031 goto meta_command_exit;
14032 }else{
14033 zLike = azArg[i];
14034 }
14035 }
 
14036 open_db(p, 0);
 
14037 /* When playing back a "dump", the content might appear in an order
14038 ** which causes immediate foreign key constraints to be violated.
14039 ** So disable foreign-key constraint enforcement to prevent problems. */
14040 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
14041 raw_printf(p->out, "BEGIN TRANSACTION;\n");
@@ -14079,11 +15738,11 @@
14079 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
14080 p->writableSchema = 0;
14081 }
14082 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
14083 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
14084 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
14085 p->showHeader = savedShowHeader;
14086 p->shellFlgs = savedShellFlags;
14087 }else
14088
14089 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
14090
--- src/shell.c
+++ src/shell.c
@@ -981,10 +981,11 @@
981
982 /*
983 ** We need several support functions from the SQLite core.
984 */
985
986 /* #include "sqlite3.h" */
987
988 /*
989 ** We need several things from the ANSI and MSVCRT headers.
990 */
991
@@ -1334,10 +1335,11 @@
1335 **
1336 ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
1337 ** is used. If SIZE is included it must be one of the integers 224, 256,
1338 ** 384, or 512, to determine SHA3 hash variant that is computed.
1339 */
1340 /* #include "sqlite3ext.h" */
1341 SQLITE_EXTENSION_INIT1
1342 #include <assert.h>
1343 #include <string.h>
1344 #include <stdarg.h>
1345 /* typedef sqlite3_uint64 u64; */
@@ -2097,10 +2099,11 @@
2099 ** If a non-NULL value is specified for the optional $dir parameter and
2100 ** $path is a relative path, then $path is interpreted relative to $dir.
2101 ** And the paths returned in the "name" column of the table are also
2102 ** relative to directory $dir.
2103 */
2104 /* #include "sqlite3ext.h" */
2105 SQLITE_EXTENSION_INIT1
2106 #include <stdio.h>
2107 #include <string.h>
2108 #include <assert.h>
2109
@@ -3054,10 +3057,11 @@
3057 ** This virtual table operates at the speed of human typing, and so there
3058 ** is no attempt to make it fast. Even a slow implementation will be much
3059 ** faster than any human can type.
3060 **
3061 */
3062 /* #include "sqlite3ext.h" */
3063 SQLITE_EXTENSION_INIT1
3064 #include <assert.h>
3065 #include <string.h>
3066 #include <ctype.h>
3067
@@ -3570,10 +3574,11 @@
3574 ** database in a separate file.
3575 **
3576 ** If the file being opened is not an appended database, then this shim is
3577 ** a pass-through into the default underlying VFS.
3578 **/
3579 /* #include "sqlite3ext.h" */
3580 SQLITE_EXTENSION_INIT1
3581 #include <string.h>
3582 #include <assert.h>
3583
3584 /* The append mark at the end of the database is:
@@ -4226,10 +4231,11 @@
4231 ** * No support for encryption
4232 ** * No support for ZIP archives spanning multiple files
4233 ** * No support for zip64 extensions
4234 ** * Only the "inflate/deflate" (zlib) compression method is supported
4235 */
4236 /* #include "sqlite3ext.h" */
4237 SQLITE_EXTENSION_INIT1
4238 #include <stdio.h>
4239 #include <string.h>
4240 #include <assert.h>
4241
@@ -6396,10 +6402,11 @@
6402 **
6403 ** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
6404 ** for working with sqlar archives and used by the shell tool's built-in
6405 ** sqlar support.
6406 */
6407 /* #include "sqlite3ext.h" */
6408 SQLITE_EXTENSION_INIT1
6409 #include <zlib.h>
6410
6411 /*
6412 ** Implementation of the "sqlar_compress(X)" SQL function.
@@ -6518,10 +6525,11 @@
6525 **
6526 *************************************************************************
6527 */
6528
6529
6530 /* #include "sqlite3.h" */
6531
6532 typedef struct sqlite3expert sqlite3expert;
6533
6534 /*
6535 ** Create a new sqlite3expert object.
@@ -6686,10 +6694,11 @@
6694 ** May you find forgiveness for yourself and forgive others.
6695 ** May you share freely, never taking more than you give.
6696 **
6697 *************************************************************************
6698 */
6699 /* #include "sqlite3expert.h" */
6700 #include <assert.h>
6701 #include <string.h>
6702 #include <stdio.h>
6703
6704 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -8628,10 +8637,867 @@
8637 }
8638
8639 #endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
8640
8641 /************************* End ../ext/expert/sqlite3expert.c ********************/
8642
8643 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
8644 /************************* Begin ../ext/misc/dbdata.c ******************/
8645 /*
8646 ** 2019-04-17
8647 **
8648 ** The author disclaims copyright to this source code. In place of
8649 ** a legal notice, here is a blessing:
8650 **
8651 ** May you do good and not evil.
8652 ** May you find forgiveness for yourself and forgive others.
8653 ** May you share freely, never taking more than you give.
8654 **
8655 ******************************************************************************
8656 **
8657 ** This file contains an implementation of two eponymous virtual tables,
8658 ** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
8659 ** "sqlite_dbpage" eponymous virtual table be available.
8660 **
8661 ** SQLITE_DBDATA:
8662 ** sqlite_dbdata is used to extract data directly from a database b-tree
8663 ** page and its associated overflow pages, bypassing the b-tree layer.
8664 ** The table schema is equivalent to:
8665 **
8666 ** CREATE TABLE sqlite_dbdata(
8667 ** pgno INTEGER,
8668 ** cell INTEGER,
8669 ** field INTEGER,
8670 ** value ANY,
8671 ** schema TEXT HIDDEN
8672 ** );
8673 **
8674 ** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
8675 ** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
8676 ** "schema".
8677 **
8678 ** Each page of the database is inspected. If it cannot be interpreted as
8679 ** a b-tree page, or if it is a b-tree page containing 0 entries, the
8680 ** sqlite_dbdata table contains no rows for that page. Otherwise, the
8681 ** table contains one row for each field in the record associated with
8682 ** each cell on the page. For intkey b-trees, the key value is stored in
8683 ** field -1.
8684 **
8685 ** For example, for the database:
8686 **
8687 ** CREATE TABLE t1(a, b); -- root page is page 2
8688 ** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
8689 ** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
8690 **
8691 ** the sqlite_dbdata table contains, as well as from entries related to
8692 ** page 1, content equivalent to:
8693 **
8694 ** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
8695 ** (2, 0, -1, 5 ),
8696 ** (2, 0, 0, 'v' ),
8697 ** (2, 0, 1, 'five'),
8698 ** (2, 1, -1, 10 ),
8699 ** (2, 1, 0, 'x' ),
8700 ** (2, 1, 1, 'ten' );
8701 **
8702 ** If database corruption is encountered, this module does not report an
8703 ** error. Instead, it attempts to extract as much data as possible and
8704 ** ignores the corruption.
8705 **
8706 ** SQLITE_DBPTR:
8707 ** The sqlite_dbptr table has the following schema:
8708 **
8709 ** CREATE TABLE sqlite_dbptr(
8710 ** pgno INTEGER,
8711 ** child INTEGER,
8712 ** schema TEXT HIDDEN
8713 ** );
8714 **
8715 ** It contains one entry for each b-tree pointer between a parent and
8716 ** child page in the database.
8717 */
8718 #if !defined(SQLITEINT_H)
8719 /* #include "sqlite3ext.h" */
8720
8721 /* typedef unsigned char u8; */
8722
8723 #endif
8724 SQLITE_EXTENSION_INIT1
8725 #include <string.h>
8726 #include <assert.h>
8727
8728 #define DBDATA_PADDING_BYTES 100
8729
8730 typedef struct DbdataTable DbdataTable;
8731 typedef struct DbdataCursor DbdataCursor;
8732
8733 /* Cursor object */
8734 struct DbdataCursor {
8735 sqlite3_vtab_cursor base; /* Base class. Must be first */
8736 sqlite3_stmt *pStmt; /* For fetching database pages */
8737
8738 int iPgno; /* Current page number */
8739 u8 *aPage; /* Buffer containing page */
8740 int nPage; /* Size of aPage[] in bytes */
8741 int nCell; /* Number of cells on aPage[] */
8742 int iCell; /* Current cell number */
8743 int bOnePage; /* True to stop after one page */
8744 int szDb;
8745 sqlite3_int64 iRowid;
8746
8747 /* Only for the sqlite_dbdata table */
8748 u8 *pRec; /* Buffer containing current record */
8749 int nRec; /* Size of pRec[] in bytes */
8750 int nHdr; /* Size of header in bytes */
8751 int iField; /* Current field number */
8752 u8 *pHdrPtr;
8753 u8 *pPtr;
8754
8755 sqlite3_int64 iIntkey; /* Integer key value */
8756 };
8757
8758 /* Table object */
8759 struct DbdataTable {
8760 sqlite3_vtab base; /* Base class. Must be first */
8761 sqlite3 *db; /* The database connection */
8762 sqlite3_stmt *pStmt; /* For fetching database pages */
8763 int bPtr; /* True for sqlite3_dbptr table */
8764 };
8765
8766 /* Column and schema definitions for sqlite_dbdata */
8767 #define DBDATA_COLUMN_PGNO 0
8768 #define DBDATA_COLUMN_CELL 1
8769 #define DBDATA_COLUMN_FIELD 2
8770 #define DBDATA_COLUMN_VALUE 3
8771 #define DBDATA_COLUMN_SCHEMA 4
8772 #define DBDATA_SCHEMA \
8773 "CREATE TABLE x(" \
8774 " pgno INTEGER," \
8775 " cell INTEGER," \
8776 " field INTEGER," \
8777 " value ANY," \
8778 " schema TEXT HIDDEN" \
8779 ")"
8780
8781 /* Column and schema definitions for sqlite_dbptr */
8782 #define DBPTR_COLUMN_PGNO 0
8783 #define DBPTR_COLUMN_CHILD 1
8784 #define DBPTR_COLUMN_SCHEMA 2
8785 #define DBPTR_SCHEMA \
8786 "CREATE TABLE x(" \
8787 " pgno INTEGER," \
8788 " child INTEGER," \
8789 " schema TEXT HIDDEN" \
8790 ")"
8791
8792 /*
8793 ** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual
8794 ** table.
8795 */
8796 static int dbdataConnect(
8797 sqlite3 *db,
8798 void *pAux,
8799 int argc, const char *const*argv,
8800 sqlite3_vtab **ppVtab,
8801 char **pzErr
8802 ){
8803 DbdataTable *pTab = 0;
8804 int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
8805
8806 if( rc==SQLITE_OK ){
8807 pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
8808 if( pTab==0 ){
8809 rc = SQLITE_NOMEM;
8810 }else{
8811 memset(pTab, 0, sizeof(DbdataTable));
8812 pTab->db = db;
8813 pTab->bPtr = (pAux!=0);
8814 }
8815 }
8816
8817 *ppVtab = (sqlite3_vtab*)pTab;
8818 return rc;
8819 }
8820
8821 /*
8822 ** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
8823 */
8824 static int dbdataDisconnect(sqlite3_vtab *pVtab){
8825 DbdataTable *pTab = (DbdataTable*)pVtab;
8826 if( pTab ){
8827 sqlite3_finalize(pTab->pStmt);
8828 sqlite3_free(pVtab);
8829 }
8830 return SQLITE_OK;
8831 }
8832
8833 /*
8834 ** This function interprets two types of constraints:
8835 **
8836 ** schema=?
8837 ** pgno=?
8838 **
8839 ** If neither are present, idxNum is set to 0. If schema=? is present,
8840 ** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
8841 ** in idxNum is set.
8842 **
8843 ** If both parameters are present, schema is in position 0 and pgno in
8844 ** position 1.
8845 */
8846 static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
8847 DbdataTable *pTab = (DbdataTable*)tab;
8848 int i;
8849 int iSchema = -1;
8850 int iPgno = -1;
8851 int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
8852
8853 for(i=0; i<pIdx->nConstraint; i++){
8854 struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
8855 if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
8856 if( p->iColumn==colSchema ){
8857 if( p->usable==0 ) return SQLITE_CONSTRAINT;
8858 iSchema = i;
8859 }
8860 if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
8861 iPgno = i;
8862 }
8863 }
8864 }
8865
8866 if( iSchema>=0 ){
8867 pIdx->aConstraintUsage[iSchema].argvIndex = 1;
8868 pIdx->aConstraintUsage[iSchema].omit = 1;
8869 }
8870 if( iPgno>=0 ){
8871 pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
8872 pIdx->aConstraintUsage[iPgno].omit = 1;
8873 pIdx->estimatedCost = 100;
8874 pIdx->estimatedRows = 50;
8875
8876 if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
8877 int iCol = pIdx->aOrderBy[0].iColumn;
8878 if( pIdx->nOrderBy==1 ){
8879 pIdx->orderByConsumed = (iCol==0 || iCol==1);
8880 }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
8881 pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
8882 }
8883 }
8884
8885 }else{
8886 pIdx->estimatedCost = 100000000;
8887 pIdx->estimatedRows = 1000000000;
8888 }
8889 pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
8890 return SQLITE_OK;
8891 }
8892
8893 /*
8894 ** Open a new sqlite_dbdata or sqlite_dbptr cursor.
8895 */
8896 static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
8897 DbdataCursor *pCsr;
8898
8899 pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
8900 if( pCsr==0 ){
8901 return SQLITE_NOMEM;
8902 }else{
8903 memset(pCsr, 0, sizeof(DbdataCursor));
8904 pCsr->base.pVtab = pVTab;
8905 }
8906
8907 *ppCursor = (sqlite3_vtab_cursor *)pCsr;
8908 return SQLITE_OK;
8909 }
8910
8911 /*
8912 ** Restore a cursor object to the state it was in when first allocated
8913 ** by dbdataOpen().
8914 */
8915 static void dbdataResetCursor(DbdataCursor *pCsr){
8916 DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
8917 if( pTab->pStmt==0 ){
8918 pTab->pStmt = pCsr->pStmt;
8919 }else{
8920 sqlite3_finalize(pCsr->pStmt);
8921 }
8922 pCsr->pStmt = 0;
8923 pCsr->iPgno = 1;
8924 pCsr->iCell = 0;
8925 pCsr->iField = 0;
8926 pCsr->bOnePage = 0;
8927 sqlite3_free(pCsr->aPage);
8928 sqlite3_free(pCsr->pRec);
8929 pCsr->pRec = 0;
8930 pCsr->aPage = 0;
8931 }
8932
8933 /*
8934 ** Close an sqlite_dbdata or sqlite_dbptr cursor.
8935 */
8936 static int dbdataClose(sqlite3_vtab_cursor *pCursor){
8937 DbdataCursor *pCsr = (DbdataCursor*)pCursor;
8938 dbdataResetCursor(pCsr);
8939 sqlite3_free(pCsr);
8940 return SQLITE_OK;
8941 }
8942
8943 /*
8944 ** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
8945 */
8946 static unsigned int get_uint16(unsigned char *a){
8947 return (a[0]<<8)|a[1];
8948 }
8949 static unsigned int get_uint32(unsigned char *a){
8950 return ((unsigned int)a[0]<<24)
8951 | ((unsigned int)a[1]<<16)
8952 | ((unsigned int)a[2]<<8)
8953 | ((unsigned int)a[3]);
8954 }
8955
8956 /*
8957 ** Load page pgno from the database via the sqlite_dbpage virtual table.
8958 ** If successful, set (*ppPage) to point to a buffer containing the page
8959 ** data, (*pnPage) to the size of that buffer in bytes and return
8960 ** SQLITE_OK. In this case it is the responsibility of the caller to
8961 ** eventually free the buffer using sqlite3_free().
8962 **
8963 ** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
8964 ** return an SQLite error code.
8965 */
8966 static int dbdataLoadPage(
8967 DbdataCursor *pCsr, /* Cursor object */
8968 unsigned int pgno, /* Page number of page to load */
8969 u8 **ppPage, /* OUT: pointer to page buffer */
8970 int *pnPage /* OUT: Size of (*ppPage) in bytes */
8971 ){
8972 int rc2;
8973 int rc = SQLITE_OK;
8974 sqlite3_stmt *pStmt = pCsr->pStmt;
8975
8976 *ppPage = 0;
8977 *pnPage = 0;
8978 sqlite3_bind_int64(pStmt, 2, pgno);
8979 if( SQLITE_ROW==sqlite3_step(pStmt) ){
8980 int nCopy = sqlite3_column_bytes(pStmt, 0);
8981 if( nCopy>0 ){
8982 u8 *pPage;
8983 pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
8984 if( pPage==0 ){
8985 rc = SQLITE_NOMEM;
8986 }else{
8987 const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
8988 memcpy(pPage, pCopy, nCopy);
8989 memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
8990 }
8991 *ppPage = pPage;
8992 *pnPage = nCopy;
8993 }
8994 }
8995 rc2 = sqlite3_reset(pStmt);
8996 if( rc==SQLITE_OK ) rc = rc2;
8997
8998 return rc;
8999 }
9000
9001 /*
9002 ** Read a varint. Put the value in *pVal and return the number of bytes.
9003 */
9004 static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
9005 sqlite3_int64 v = 0;
9006 int i;
9007 for(i=0; i<8; i++){
9008 v = (v<<7) + (z[i]&0x7f);
9009 if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
9010 }
9011 v = (v<<8) + (z[i]&0xff);
9012 *pVal = v;
9013 return 9;
9014 }
9015
9016 /*
9017 ** Return the number of bytes of space used by an SQLite value of type
9018 ** eType.
9019 */
9020 static int dbdataValueBytes(int eType){
9021 switch( eType ){
9022 case 0: case 8: case 9:
9023 case 10: case 11:
9024 return 0;
9025 case 1:
9026 return 1;
9027 case 2:
9028 return 2;
9029 case 3:
9030 return 3;
9031 case 4:
9032 return 4;
9033 case 5:
9034 return 6;
9035 case 6:
9036 case 7:
9037 return 8;
9038 default:
9039 if( eType>0 ){
9040 return ((eType-12) / 2);
9041 }
9042 return 0;
9043 }
9044 }
9045
9046 /*
9047 ** Load a value of type eType from buffer pData and use it to set the
9048 ** result of context object pCtx.
9049 */
9050 static void dbdataValue(
9051 sqlite3_context *pCtx,
9052 int eType,
9053 u8 *pData,
9054 int nData
9055 ){
9056 if( eType>=0 && dbdataValueBytes(eType)<=nData ){
9057 switch( eType ){
9058 case 0:
9059 case 10:
9060 case 11:
9061 sqlite3_result_null(pCtx);
9062 break;
9063
9064 case 8:
9065 sqlite3_result_int(pCtx, 0);
9066 break;
9067 case 9:
9068 sqlite3_result_int(pCtx, 1);
9069 break;
9070
9071 case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
9072 sqlite3_uint64 v = (signed char)pData[0];
9073 pData++;
9074 switch( eType ){
9075 case 7:
9076 case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
9077 case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
9078 case 4: v = (v<<8) + pData[0]; pData++;
9079 case 3: v = (v<<8) + pData[0]; pData++;
9080 case 2: v = (v<<8) + pData[0]; pData++;
9081 }
9082
9083 if( eType==7 ){
9084 double r;
9085 memcpy(&r, &v, sizeof(r));
9086 sqlite3_result_double(pCtx, r);
9087 }else{
9088 sqlite3_result_int64(pCtx, (sqlite3_int64)v);
9089 }
9090 break;
9091 }
9092
9093 default: {
9094 int n = ((eType-12) / 2);
9095 if( eType % 2 ){
9096 sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
9097 }else{
9098 sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
9099 }
9100 }
9101 }
9102 }
9103 }
9104
9105 /*
9106 ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
9107 */
9108 static int dbdataNext(sqlite3_vtab_cursor *pCursor){
9109 DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9110 DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
9111
9112 pCsr->iRowid++;
9113 while( 1 ){
9114 int rc;
9115 int iOff = (pCsr->iPgno==1 ? 100 : 0);
9116 int bNextPage = 0;
9117
9118 if( pCsr->aPage==0 ){
9119 while( 1 ){
9120 if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
9121 rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
9122 if( rc!=SQLITE_OK ) return rc;
9123 if( pCsr->aPage ) break;
9124 pCsr->iPgno++;
9125 }
9126 pCsr->iCell = pTab->bPtr ? -2 : 0;
9127 pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
9128 }
9129
9130 if( pTab->bPtr ){
9131 if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
9132 pCsr->iCell = pCsr->nCell;
9133 }
9134 pCsr->iCell++;
9135 if( pCsr->iCell>=pCsr->nCell ){
9136 sqlite3_free(pCsr->aPage);
9137 pCsr->aPage = 0;
9138 if( pCsr->bOnePage ) return SQLITE_OK;
9139 pCsr->iPgno++;
9140 }else{
9141 return SQLITE_OK;
9142 }
9143 }else{
9144 /* If there is no record loaded, load it now. */
9145 if( pCsr->pRec==0 ){
9146 int bHasRowid = 0;
9147 int nPointer = 0;
9148 sqlite3_int64 nPayload = 0;
9149 sqlite3_int64 nHdr = 0;
9150 int iHdr;
9151 int U, X;
9152 int nLocal;
9153
9154 switch( pCsr->aPage[iOff] ){
9155 case 0x02:
9156 nPointer = 4;
9157 break;
9158 case 0x0a:
9159 break;
9160 case 0x0d:
9161 bHasRowid = 1;
9162 break;
9163 default:
9164 /* This is not a b-tree page with records on it. Continue. */
9165 pCsr->iCell = pCsr->nCell;
9166 break;
9167 }
9168
9169 if( pCsr->iCell>=pCsr->nCell ){
9170 bNextPage = 1;
9171 }else{
9172
9173 iOff += 8 + nPointer + pCsr->iCell*2;
9174 if( iOff>pCsr->nPage ){
9175 bNextPage = 1;
9176 }else{
9177 iOff = get_uint16(&pCsr->aPage[iOff]);
9178 }
9179
9180 /* For an interior node cell, skip past the child-page number */
9181 iOff += nPointer;
9182
9183 /* Load the "byte of payload including overflow" field */
9184 if( bNextPage || iOff>pCsr->nPage ){
9185 bNextPage = 1;
9186 }else{
9187 iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
9188 }
9189
9190 /* If this is a leaf intkey cell, load the rowid */
9191 if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
9192 iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
9193 }
9194
9195 /* Figure out how much data to read from the local page */
9196 U = pCsr->nPage;
9197 if( bHasRowid ){
9198 X = U-35;
9199 }else{
9200 X = ((U-12)*64/255)-23;
9201 }
9202 if( nPayload<=X ){
9203 nLocal = nPayload;
9204 }else{
9205 int M, K;
9206 M = ((U-12)*32/255)-23;
9207 K = M+((nPayload-M)%(U-4));
9208 if( K<=X ){
9209 nLocal = K;
9210 }else{
9211 nLocal = M;
9212 }
9213 }
9214
9215 if( bNextPage || nLocal+iOff>pCsr->nPage ){
9216 bNextPage = 1;
9217 }else{
9218
9219 /* Allocate space for payload. And a bit more to catch small buffer
9220 ** overruns caused by attempting to read a varint or similar from
9221 ** near the end of a corrupt record. */
9222 pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
9223 if( pCsr->pRec==0 ) return SQLITE_NOMEM;
9224 memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
9225 pCsr->nRec = nPayload;
9226
9227 /* Load the nLocal bytes of payload */
9228 memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
9229 iOff += nLocal;
9230
9231 /* Load content from overflow pages */
9232 if( nPayload>nLocal ){
9233 sqlite3_int64 nRem = nPayload - nLocal;
9234 unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
9235 while( nRem>0 ){
9236 u8 *aOvfl = 0;
9237 int nOvfl = 0;
9238 int nCopy;
9239 rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
9240 assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
9241 if( rc!=SQLITE_OK ) return rc;
9242 if( aOvfl==0 ) break;
9243
9244 nCopy = U-4;
9245 if( nCopy>nRem ) nCopy = nRem;
9246 memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
9247 nRem -= nCopy;
9248
9249 pgnoOvfl = get_uint32(aOvfl);
9250 sqlite3_free(aOvfl);
9251 }
9252 }
9253
9254 iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
9255 pCsr->nHdr = nHdr;
9256 pCsr->pHdrPtr = &pCsr->pRec[iHdr];
9257 pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
9258 pCsr->iField = (bHasRowid ? -1 : 0);
9259 }
9260 }
9261 }else{
9262 pCsr->iField++;
9263 if( pCsr->iField>0 ){
9264 sqlite3_int64 iType;
9265 if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
9266 bNextPage = 1;
9267 }else{
9268 pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
9269 pCsr->pPtr += dbdataValueBytes(iType);
9270 }
9271 }
9272 }
9273
9274 if( bNextPage ){
9275 sqlite3_free(pCsr->aPage);
9276 sqlite3_free(pCsr->pRec);
9277 pCsr->aPage = 0;
9278 pCsr->pRec = 0;
9279 if( pCsr->bOnePage ) return SQLITE_OK;
9280 pCsr->iPgno++;
9281 }else{
9282 if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
9283 return SQLITE_OK;
9284 }
9285
9286 /* Advance to the next cell. The next iteration of the loop will load
9287 ** the record and so on. */
9288 sqlite3_free(pCsr->pRec);
9289 pCsr->pRec = 0;
9290 pCsr->iCell++;
9291 }
9292 }
9293 }
9294
9295 assert( !"can't get here" );
9296 return SQLITE_OK;
9297 }
9298
9299 /*
9300 ** Return true if the cursor is at EOF.
9301 */
9302 static int dbdataEof(sqlite3_vtab_cursor *pCursor){
9303 DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9304 return pCsr->aPage==0;
9305 }
9306
9307 /*
9308 ** Determine the size in pages of database zSchema (where zSchema is
9309 ** "main", "temp" or the name of an attached database) and set
9310 ** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
9311 ** an SQLite error code.
9312 */
9313 static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
9314 DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
9315 char *zSql = 0;
9316 int rc, rc2;
9317 sqlite3_stmt *pStmt = 0;
9318
9319 zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
9320 if( zSql==0 ) return SQLITE_NOMEM;
9321 rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
9322 sqlite3_free(zSql);
9323 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
9324 pCsr->szDb = sqlite3_column_int(pStmt, 0);
9325 }
9326 rc2 = sqlite3_finalize(pStmt);
9327 if( rc==SQLITE_OK ) rc = rc2;
9328 return rc;
9329 }
9330
9331 /*
9332 ** xFilter method for sqlite_dbdata and sqlite_dbptr.
9333 */
9334 static int dbdataFilter(
9335 sqlite3_vtab_cursor *pCursor,
9336 int idxNum, const char *idxStr,
9337 int argc, sqlite3_value **argv
9338 ){
9339 DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9340 DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
9341 int rc = SQLITE_OK;
9342 const char *zSchema = "main";
9343
9344 dbdataResetCursor(pCsr);
9345 assert( pCsr->iPgno==1 );
9346 if( idxNum & 0x01 ){
9347 zSchema = (const char*)sqlite3_value_text(argv[0]);
9348 }
9349 if( idxNum & 0x02 ){
9350 pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
9351 pCsr->bOnePage = 1;
9352 }else{
9353 pCsr->nPage = dbdataDbsize(pCsr, zSchema);
9354 rc = dbdataDbsize(pCsr, zSchema);
9355 }
9356
9357 if( rc==SQLITE_OK ){
9358 if( pTab->pStmt ){
9359 pCsr->pStmt = pTab->pStmt;
9360 pTab->pStmt = 0;
9361 }else{
9362 rc = sqlite3_prepare_v2(pTab->db,
9363 "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
9364 &pCsr->pStmt, 0
9365 );
9366 }
9367 }
9368 if( rc==SQLITE_OK ){
9369 rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
9370 }else{
9371 pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
9372 }
9373 if( rc==SQLITE_OK ){
9374 rc = dbdataNext(pCursor);
9375 }
9376 return rc;
9377 }
9378
9379 /*
9380 ** Return a column for the sqlite_dbdata or sqlite_dbptr table.
9381 */
9382 static int dbdataColumn(
9383 sqlite3_vtab_cursor *pCursor,
9384 sqlite3_context *ctx,
9385 int i
9386 ){
9387 DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9388 DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
9389 if( pTab->bPtr ){
9390 switch( i ){
9391 case DBPTR_COLUMN_PGNO:
9392 sqlite3_result_int64(ctx, pCsr->iPgno);
9393 break;
9394 case DBPTR_COLUMN_CHILD: {
9395 int iOff = pCsr->iPgno==1 ? 100 : 0;
9396 if( pCsr->iCell<0 ){
9397 iOff += 8;
9398 }else{
9399 iOff += 12 + pCsr->iCell*2;
9400 if( iOff>pCsr->nPage ) return SQLITE_OK;
9401 iOff = get_uint16(&pCsr->aPage[iOff]);
9402 }
9403 if( iOff<=pCsr->nPage ){
9404 sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
9405 }
9406 break;
9407 }
9408 }
9409 }else{
9410 switch( i ){
9411 case DBDATA_COLUMN_PGNO:
9412 sqlite3_result_int64(ctx, pCsr->iPgno);
9413 break;
9414 case DBDATA_COLUMN_CELL:
9415 sqlite3_result_int(ctx, pCsr->iCell);
9416 break;
9417 case DBDATA_COLUMN_FIELD:
9418 sqlite3_result_int(ctx, pCsr->iField);
9419 break;
9420 case DBDATA_COLUMN_VALUE: {
9421 if( pCsr->iField<0 ){
9422 sqlite3_result_int64(ctx, pCsr->iIntkey);
9423 }else{
9424 sqlite3_int64 iType;
9425 dbdataGetVarint(pCsr->pHdrPtr, &iType);
9426 dbdataValue(
9427 ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
9428 );
9429 }
9430 break;
9431 }
9432 }
9433 }
9434 return SQLITE_OK;
9435 }
9436
9437 /*
9438 ** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
9439 */
9440 static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
9441 DbdataCursor *pCsr = (DbdataCursor*)pCursor;
9442 *pRowid = pCsr->iRowid;
9443 return SQLITE_OK;
9444 }
9445
9446
9447 /*
9448 ** Invoke this routine to register the "sqlite_dbdata" virtual table module
9449 */
9450 static int sqlite3DbdataRegister(sqlite3 *db){
9451 static sqlite3_module dbdata_module = {
9452 0, /* iVersion */
9453 0, /* xCreate */
9454 dbdataConnect, /* xConnect */
9455 dbdataBestIndex, /* xBestIndex */
9456 dbdataDisconnect, /* xDisconnect */
9457 0, /* xDestroy */
9458 dbdataOpen, /* xOpen - open a cursor */
9459 dbdataClose, /* xClose - close a cursor */
9460 dbdataFilter, /* xFilter - configure scan constraints */
9461 dbdataNext, /* xNext - advance a cursor */
9462 dbdataEof, /* xEof - check for end of scan */
9463 dbdataColumn, /* xColumn - read data */
9464 dbdataRowid, /* xRowid - read data */
9465 0, /* xUpdate */
9466 0, /* xBegin */
9467 0, /* xSync */
9468 0, /* xCommit */
9469 0, /* xRollback */
9470 0, /* xFindMethod */
9471 0, /* xRename */
9472 0, /* xSavepoint */
9473 0, /* xRelease */
9474 0, /* xRollbackTo */
9475 0 /* xShadowName */
9476 };
9477
9478 int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
9479 if( rc==SQLITE_OK ){
9480 rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
9481 }
9482 return rc;
9483 }
9484
9485 #ifdef _WIN32
9486
9487 #endif
9488 int sqlite3_dbdata_init(
9489 sqlite3 *db,
9490 char **pzErrMsg,
9491 const sqlite3_api_routines *pApi
9492 ){
9493 SQLITE_EXTENSION_INIT2(pApi);
9494 return sqlite3DbdataRegister(db);
9495 }
9496
9497 /************************* End ../ext/misc/dbdata.c ********************/
9498 #endif
9499
9500 #if defined(SQLITE_ENABLE_SESSION)
9501 /*
9502 ** State information for a single open session
9503 */
@@ -9358,10 +10224,12 @@
10224 **
10225 ** This routine converts some CREATE TABLE statements for shadow tables
10226 ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
10227 */
10228 static void printSchemaLine(FILE *out, const char *z, const char *zTail){
10229 if( z==0 ) return;
10230 if( zTail==0 ) return;
10231 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
10232 utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
10233 }else{
10234 utf8_printf(out, "%s%s", z, zTail);
10235 }
@@ -11170,11 +12038,11 @@
12038 ".dbinfo ?DB? Show status information about the database",
12039 ".dump ?TABLE? ... Render all database content as SQL",
12040 " Options:",
12041 " --preserve-rowids Include ROWID values in the output",
12042 " --newlines Allow unescaped newline characters in output",
12043 " TABLE is a LIKE pattern for the tables to dump",
12044 ".echo on|off Turn command echo on or off",
12045 ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
12046 " Other Modes:",
12047 #ifdef SQLITE_DEBUG
12048 " test Show raw EXPLAIN QUERY PLAN output",
@@ -11255,10 +12123,13 @@
12123 " --reset Reset the count for each input and interrupt",
12124 #endif
12125 ".prompt MAIN CONTINUE Replace the standard prompts",
12126 ".quit Exit this program",
12127 ".read FILE Read input from FILE",
12128 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
12129 ".recover Recover as much data as possible from corrupt db.",
12130 #endif
12131 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
12132 ".save FILE Write in-memory database into FILE",
12133 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
12134 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
12135 " Options:",
@@ -11539,11 +12410,11 @@
12410 int pgsz = 0;
12411 int iOffset = 0;
12412 int j, k;
12413 int rc;
12414 FILE *in;
12415 unsigned int x[16];
12416 char zLine[1000];
12417 if( p->zDbFilename ){
12418 in = fopen(p->zDbFilename, "r");
12419 if( in==0 ){
12420 utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
@@ -11551,18 +12422,19 @@
12422 }
12423 nLine = 0;
12424 }else{
12425 in = p->in;
12426 nLine = p->lineno;
12427 if( in==0 ) in = stdin;
12428 }
12429 *pnData = 0;
12430 nLine++;
12431 if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
12432 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
12433 if( rc!=2 ) goto readHexDb_error;
12434 if( n<0 ) goto readHexDb_error;
12435 a = sqlite3_malloc( n ? n : 1 );
12436 if( a==0 ){
12437 utf8_printf(stderr, "Out of memory!\n");
12438 goto readHexDb_error;
12439 }
12440 memset(a, 0, n);
@@ -11577,18 +12449,18 @@
12449 continue;
12450 }
12451 if( strncmp(zLine, "| end ", 6)==0 ){
12452 break;
12453 }
12454 rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
 
12455 &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
12456 &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
12457 if( rc==17 ){
12458 k = iOffset+j;
12459 if( k+16<=n ){
12460 int ii;
12461 for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
12462 }
12463 }
12464 }
12465 *pnData = n;
12466 if( in!=p->in ){
@@ -11597,11 +12469,11 @@
12469 p->lineno = nLine;
12470 }
12471 return a;
12472
12473 readHexDb_error:
12474 if( in!=p->in ){
12475 fclose(in);
12476 }else{
12477 while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
12478 nLine++;
12479 if(strncmp(zLine, "| end ", 6)==0 ) break;
@@ -11611,10 +12483,131 @@
12483 sqlite3_free(a);
12484 utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
12485 return 0;
12486 }
12487 #endif /* SQLITE_ENABLE_DESERIALIZE */
12488
12489 /*
12490 ** Scalar function "shell_int32". The first argument to this function
12491 ** must be a blob. The second a non-negative integer. This function
12492 ** reads and returns a 32-bit big-endian integer from byte
12493 ** offset (4*<arg2>) of the blob.
12494 */
12495 static void shellInt32(
12496 sqlite3_context *context,
12497 int argc,
12498 sqlite3_value **argv
12499 ){
12500 const unsigned char *pBlob;
12501 int nBlob;
12502 int iInt;
12503
12504 UNUSED_PARAMETER(argc);
12505 nBlob = sqlite3_value_bytes(argv[0]);
12506 pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
12507 iInt = sqlite3_value_int(argv[1]);
12508
12509 if( iInt>=0 && (iInt+1)*4<=nBlob ){
12510 const unsigned char *a = &pBlob[iInt*4];
12511 sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
12512 + ((sqlite3_int64)a[1]<<16)
12513 + ((sqlite3_int64)a[2]<< 8)
12514 + ((sqlite3_int64)a[3]<< 0);
12515 sqlite3_result_int64(context, iVal);
12516 }
12517 }
12518
12519 /*
12520 ** Scalar function "shell_escape_crnl" used by the .recover command.
12521 ** The argument passed to this function is the output of built-in
12522 ** function quote(). If the first character of the input is "'",
12523 ** indicating that the value passed to quote() was a text value,
12524 ** then this function searches the input for "\n" and "\r" characters
12525 ** and adds a wrapper similar to the following:
12526 **
12527 ** replace(replace(<input>, '\n', char(10), '\r', char(13));
12528 **
12529 ** Or, if the first character of the input is not "'", then a copy
12530 ** of the input is returned.
12531 */
12532 static void shellEscapeCrnl(
12533 sqlite3_context *context,
12534 int argc,
12535 sqlite3_value **argv
12536 ){
12537 const char *zText = (const char*)sqlite3_value_text(argv[0]);
12538 UNUSED_PARAMETER(argc);
12539 if( zText[0]=='\'' ){
12540 int nText = sqlite3_value_bytes(argv[0]);
12541 int i;
12542 char zBuf1[20];
12543 char zBuf2[20];
12544 const char *zNL = 0;
12545 const char *zCR = 0;
12546 int nCR = 0;
12547 int nNL = 0;
12548
12549 for(i=0; zText[i]; i++){
12550 if( zNL==0 && zText[i]=='\n' ){
12551 zNL = unused_string(zText, "\\n", "\\012", zBuf1);
12552 nNL = (int)strlen(zNL);
12553 }
12554 if( zCR==0 && zText[i]=='\r' ){
12555 zCR = unused_string(zText, "\\r", "\\015", zBuf2);
12556 nCR = (int)strlen(zCR);
12557 }
12558 }
12559
12560 if( zNL || zCR ){
12561 int iOut = 0;
12562 i64 nMax = (nNL > nCR) ? nNL : nCR;
12563 i64 nAlloc = nMax * nText + (nMax+64)*2;
12564 char *zOut = (char*)sqlite3_malloc64(nAlloc);
12565 if( zOut==0 ){
12566 sqlite3_result_error_nomem(context);
12567 return;
12568 }
12569
12570 if( zNL && zCR ){
12571 memcpy(&zOut[iOut], "replace(replace(", 16);
12572 iOut += 16;
12573 }else{
12574 memcpy(&zOut[iOut], "replace(", 8);
12575 iOut += 8;
12576 }
12577 for(i=0; zText[i]; i++){
12578 if( zText[i]=='\n' ){
12579 memcpy(&zOut[iOut], zNL, nNL);
12580 iOut += nNL;
12581 }else if( zText[i]=='\r' ){
12582 memcpy(&zOut[iOut], zCR, nCR);
12583 iOut += nCR;
12584 }else{
12585 zOut[iOut] = zText[i];
12586 iOut++;
12587 }
12588 }
12589
12590 if( zNL ){
12591 memcpy(&zOut[iOut], ",'", 2); iOut += 2;
12592 memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
12593 memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
12594 }
12595 if( zCR ){
12596 memcpy(&zOut[iOut], ",'", 2); iOut += 2;
12597 memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
12598 memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
12599 }
12600
12601 sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
12602 sqlite3_free(zOut);
12603 return;
12604 }
12605 }
12606
12607 sqlite3_result_value(context, argv[0]);
12608 }
12609
12610 /* Flags for open_db().
12611 **
12612 ** The default behavior of open_db() is to exit(1) if the database fails to
12613 ** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
@@ -11680,10 +12673,13 @@
12673 sqlite3_enable_load_extension(p->db, 1);
12674 #endif
12675 sqlite3_fileio_init(p->db, 0, 0);
12676 sqlite3_shathree_init(p->db, 0, 0);
12677 sqlite3_completion_init(p->db, 0, 0);
12678 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
12679 sqlite3_dbdata_init(p->db, 0, 0);
12680 #endif
12681 #ifdef SQLITE_HAVE_ZLIB
12682 sqlite3_zipfile_init(p->db, 0, 0);
12683 sqlite3_sqlar_init(p->db, 0, 0);
12684 #endif
12685 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
@@ -11690,10 +12686,14 @@
12686 shellAddSchemaName, 0, 0);
12687 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
12688 shellModuleSchema, 0, 0);
12689 sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
12690 shellPutsFunc, 0, 0);
12691 sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
12692 shellEscapeCrnl, 0, 0);
12693 sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
12694 shellInt32, 0, 0);
12695 #ifndef SQLITE_NOHAVE_SYSTEM
12696 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
12697 editFunc, 0, 0);
12698 sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
12699 editFunc, 0, 0);
@@ -11713,11 +12713,10 @@
12713 if( p->openMode==SHELL_OPEN_DESERIALIZE ){
12714 aData = (unsigned char*)readFile(p->zDbFilename, &nData);
12715 }else{
12716 aData = readHexDb(p, &nData);
12717 if( aData==0 ){
 
12718 return;
12719 }
12720 }
12721 rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
12722 SQLITE_DESERIALIZE_RESIZEABLE |
@@ -12944,14 +13943,11 @@
13943 raw_printf(stderr, "Where sub-commands are:\n");
13944 raw_printf(stderr, " fkey-indexes\n");
13945 return SQLITE_ERROR;
13946 }
13947
13948 #if !defined SQLITE_OMIT_VIRTUALTABLE
 
 
 
13949 static void shellPrepare(
13950 sqlite3 *db,
13951 int *pRc,
13952 const char *zSql,
13953 sqlite3_stmt **ppStmt
@@ -12966,11 +13962,18 @@
13962 *pRc = rc;
13963 }
13964 }
13965 }
13966
13967 /*
13968 ** Create a prepared statement using printf-style arguments for the SQL.
13969 **
13970 ** This routine is could be marked "static". But it is not always used,
13971 ** depending on compile-time options. By omitting the "static", we avoid
13972 ** nuisance compiler warnings about "defined but not used".
13973 */
13974 void shellPreparePrintf(
13975 sqlite3 *db,
13976 int *pRc,
13977 sqlite3_stmt **ppStmt,
13978 const char *zFmt,
13979 ...
@@ -12989,11 +13992,17 @@
13992 sqlite3_free(z);
13993 }
13994 }
13995 }
13996
13997 /* Finalize the prepared statement created using shellPreparePrintf().
13998 **
13999 ** This routine is could be marked "static". But it is not always used,
14000 ** depending on compile-time options. By omitting the "static", we avoid
14001 ** nuisance compiler warnings about "defined but not used".
14002 */
14003 void shellFinalize(
14004 int *pRc,
14005 sqlite3_stmt *pStmt
14006 ){
14007 if( pStmt ){
14008 sqlite3 *db = sqlite3_db_handle(pStmt);
@@ -13005,11 +14014,17 @@
14014 *pRc = rc;
14015 }
14016 }
14017 }
14018
14019 /* Reset the prepared statement created using shellPreparePrintf().
14020 **
14021 ** This routine is could be marked "static". But it is not always used,
14022 ** depending on compile-time options. By omitting the "static", we avoid
14023 ** nuisance compiler warnings about "defined but not used".
14024 */
14025 void shellReset(
14026 int *pRc,
14027 sqlite3_stmt *pStmt
14028 ){
14029 int rc = sqlite3_reset(pStmt);
14030 if( *pRc==SQLITE_OK ){
@@ -13018,10 +14033,16 @@
14033 raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
14034 }
14035 *pRc = rc;
14036 }
14037 }
14038 #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
14039
14040 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
14041 /*********************************************************************************
14042 ** The ".archive" or ".ar" command.
14043 */
14044 /*
14045 ** Structure representing a single ".ar" command.
14046 */
14047 typedef struct ArCommand ArCommand;
14048 struct ArCommand {
@@ -13707,10 +14728,639 @@
14728 }
14729 /* End of the ".archive" or ".ar" command logic
14730 **********************************************************************************/
14731 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
14732
14733 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
14734 /*
14735 ** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op.
14736 ** Otherwise, the SQL statement or statements in zSql are executed using
14737 ** database connection db and the error code written to *pRc before
14738 ** this function returns.
14739 */
14740 static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
14741 int rc = *pRc;
14742 if( rc==SQLITE_OK ){
14743 char *zErr = 0;
14744 rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
14745 if( rc!=SQLITE_OK ){
14746 raw_printf(stderr, "SQL error: %s\n", zErr);
14747 }
14748 *pRc = rc;
14749 }
14750 }
14751
14752 /*
14753 ** Like shellExec(), except that zFmt is a printf() style format string.
14754 */
14755 static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){
14756 char *z = 0;
14757 if( *pRc==SQLITE_OK ){
14758 va_list ap;
14759 va_start(ap, zFmt);
14760 z = sqlite3_vmprintf(zFmt, ap);
14761 va_end(ap);
14762 if( z==0 ){
14763 *pRc = SQLITE_NOMEM;
14764 }else{
14765 shellExec(db, pRc, z);
14766 }
14767 sqlite3_free(z);
14768 }
14769 }
14770
14771 /*
14772 ** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
14773 ** Otherwise, an attempt is made to allocate, zero and return a pointer
14774 ** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set
14775 ** to SQLITE_NOMEM and NULL returned.
14776 */
14777 static void *shellMalloc(int *pRc, sqlite3_int64 nByte){
14778 void *pRet = 0;
14779 if( *pRc==SQLITE_OK ){
14780 pRet = sqlite3_malloc64(nByte);
14781 if( pRet==0 ){
14782 *pRc = SQLITE_NOMEM;
14783 }else{
14784 memset(pRet, 0, nByte);
14785 }
14786 }
14787 return pRet;
14788 }
14789
14790 /*
14791 ** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
14792 ** Otherwise, zFmt is treated as a printf() style string. The result of
14793 ** formatting it along with any trailing arguments is written into a
14794 ** buffer obtained from sqlite3_malloc(), and pointer to which is returned.
14795 ** It is the responsibility of the caller to eventually free this buffer
14796 ** using a call to sqlite3_free().
14797 **
14798 ** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL
14799 ** pointer returned.
14800 */
14801 static char *shellMPrintf(int *pRc, const char *zFmt, ...){
14802 char *z = 0;
14803 if( *pRc==SQLITE_OK ){
14804 va_list ap;
14805 va_start(ap, zFmt);
14806 z = sqlite3_vmprintf(zFmt, ap);
14807 va_end(ap);
14808 if( z==0 ){
14809 *pRc = SQLITE_NOMEM;
14810 }
14811 }
14812 return z;
14813 }
14814
14815 /*
14816 ** When running the ".recover" command, each output table, and the special
14817 ** orphaned row table if it is required, is represented by an instance
14818 ** of the following struct.
14819 */
14820 typedef struct RecoverTable RecoverTable;
14821 struct RecoverTable {
14822 char *zQuoted; /* Quoted version of table name */
14823 int nCol; /* Number of columns in table */
14824 char **azlCol; /* Array of column lists */
14825 int iPk; /* Index of IPK column */
14826 };
14827
14828 /*
14829 ** Free a RecoverTable object allocated by recoverFindTable() or
14830 ** recoverOrphanTable().
14831 */
14832 static void recoverFreeTable(RecoverTable *pTab){
14833 if( pTab ){
14834 sqlite3_free(pTab->zQuoted);
14835 if( pTab->azlCol ){
14836 int i;
14837 for(i=0; i<=pTab->nCol; i++){
14838 sqlite3_free(pTab->azlCol[i]);
14839 }
14840 sqlite3_free(pTab->azlCol);
14841 }
14842 sqlite3_free(pTab);
14843 }
14844 }
14845
14846 /*
14847 ** This function is a no-op if (*pRc) is not SQLITE_OK when it is called.
14848 ** Otherwise, it allocates and returns a RecoverTable object based on the
14849 ** final four arguments passed to this function. It is the responsibility
14850 ** of the caller to eventually free the returned object using
14851 ** recoverFreeTable().
14852 */
14853 static RecoverTable *recoverNewTable(
14854 int *pRc, /* IN/OUT: Error code */
14855 const char *zName, /* Name of table */
14856 const char *zSql, /* CREATE TABLE statement */
14857 int bIntkey,
14858 int nCol
14859 ){
14860 sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */
14861 int rc = *pRc;
14862 RecoverTable *pTab = 0;
14863
14864 pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable));
14865 if( rc==SQLITE_OK ){
14866 int nSqlCol = 0;
14867 int bSqlIntkey = 0;
14868 sqlite3_stmt *pStmt = 0;
14869
14870 rc = sqlite3_open("", &dbtmp);
14871 if( rc==SQLITE_OK ){
14872 rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
14873 }
14874 if( rc==SQLITE_OK ){
14875 rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0);
14876 if( rc==SQLITE_ERROR ){
14877 rc = SQLITE_OK;
14878 goto finished;
14879 }
14880 }
14881 shellPreparePrintf(dbtmp, &rc, &pStmt,
14882 "SELECT count(*) FROM pragma_table_info(%Q)", zName
14883 );
14884 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
14885 nSqlCol = sqlite3_column_int(pStmt, 0);
14886 }
14887 shellFinalize(&rc, pStmt);
14888
14889 if( rc!=SQLITE_OK || nSqlCol<nCol ){
14890 goto finished;
14891 }
14892
14893 shellPreparePrintf(dbtmp, &rc, &pStmt,
14894 "SELECT ("
14895 " SELECT substr(data,1,1)==X'0D' FROM sqlite_dbpage WHERE pgno=rootpage"
14896 ") FROM sqlite_master WHERE name = %Q", zName
14897 );
14898 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
14899 bSqlIntkey = sqlite3_column_int(pStmt, 0);
14900 }
14901 shellFinalize(&rc, pStmt);
14902
14903 if( bIntkey==bSqlIntkey ){
14904 int i;
14905 const char *zPk = "_rowid_";
14906 sqlite3_stmt *pPkFinder = 0;
14907
14908 /* If this is an intkey table and there is an INTEGER PRIMARY KEY,
14909 ** set zPk to the name of the PK column, and pTab->iPk to the index
14910 ** of the column, where columns are 0-numbered from left to right.
14911 ** Or, if this is a WITHOUT ROWID table or if there is no IPK column,
14912 ** leave zPk as "_rowid_" and pTab->iPk at -2. */
14913 pTab->iPk = -2;
14914 if( bIntkey ){
14915 shellPreparePrintf(dbtmp, &rc, &pPkFinder,
14916 "SELECT cid, name FROM pragma_table_info(%Q) "
14917 " WHERE pk=1 AND type='integer' COLLATE nocase"
14918 " AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)"
14919 , zName, zName
14920 );
14921 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){
14922 pTab->iPk = sqlite3_column_int(pPkFinder, 0);
14923 zPk = (const char*)sqlite3_column_text(pPkFinder, 1);
14924 }
14925 }
14926
14927 pTab->zQuoted = shellMPrintf(&rc, "%Q", zName);
14928 pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
14929 pTab->nCol = nSqlCol;
14930
14931 if( bIntkey ){
14932 pTab->azlCol[0] = shellMPrintf(&rc, "%Q", zPk);
14933 }else{
14934 pTab->azlCol[0] = shellMPrintf(&rc, "");
14935 }
14936 i = 1;
14937 shellPreparePrintf(dbtmp, &rc, &pStmt,
14938 "SELECT %Q || group_concat(name, ', ') "
14939 " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
14940 "FROM pragma_table_info(%Q)",
14941 bIntkey ? ", " : "", pTab->iPk,
14942 bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ",
14943 zName
14944 );
14945 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
14946 const char *zText = (const char*)sqlite3_column_text(pStmt, 0);
14947 pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText);
14948 i++;
14949 }
14950 shellFinalize(&rc, pStmt);
14951
14952 shellFinalize(&rc, pPkFinder);
14953 }
14954 }
14955
14956 finished:
14957 sqlite3_close(dbtmp);
14958 *pRc = rc;
14959 if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
14960 recoverFreeTable(pTab);
14961 pTab = 0;
14962 }
14963 return pTab;
14964 }
14965
14966 /*
14967 ** This function is called to search the schema recovered from the
14968 ** sqlite_master table of the (possibly) corrupt database as part
14969 ** of a ".recover" command. Specifically, for a table with root page
14970 ** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the
14971 ** table must be a WITHOUT ROWID table, or if non-zero, not one of
14972 ** those.
14973 **
14974 ** If a table is found, a (RecoverTable*) object is returned. Or, if
14975 ** no such table is found, but bIntkey is false and iRoot is the
14976 ** root page of an index in the recovered schema, then (*pbNoop) is
14977 ** set to true and NULL returned. Or, if there is no such table or
14978 ** index, NULL is returned and (*pbNoop) set to 0, indicating that
14979 ** the caller should write data to the orphans table.
14980 */
14981 static RecoverTable *recoverFindTable(
14982 ShellState *pState, /* Shell state object */
14983 int *pRc, /* IN/OUT: Error code */
14984 int iRoot, /* Root page of table */
14985 int bIntkey, /* True for an intkey table */
14986 int nCol, /* Number of columns in table */
14987 int *pbNoop /* OUT: True if iRoot is root of index */
14988 ){
14989 sqlite3_stmt *pStmt = 0;
14990 RecoverTable *pRet = 0;
14991 int bNoop = 0;
14992 const char *zSql = 0;
14993 const char *zName = 0;
14994
14995 /* Search the recovered schema for an object with root page iRoot. */
14996 shellPreparePrintf(pState->db, pRc, &pStmt,
14997 "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot
14998 );
14999 while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
15000 const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
15001 if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){
15002 bNoop = 1;
15003 break;
15004 }
15005 if( sqlite3_stricmp(zType, "table")==0 ){
15006 zName = (const char*)sqlite3_column_text(pStmt, 1);
15007 zSql = (const char*)sqlite3_column_text(pStmt, 2);
15008 pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol);
15009 break;
15010 }
15011 }
15012
15013 shellFinalize(pRc, pStmt);
15014 *pbNoop = bNoop;
15015 return pRet;
15016 }
15017
15018 /*
15019 ** Return a RecoverTable object representing the orphans table.
15020 */
15021 static RecoverTable *recoverOrphanTable(
15022 ShellState *pState, /* Shell state object */
15023 int *pRc, /* IN/OUT: Error code */
15024 const char *zLostAndFound, /* Base name for orphans table */
15025 int nCol /* Number of user data columns */
15026 ){
15027 RecoverTable *pTab = 0;
15028 if( nCol>=0 && *pRc==SQLITE_OK ){
15029 int i;
15030
15031 /* This block determines the name of the orphan table. The prefered
15032 ** name is zLostAndFound. But if that clashes with another name
15033 ** in the recovered schema, try zLostAndFound_0, zLostAndFound_1
15034 ** and so on until a non-clashing name is found. */
15035 int iTab = 0;
15036 char *zTab = shellMPrintf(pRc, "%s", zLostAndFound);
15037 sqlite3_stmt *pTest = 0;
15038 shellPrepare(pState->db, pRc,
15039 "SELECT 1 FROM recovery.schema WHERE name=?", &pTest
15040 );
15041 if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
15042 while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){
15043 shellReset(pRc, pTest);
15044 sqlite3_free(zTab);
15045 zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++);
15046 sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
15047 }
15048 shellFinalize(pRc, pTest);
15049
15050 pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
15051 if( pTab ){
15052 pTab->zQuoted = shellMPrintf(pRc, "%Q", zTab);
15053 pTab->nCol = nCol;
15054 pTab->iPk = -2;
15055 if( nCol>0 ){
15056 pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1));
15057 if( pTab->azlCol ){
15058 pTab->azlCol[nCol] = shellMPrintf(pRc, "");
15059 for(i=nCol-1; i>=0; i--){
15060 pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]);
15061 }
15062 }
15063 }
15064
15065 if( *pRc!=SQLITE_OK ){
15066 recoverFreeTable(pTab);
15067 pTab = 0;
15068 }else{
15069 raw_printf(pState->out,
15070 "CREATE TABLE %s(rootpgno INTEGER, "
15071 "pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted
15072 );
15073 for(i=0; i<nCol; i++){
15074 raw_printf(pState->out, ", c%d", i);
15075 }
15076 raw_printf(pState->out, ");\n");
15077 }
15078 }
15079 sqlite3_free(zTab);
15080 }
15081 return pTab;
15082 }
15083
15084 /*
15085 ** This function is called to recover data from the database. A script
15086 ** to construct a new database containing all recovered data is output
15087 ** on stream pState->out.
15088 */
15089 static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
15090 int rc = SQLITE_OK;
15091 sqlite3_stmt *pLoop = 0; /* Loop through all root pages */
15092 sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */
15093 sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */
15094 const char *zRecoveryDb = ""; /* Name of "recovery" database */
15095 const char *zLostAndFound = "lost_and_found";
15096 int i;
15097 int nOrphan = -1;
15098 RecoverTable *pOrphan = 0;
15099
15100 int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
15101 for(i=1; i<nArg; i++){
15102 char *z = azArg[i];
15103 int n;
15104 if( z[0]=='-' && z[1]=='-' ) z++;
15105 n = strlen(z);
15106 if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
15107 bFreelist = 0;
15108 }else
15109 if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
15110 i++;
15111 zRecoveryDb = azArg[i];
15112 }else
15113 if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
15114 i++;
15115 zLostAndFound = azArg[i];
15116 }
15117 else{
15118 raw_printf(stderr, "unexpected option: %s\n", azArg[i]);
15119 raw_printf(stderr, "options are:\n");
15120 raw_printf(stderr, " --freelist-corrupt\n");
15121 raw_printf(stderr, " --recovery-db DATABASE\n");
15122 raw_printf(stderr, " --lost-and-found TABLE-NAME\n");
15123 return 1;
15124 }
15125 }
15126
15127 shellExecPrintf(pState->db, &rc,
15128 /* Attach an in-memory database named 'recovery'. Create an indexed
15129 ** cache of the sqlite_dbptr virtual table. */
15130 "ATTACH %Q AS recovery;"
15131 "DROP TABLE IF EXISTS recovery.dbptr;"
15132 "DROP TABLE IF EXISTS recovery.freelist;"
15133 "DROP TABLE IF EXISTS recovery.map;"
15134 "DROP TABLE IF EXISTS recovery.schema;"
15135 "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
15136 );
15137
15138 if( bFreelist ){
15139 shellExec(pState->db, &rc,
15140 "WITH trunk(pgno) AS ("
15141 " SELECT shell_int32("
15142 " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
15143 " WHERE x>0"
15144 " UNION"
15145 " SELECT shell_int32("
15146 " (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
15147 " FROM trunk WHERE x>0"
15148 "),"
15149 "freelist(data, n, freepgno) AS ("
15150 " SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
15151 " FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
15152 " UNION ALL"
15153 " SELECT data, n-1, shell_int32(data, 2+n) "
15154 " FROM freelist WHERE n>=0"
15155 ")"
15156 "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
15157 );
15158 }
15159
15160 shellExec(pState->db, &rc,
15161 "CREATE TABLE recovery.dbptr("
15162 " pgno, child, PRIMARY KEY(child, pgno)"
15163 ") WITHOUT ROWID;"
15164 "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
15165 " SELECT * FROM sqlite_dbptr"
15166 " WHERE pgno NOT IN freelist AND child NOT IN freelist;"
15167
15168 /* Delete any pointer to page 1. This ensures that page 1 is considered
15169 ** a root page, regardless of how corrupt the db is. */
15170 "DELETE FROM recovery.dbptr WHERE child = 1;"
15171
15172 /* Delete all pointers to any pages that have more than one pointer
15173 ** to them. Such pages will be treated as root pages when recovering
15174 ** data. */
15175 "DELETE FROM recovery.dbptr WHERE child IN ("
15176 " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
15177 ");"
15178
15179 /* Create the "map" table that will (eventually) contain instructions
15180 ** for dealing with each page in the db that contains one or more
15181 ** records. */
15182 "CREATE TABLE recovery.map("
15183 "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
15184 ");"
15185
15186 /* Populate table [map]. If there are circular loops of pages in the
15187 ** database, the following adds all pages in such a loop to the map
15188 ** as individual root pages. This could be handled better. */
15189 "WITH pages(i, maxlen) AS ("
15190 " SELECT page_count, ("
15191 " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
15192 " ) FROM pragma_page_count WHERE page_count>0"
15193 " UNION ALL"
15194 " SELECT i-1, ("
15195 " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
15196 " ) FROM pages WHERE i>=2"
15197 ")"
15198 "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
15199 " SELECT i, maxlen, NULL, ("
15200 " WITH p(orig, pgno, parent) AS ("
15201 " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
15202 " UNION "
15203 " SELECT i, p.parent, "
15204 " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
15205 " )"
15206 " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
15207 ") "
15208 "FROM pages WHERE maxlen > 0 AND i NOT IN freelist;"
15209 "UPDATE recovery.map AS o SET intkey = ("
15210 " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
15211 ");"
15212
15213 /* Extract data from page 1 and any linked pages into table
15214 ** recovery.schema. With the same schema as an sqlite_master table. */
15215 "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
15216 "INSERT INTO recovery.schema SELECT "
15217 " max(CASE WHEN field=0 THEN value ELSE NULL END),"
15218 " max(CASE WHEN field=1 THEN value ELSE NULL END),"
15219 " max(CASE WHEN field=2 THEN value ELSE NULL END),"
15220 " max(CASE WHEN field=3 THEN value ELSE NULL END),"
15221 " max(CASE WHEN field=4 THEN value ELSE NULL END)"
15222 "FROM sqlite_dbdata WHERE pgno IN ("
15223 " SELECT pgno FROM recovery.map WHERE root=1"
15224 ")"
15225 "GROUP BY pgno, cell;"
15226 "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
15227 );
15228
15229 /* Open a transaction, then print out all non-virtual, non-"sqlite_%"
15230 ** CREATE TABLE statements that extracted from the existing schema. */
15231 if( rc==SQLITE_OK ){
15232 sqlite3_stmt *pStmt = 0;
15233 raw_printf(pState->out, "BEGIN;\n");
15234 raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
15235 shellPrepare(pState->db, &rc,
15236 "SELECT sql FROM recovery.schema "
15237 "WHERE type='table' AND sql LIKE 'create table%'", &pStmt
15238 );
15239 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
15240 const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
15241 raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n",
15242 &zCreateTable[12]
15243 );
15244 }
15245 shellFinalize(&rc, pStmt);
15246 }
15247
15248 /* Figure out if an orphan table will be required. And if so, how many
15249 ** user columns it should contain */
15250 shellPrepare(pState->db, &rc,
15251 "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
15252 , &pLoop
15253 );
15254 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
15255 nOrphan = sqlite3_column_int(pLoop, 0);
15256 }
15257 shellFinalize(&rc, pLoop);
15258 pLoop = 0;
15259
15260 shellPrepare(pState->db, &rc,
15261 "SELECT pgno FROM recovery.map WHERE root=?", &pPages
15262 );
15263 shellPrepare(pState->db, &rc,
15264 "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
15265 "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
15266 "GROUP BY cell", &pCells
15267 );
15268
15269 /* Loop through each root page. */
15270 shellPrepare(pState->db, &rc,
15271 "SELECT root, intkey, max(maxlen) FROM recovery.map"
15272 " WHERE root>1 GROUP BY root, intkey ORDER BY root=("
15273 " SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
15274 ")", &pLoop
15275 );
15276 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
15277 int iRoot = sqlite3_column_int(pLoop, 0);
15278 int bIntkey = sqlite3_column_int(pLoop, 1);
15279 int nCol = sqlite3_column_int(pLoop, 2);
15280 int bNoop = 0;
15281 RecoverTable *pTab;
15282
15283 pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
15284 if( bNoop || rc ) continue;
15285 if( pTab==0 ){
15286 if( pOrphan==0 ){
15287 pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
15288 }
15289 pTab = pOrphan;
15290 if( pTab==0 ) break;
15291 }
15292
15293 if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){
15294 raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
15295 }
15296 sqlite3_bind_int(pPages, 1, iRoot);
15297 sqlite3_bind_int(pCells, 2, pTab->iPk);
15298
15299 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
15300 int iPgno = sqlite3_column_int(pPages, 0);
15301 sqlite3_bind_int(pCells, 1, iPgno);
15302 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
15303 int nField = sqlite3_column_int(pCells, 0);
15304 const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
15305
15306 nField = nField+1;
15307 if( pTab==pOrphan ){
15308 raw_printf(pState->out,
15309 "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
15310 pTab->zQuoted, iRoot, iPgno, nField,
15311 bIntkey ? "" : "NULL, ", zVal, pTab->azlCol[nField]
15312 );
15313 }else{
15314 raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
15315 pTab->zQuoted, pTab->azlCol[nField], zVal
15316 );
15317 }
15318 }
15319 shellReset(&rc, pCells);
15320 }
15321 shellReset(&rc, pPages);
15322 if( pTab!=pOrphan ) recoverFreeTable(pTab);
15323 }
15324 shellFinalize(&rc, pLoop);
15325 shellFinalize(&rc, pPages);
15326 shellFinalize(&rc, pCells);
15327 recoverFreeTable(pOrphan);
15328
15329 /* The rest of the schema */
15330 if( rc==SQLITE_OK ){
15331 sqlite3_stmt *pStmt = 0;
15332 shellPrepare(pState->db, &rc,
15333 "SELECT sql, name FROM recovery.schema "
15334 "WHERE sql NOT LIKE 'create table%'", &pStmt
15335 );
15336 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
15337 const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
15338 if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
15339 const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
15340 char *zPrint = shellMPrintf(&rc,
15341 "INSERT INTO sqlite_master VALUES('table', %Q, %Q, 0, %Q)",
15342 zName, zName, zSql
15343 );
15344 raw_printf(pState->out, "%s;\n", zPrint);
15345 sqlite3_free(zPrint);
15346 }else{
15347 raw_printf(pState->out, "%s;\n", zSql);
15348 }
15349 }
15350 shellFinalize(&rc, pStmt);
15351 }
15352
15353 if( rc==SQLITE_OK ){
15354 raw_printf(pState->out, "PRAGMA writable_schema = off;\n");
15355 raw_printf(pState->out, "COMMIT;\n");
15356 }
15357 sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
15358 return rc;
15359 }
15360 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
15361
15362
15363 /*
15364 ** If an input line begins with "." then invoke this routine to
15365 ** process that line.
15366 **
@@ -13994,10 +15644,17 @@
15644
15645 if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
15646 rc = shell_dbinfo_command(p, nArg, azArg);
15647 }else
15648
15649 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
15650 if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
15651 open_db(p, 0);
15652 rc = recoverDatabaseCmd(p, nArg, azArg);
15653 }else
15654 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
15655
15656 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
15657 const char *zLike = 0;
15658 int i;
15659 int savedShowHeader = p->showHeader;
15660 int savedShellFlags = p->shellFlgs;
@@ -14031,11 +15688,13 @@
15688 goto meta_command_exit;
15689 }else{
15690 zLike = azArg[i];
15691 }
15692 }
15693
15694 open_db(p, 0);
15695
15696 /* When playing back a "dump", the content might appear in an order
15697 ** which causes immediate foreign key constraints to be violated.
15698 ** So disable foreign-key constraint enforcement to prevent problems. */
15699 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
15700 raw_printf(p->out, "BEGIN TRANSACTION;\n");
@@ -14079,11 +15738,11 @@
15738 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
15739 p->writableSchema = 0;
15740 }
15741 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
15742 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
15743 raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
15744 p->showHeader = savedShowHeader;
15745 p->shellFlgs = savedShellFlags;
15746 }else
15747
15748 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
15749
+937 -378
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.28.0. By combining all the individual C code files into this
3
+** version 3.29.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -886,10 +886,15 @@
886886
#pragma warning(disable : 4306)
887887
#pragma warning(disable : 4702)
888888
#pragma warning(disable : 4706)
889889
#endif /* defined(_MSC_VER) */
890890
891
+#if defined(_MSC_VER) && !defined(_WIN64)
892
+#undef SQLITE_4_BYTE_ALIGNED_MALLOC
893
+#define SQLITE_4_BYTE_ALIGNED_MALLOC
894
+#endif /* defined(_MSC_VER) && !defined(_WIN64) */
895
+
891896
#endif /* SQLITE_MSVC_H */
892897
893898
/************** End of msvc.h ************************************************/
894899
/************** Continuing where we left off in sqliteInt.h ******************/
895900
@@ -1160,13 +1165,13 @@
11601165
**
11611166
** See also: [sqlite3_libversion()],
11621167
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
11631168
** [sqlite_version()] and [sqlite_source_id()].
11641169
*/
1165
-#define SQLITE_VERSION "3.28.0"
1166
-#define SQLITE_VERSION_NUMBER 3028000
1167
-#define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50"
1170
+#define SQLITE_VERSION "3.29.0"
1171
+#define SQLITE_VERSION_NUMBER 3029000
1172
+#define SQLITE_SOURCE_ID "2019-05-10 17:54:58 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000f2362"
11681173
11691174
/*
11701175
** CAPI3REF: Run-Time Library Version Numbers
11711176
** KEYWORDS: sqlite3_version sqlite3_sourceid
11721177
**
@@ -8356,11 +8361,12 @@
83568361
#define SQLITE_TESTCTRL_BYTEORDER 22
83578362
#define SQLITE_TESTCTRL_ISINIT 23
83588363
#define SQLITE_TESTCTRL_SORTER_MMAP 24
83598364
#define SQLITE_TESTCTRL_IMPOSTER 25
83608365
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
8361
-#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
8366
+#define SQLITE_TESTCTRL_RESULT_INTREAL 27
8367
+#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
83628368
83638369
/*
83648370
** CAPI3REF: SQL Keyword Checking
83658371
**
83668372
** These routines provide access to the set of SQL language keywords
@@ -17451,10 +17457,12 @@
1745117457
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
1745217458
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
1745317459
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
1745417460
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
1745517461
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
17462
+#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
17463
+#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
1745617464
1745717465
/*
1745817466
** The EP_Propagate mask is a set of properties that automatically propagate
1745917467
** upwards into parent nodes.
1746017468
*/
@@ -17466,10 +17474,12 @@
1746617474
*/
1746717475
#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
1746817476
#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
1746917477
#define ExprSetProperty(E,P) (E)->flags|=(P)
1747017478
#define ExprClearProperty(E,P) (E)->flags&=~(P)
17479
+#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
17480
+#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
1747117481
1747217482
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
1747317483
** and Accreditation only. It works like ExprSetProperty() during VVA
1747417484
** processes but is a no-op for delivery.
1747517485
*/
@@ -18775,11 +18785,12 @@
1877518785
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
1877618786
SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
1877718787
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
1877818788
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
1877918789
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
18780
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
18790
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
18791
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*);
1878118792
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
1878218793
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
1878318794
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
1878418795
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
1878518796
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
@@ -19188,10 +19199,13 @@
1918819199
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
1918919200
SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
1919019201
void(*)(void*));
1919119202
SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
1919219203
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
19204
+#ifndef SQLITE_UNTESTABLE
19205
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*);
19206
+#endif
1919319207
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
1919419208
#ifndef SQLITE_OMIT_UTF16
1919519209
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
1919619210
#endif
1919719211
SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
@@ -20178,16 +20192,16 @@
2017820192
#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
2017920193
#define MEM_Str 0x0002 /* Value is a string */
2018020194
#define MEM_Int 0x0004 /* Value is an integer */
2018120195
#define MEM_Real 0x0008 /* Value is a real number */
2018220196
#define MEM_Blob 0x0010 /* Value is a BLOB */
20183
-#define MEM_AffMask 0x001f /* Mask of affinity bits */
20184
-#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
20185
-/* Available 0x0040 */
20197
+#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
20198
+#define MEM_AffMask 0x003f /* Mask of affinity bits */
20199
+#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
2018620200
#define MEM_Undefined 0x0080 /* Value is undefined */
2018720201
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
20188
-#define MEM_TypeMask 0xc1df /* Mask of type bits */
20202
+#define MEM_TypeMask 0xc1bf /* Mask of type bits */
2018920203
2019020204
2019120205
/* Whenever Mem contains a valid string or blob representation, one of
2019220206
** the following flags must be set to determine the memory management
2019320207
** policy for Mem.z. The MEM_Term flag tells us whether or not the
@@ -30210,13 +30224,11 @@
3021030224
** strings, and stuff like that.
3021130225
**
3021230226
*/
3021330227
/* #include "sqliteInt.h" */
3021430228
/* #include <stdarg.h> */
30215
-#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
30216
-# include <math.h>
30217
-#endif
30229
+#include <math.h>
3021830230
3021930231
/*
3022030232
** Routine needed to support the testcase() macro.
3022130233
*/
3022230234
#ifdef SQLITE_COVERAGE_TEST
@@ -30515,16 +30527,22 @@
3051530527
}
3051630528
return sqlite3StrICmp(zLeft, zRight);
3051730529
}
3051830530
SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
3051930531
unsigned char *a, *b;
30520
- int c;
30532
+ int c, x;
3052130533
a = (unsigned char *)zLeft;
3052230534
b = (unsigned char *)zRight;
3052330535
for(;;){
30524
- c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
30525
- if( c || *a==0 ) break;
30536
+ c = *a;
30537
+ x = *b;
30538
+ if( c==x ){
30539
+ if( c==0 ) break;
30540
+ }else{
30541
+ c = (int)UpperToLower[c] - (int)UpperToLower[x];
30542
+ if( c ) break;
30543
+ }
3052630544
a++;
3052730545
b++;
3052830546
}
3052930547
return c;
3053030548
}
@@ -31105,36 +31123,26 @@
3110531123
** Return the number of bytes read. The value is stored in *v.
3110631124
*/
3110731125
SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
3110831126
u32 a,b,s;
3110931127
31110
- a = *p;
31111
- /* a: p0 (unmasked) */
31112
- if (!(a&0x80))
31113
- {
31114
- *v = a;
31128
+ if( ((signed char*)p)[0]>=0 ){
31129
+ *v = *p;
3111531130
return 1;
3111631131
}
31117
-
31118
- p++;
31119
- b = *p;
31120
- /* b: p1 (unmasked) */
31121
- if (!(b&0x80))
31122
- {
31123
- a &= 0x7f;
31124
- a = a<<7;
31125
- a |= b;
31126
- *v = a;
31132
+ if( ((signed char*)p)[1]>=0 ){
31133
+ *v = ((u32)(p[0]&0x7f)<<7) | p[1];
3112731134
return 2;
3112831135
}
3112931136
3113031137
/* Verify that constants are precomputed correctly */
3113131138
assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
3113231139
assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
3113331140
31134
- p++;
31135
- a = a<<14;
31141
+ a = ((u32)p[0])<<14;
31142
+ b = p[1];
31143
+ p += 2;
3113631144
a |= *p;
3113731145
/* a: p0<<14 | p2 (unmasked) */
3113831146
if (!(a&0x80))
3113931147
{
3114031148
a &= SLOT_2_0;
@@ -61220,13 +61228,13 @@
6122061228
if( rc!=SQLITE_OK ){
6122161229
return rc;
6122261230
}
6122361231
nCollide = HASHTABLE_NSLOT;
6122461232
for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
61225
- u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
61226
- if( iFrame<=iLast && iFrame>=pWal->minFrame
61227
- && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
61233
+ u32 iH = sLoc.aHash[iKey];
61234
+ u32 iFrame = iH + sLoc.iZero;
61235
+ if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
6122861236
assert( iFrame>iRead || CORRUPT_DB );
6122961237
iRead = iFrame;
6123061238
}
6123161239
if( (nCollide--)==0 ){
6123261240
return SQLITE_CORRUPT_BKPT;
@@ -64814,11 +64822,11 @@
6481464822
** and the reserved space is zero (the usual value for reserved space)
6481564823
** then the cell content offset of an empty page wants to be 65536.
6481664824
** However, that integer is too large to be stored in a 2-byte unsigned
6481764825
** integer, so a value of 0 is used in its place. */
6481864826
top = get2byte(&data[hdr+5]);
64819
- assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
64827
+ assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
6482064828
if( gap>top ){
6482164829
if( top==0 && pPage->pBt->usableSize==65536 ){
6482264830
top = 65536;
6482364831
}else{
6482464832
return SQLITE_CORRUPT_PAGE(pPage);
@@ -65111,11 +65119,11 @@
6511165119
** the cell-content area. If this is greater than the usable-size
6511265120
** of the page, then the page must be corrupted. This check also
6511365121
** serves to verify that the offset to the start of the cell-content
6511465122
** area, according to the page header, lies within the page.
6511565123
*/
65116
- if( nFree>usableSize ){
65124
+ if( nFree>usableSize || nFree<iCellFirst ){
6511765125
return SQLITE_CORRUPT_PAGE(pPage);
6511865126
}
6511965127
pPage->nFree = (u16)(nFree - iCellFirst);
6512065128
return SQLITE_OK;
6512165129
}
@@ -67338,10 +67346,22 @@
6733867346
}
6733967347
sqlite3BtreeLeave(pBtree);
6734067348
}
6734167349
return rc;
6734267350
}
67351
+
67352
+/*
67353
+** Set the pBt->nPage field correctly, according to the current
67354
+** state of the database. Assume pBt->pPage1 is valid.
67355
+*/
67356
+static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
67357
+ int nPage = get4byte(&pPage1->aData[28]);
67358
+ testcase( nPage==0 );
67359
+ if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
67360
+ testcase( pBt->nPage!=nPage );
67361
+ pBt->nPage = nPage;
67362
+}
6734367363
6734467364
/*
6734567365
** Rollback the transaction in progress.
6734667366
**
6734767367
** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
@@ -67384,15 +67404,11 @@
6738467404
6738567405
/* The rollback may have destroyed the pPage1->aData value. So
6738667406
** call btreeGetPage() on page 1 again to make
6738767407
** sure pPage1->aData is set correctly. */
6738867408
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
67389
- int nPage = get4byte(28+(u8*)pPage1->aData);
67390
- testcase( nPage==0 );
67391
- if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
67392
- testcase( pBt->nPage!=nPage );
67393
- pBt->nPage = nPage;
67409
+ btreeSetNPage(pBt, pPage1);
6739467410
releasePageOne(pPage1);
6739567411
}
6739667412
assert( countValidCursors(pBt, 1)==0 );
6739767413
pBt->inTransaction = TRANS_READ;
6739867414
btreeClearHasContent(pBt);
@@ -67468,16 +67484,15 @@
6746867484
if( rc==SQLITE_OK ){
6746967485
if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
6747067486
pBt->nPage = 0;
6747167487
}
6747267488
rc = newDatabase(pBt);
67473
- pBt->nPage = get4byte(28 + pBt->pPage1->aData);
67489
+ btreeSetNPage(pBt, pBt->pPage1);
6747467490
67475
- /* The database size was written into the offset 28 of the header
67476
- ** when the transaction started, so we know that the value at offset
67477
- ** 28 is nonzero. */
67478
- assert( pBt->nPage>0 );
67491
+ /* pBt->nPage might be zero if the database was corrupt when
67492
+ ** the transaction was started. Otherwise, it must be at least 1. */
67493
+ assert( CORRUPT_DB || pBt->nPage>0 );
6747967494
}
6748067495
sqlite3BtreeLeave(p);
6748167496
}
6748267497
return rc;
6748367498
}
@@ -68481,10 +68496,11 @@
6848168496
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
6848268497
}
6848368498
assert( pCur->ix==pCur->pPage->nCell-1 );
6848468499
assert( pCur->pPage->leaf );
6848568500
#endif
68501
+ *pRes = 0;
6848668502
return SQLITE_OK;
6848768503
}
6848868504
6848968505
rc = moveToRoot(pCur);
6849068506
if( rc==SQLITE_OK ){
@@ -70823,10 +70839,11 @@
7082370839
int limit = pOld->nCell;
7082470840
u8 *aData = pOld->aData;
7082570841
u16 maskPage = pOld->maskPage;
7082670842
u8 *piCell = aData + pOld->cellOffset;
7082770843
u8 *piEnd;
70844
+ VVA_ONLY( int nCellAtStart = b.nCell; )
7082870845
7082970846
/* Verify that all sibling pages are of the same "type" (table-leaf,
7083070847
** table-interior, index-leaf, or index-interior).
7083170848
*/
7083270849
if( pOld->aData[0]!=apOld[0]->aData[0] ){
@@ -70851,10 +70868,14 @@
7085170868
** long be able to find the cells if a pointer to each cell is not saved
7085270869
** first.
7085370870
*/
7085470871
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
7085570872
if( pOld->nOverflow>0 ){
70873
+ if( limit<pOld->aiOvfl[0] ){
70874
+ rc = SQLITE_CORRUPT_BKPT;
70875
+ goto balance_cleanup;
70876
+ }
7085670877
limit = pOld->aiOvfl[0];
7085770878
for(j=0; j<limit; j++){
7085870879
b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
7085970880
piCell += 2;
7086070881
b.nCell++;
@@ -70870,10 +70891,11 @@
7087070891
assert( b.nCell<nMaxCells );
7087170892
b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
7087270893
piCell += 2;
7087370894
b.nCell++;
7087470895
}
70896
+ assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) );
7087570897
7087670898
cntOld[i] = b.nCell;
7087770899
if( i<nOld-1 && !leafData){
7087870900
u16 sz = (u16)szNew[i];
7087970901
u8 *pTemp;
@@ -71170,10 +71192,11 @@
7117071192
for(i=0; i<b.nCell; i++){
7117171193
u8 *pCell = b.apCell[i];
7117271194
while( i==cntOldNext ){
7117371195
iOld++;
7117471196
assert( iOld<nNew || iOld<nOld );
71197
+ assert( iOld>=0 && iOld<NB );
7117571198
pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
7117671199
cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
7117771200
}
7117871201
if( i==cntNew[iNew] ){
7117971202
pNew = apNew[++iNew];
@@ -73890,11 +73913,11 @@
7389073913
** then the backup cannot proceed.
7389173914
*/
7389273915
if( nSrcReserve!=nDestReserve ){
7389373916
u32 newPgsz = nSrcPgsz;
7389473917
rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
73895
- if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
73918
+ if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
7389673919
}
7389773920
#endif
7389873921
7389973922
/* This loop runs once for each destination page spanned by the source
7390073923
** page. For each iteration, variable iOff is set to the byte offset
@@ -74437,10 +74460,15 @@
7443774460
** name sqlite_value
7443874461
*/
7443974462
/* #include "sqliteInt.h" */
7444074463
/* #include "vdbeInt.h" */
7444174464
74465
+/* True if X is a power of two. 0 is considered a power of two here.
74466
+** In other words, return true if X has at most one bit set.
74467
+*/
74468
+#define ISPOWEROF2(X) (((X)&((X)-1))==0)
74469
+
7444274470
#ifdef SQLITE_DEBUG
7444374471
/*
7444474472
** Check invariants on a Mem object.
7444574473
**
7444674474
** This routine is intended for use inside of assert() statements, like
@@ -74456,12 +74484,12 @@
7445674484
** ensure that if Mem.szMalloc>0 then it is safe to do
7445774485
** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
7445874486
** That saves a few cycles in inner loops. */
7445974487
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
7446074488
74461
- /* Cannot be both MEM_Int and MEM_Real at the same time */
74462
- assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
74489
+ /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
74490
+ assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
7446374491
7446474492
if( p->flags & MEM_Null ){
7446574493
/* Cannot be both MEM_Null and some other type */
7446674494
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
7446774495
@@ -74510,10 +74538,29 @@
7451074538
);
7451174539
}
7451274540
return 1;
7451374541
}
7451474542
#endif
74543
+
74544
+/*
74545
+** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
74546
+** into a buffer.
74547
+*/
74548
+static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
74549
+ StrAccum acc;
74550
+ assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
74551
+ sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
74552
+ if( p->flags & MEM_Int ){
74553
+ sqlite3_str_appendf(&acc, "%lld", p->u.i);
74554
+ }else if( p->flags & MEM_IntReal ){
74555
+ sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
74556
+ }else{
74557
+ sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
74558
+ }
74559
+ assert( acc.zText==zBuf && acc.mxAlloc<=0 );
74560
+ zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
74561
+}
7451574562
7451674563
#ifdef SQLITE_DEBUG
7451774564
/*
7451874565
** Check that string value of pMem agrees with its integer or real value.
7451974566
**
@@ -74536,16 +74583,12 @@
7453674583
SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
7453774584
char zBuf[100];
7453874585
char *z;
7453974586
int i, j, incr;
7454074587
if( (p->flags & MEM_Str)==0 ) return 1;
74541
- if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
74542
- if( p->flags & MEM_Int ){
74543
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
74544
- }else{
74545
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
74546
- }
74588
+ if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
74589
+ vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
7454774590
z = p->z;
7454874591
i = j = 0;
7454974592
incr = 1;
7455074593
if( p->enc!=SQLITE_UTF8 ){
7455174594
incr = 2;
@@ -74653,12 +74696,12 @@
7465374696
** If pMem->zMalloc already meets or exceeds the requested size, this
7465474697
** routine is a no-op.
7465574698
**
7465674699
** Any prior string or blob content in the pMem object may be discarded.
7465774700
** The pMem->xDel destructor is called, if it exists. Though MEM_Str
74658
-** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
74659
-** values are preserved.
74701
+** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
74702
+** and MEM_Null values are preserved.
7466074703
**
7466174704
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
7466274705
** if unable to complete the resizing.
7466374706
*/
7466474707
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
@@ -74667,24 +74710,30 @@
7466774710
if( pMem->szMalloc<szNew ){
7466874711
return sqlite3VdbeMemGrow(pMem, szNew, 0);
7466974712
}
7467074713
assert( (pMem->flags & MEM_Dyn)==0 );
7467174714
pMem->z = pMem->zMalloc;
74672
- pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
74715
+ pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
7467374716
return SQLITE_OK;
7467474717
}
7467574718
7467674719
/*
7467774720
** It is already known that pMem contains an unterminated string.
7467874721
** Add the zero terminator.
74722
+**
74723
+** Three bytes of zero are added. In this way, there is guaranteed
74724
+** to be a double-zero byte at an even byte boundary in order to
74725
+** terminate a UTF16 string, even if the initial size of the buffer
74726
+** is an odd number of bytes.
7467974727
*/
7468074728
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
74681
- if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
74729
+ if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
7468274730
return SQLITE_NOMEM_BKPT;
7468374731
}
7468474732
pMem->z[pMem->n] = 0;
7468574733
pMem->z[pMem->n+1] = 0;
74734
+ pMem->z[pMem->n+2] = 0;
7468674735
pMem->flags |= MEM_Term;
7468774736
return SQLITE_OK;
7468874737
}
7468974738
7469074739
/*
@@ -74754,57 +74803,45 @@
7475474803
return vdbeMemAddTerminator(pMem);
7475574804
}
7475674805
}
7475774806
7475874807
/*
74759
-** Add MEM_Str to the set of representations for the given Mem. Numbers
74760
-** are converted using sqlite3_snprintf(). Converting a BLOB to a string
74761
-** is a no-op.
74808
+** Add MEM_Str to the set of representations for the given Mem. This
74809
+** routine is only called if pMem is a number of some kind, not a NULL
74810
+** or a BLOB.
7476274811
**
74763
-** Existing representations MEM_Int and MEM_Real are invalidated if
74764
-** bForce is true but are retained if bForce is false.
74812
+** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
74813
+** if bForce is true but are retained if bForce is false.
7476574814
**
7476674815
** A MEM_Null value will never be passed to this function. This function is
7476774816
** used for converting values to text for returning to the user (i.e. via
7476874817
** sqlite3_value_text()), or for ensuring that values to be used as btree
7476974818
** keys are strings. In the former case a NULL pointer is returned the
7477074819
** user and the latter is an internal programming error.
7477174820
*/
7477274821
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
74773
- int fg = pMem->flags;
7477474822
const int nByte = 32;
7477574823
7477674824
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
74777
- assert( !(fg&MEM_Zero) );
74778
- assert( !(fg&(MEM_Str|MEM_Blob)) );
74779
- assert( fg&(MEM_Int|MEM_Real) );
74825
+ assert( !(pMem->flags&MEM_Zero) );
74826
+ assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
74827
+ assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
7478074828
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7478174829
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7478274830
7478374831
7478474832
if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
7478574833
pMem->enc = 0;
7478674834
return SQLITE_NOMEM_BKPT;
7478774835
}
7478874836
74789
- /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
74790
- ** string representation of the value. Then, if the required encoding
74791
- ** is UTF-16le or UTF-16be do a translation.
74792
- **
74793
- ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
74794
- */
74795
- if( fg & MEM_Int ){
74796
- sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
74797
- }else{
74798
- assert( fg & MEM_Real );
74799
- sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
74800
- }
74837
+ vdbeMemRenderNum(nByte, pMem->z, pMem);
7480174838
assert( pMem->z!=0 );
7480274839
pMem->n = sqlite3Strlen30NN(pMem->z);
7480374840
pMem->enc = SQLITE_UTF8;
7480474841
pMem->flags |= MEM_Str|MEM_Term;
74805
- if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
74842
+ if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
7480674843
sqlite3VdbeChangeEncoding(pMem, enc);
7480774844
return SQLITE_OK;
7480874845
}
7480974846
7481074847
/*
@@ -74974,11 +75011,12 @@
7497475011
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
7497575012
int flags;
7497675013
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7497775014
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7497875015
flags = pMem->flags;
74979
- if( flags & MEM_Int ){
75016
+ if( flags & (MEM_Int|MEM_IntReal) ){
75017
+ testcase( flags & MEM_IntReal );
7498075018
return pMem->u.i;
7498175019
}else if( flags & MEM_Real ){
7498275020
return doubleToInt64(pMem->u.r);
7498375021
}else if( flags & (MEM_Str|MEM_Blob) ){
7498475022
assert( pMem->z || pMem->n==0 );
@@ -75003,11 +75041,12 @@
7500375041
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
7500475042
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7500575043
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7500675044
if( pMem->flags & MEM_Real ){
7500775045
return pMem->u.r;
75008
- }else if( pMem->flags & MEM_Int ){
75046
+ }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
75047
+ testcase( pMem->flags & MEM_IntReal );
7500975048
return (double)pMem->u.i;
7501075049
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
7501175050
return memRealValue(pMem);
7501275051
}else{
7501375052
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
@@ -75018,11 +75057,12 @@
7501875057
/*
7501975058
** Return 1 if pMem represents true, and return 0 if pMem represents false.
7502075059
** Return the value ifNull if pMem is NULL.
7502175060
*/
7502275061
SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
75023
- if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
75062
+ testcase( pMem->flags & MEM_IntReal );
75063
+ if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
7502475064
if( pMem->flags & MEM_Null ) return ifNull;
7502575065
return sqlite3VdbeRealValue(pMem)!=0.0;
7502675066
}
7502775067
7502875068
/*
@@ -75091,19 +75131,23 @@
7509175131
double r2 = (double)i;
7509275132
return memcmp(&r1, &r2, sizeof(r1))==0;
7509375133
}
7509475134
7509575135
/*
75096
-** Convert pMem so that it has types MEM_Real or MEM_Int or both.
75136
+** Convert pMem so that it has type MEM_Real or MEM_Int.
7509775137
** Invalidate any prior representations.
7509875138
**
7509975139
** Every effort is made to force the conversion, even if the input
7510075140
** is a string that does not look completely like a number. Convert
7510175141
** as much of the string as we can and ignore the rest.
7510275142
*/
7510375143
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
75104
- if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
75144
+ testcase( pMem->flags & MEM_Int );
75145
+ testcase( pMem->flags & MEM_Real );
75146
+ testcase( pMem->flags & MEM_IntReal );
75147
+ testcase( pMem->flags & MEM_Null );
75148
+ if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
7510575149
int rc;
7510675150
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
7510775151
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7510875152
rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
7510975153
if( rc==0 ){
@@ -75117,11 +75161,11 @@
7511775161
}else{
7511875162
MemSetTypeFlag(pMem, MEM_Real);
7511975163
}
7512075164
}
7512175165
}
75122
- assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
75166
+ assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
7512375167
pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
7512475168
return SQLITE_OK;
7512575169
}
7512675170
7512775171
/*
@@ -75160,11 +75204,11 @@
7516075204
assert( aff==SQLITE_AFF_TEXT );
7516175205
assert( MEM_Str==(MEM_Blob>>3) );
7516275206
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
7516375207
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
7516475208
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
75165
- pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
75209
+ pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
7516675210
break;
7516775211
}
7516875212
}
7516975213
}
7517075214
@@ -75344,11 +75388,11 @@
7534475388
** A significant change would indicated a missed call to this
7534575389
** function for pX. Minor changes, such as adding or removing a
7534675390
** dual type, are allowed, as long as the underlying value is the
7534775391
** same. */
7534875392
u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
75349
- assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
75393
+ assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
7535075394
assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
7535175395
assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
7535275396
assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
7535375397
7535475398
/* pMem is the register that is changing. But also mark pX as
@@ -75907,11 +75951,16 @@
7590775951
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
7590875952
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
7590975953
}else{
7591075954
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
7591175955
}
75912
- if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
75956
+ assert( (pVal->flags & MEM_IntReal)==0 );
75957
+ if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
75958
+ testcase( pVal->flags & MEM_Int );
75959
+ testcase( pVal->flags & MEM_Real );
75960
+ pVal->flags &= ~MEM_Str;
75961
+ }
7591375962
if( enc!=SQLITE_UTF8 ){
7591475963
rc = sqlite3VdbeChangeEncoding(pVal, enc);
7591575964
}
7591675965
}else if( op==TK_UMINUS ) {
7591775966
/* This branch happens for multiple negative signs. Ex: -(-5) */
@@ -75930,11 +75979,11 @@
7593075979
sqlite3ValueApplyAffinity(pVal, affinity, enc);
7593175980
}
7593275981
}else if( op==TK_NULL ){
7593375982
pVal = valueNew(db, pCtx);
7593475983
if( pVal==0 ) goto no_mem;
75935
- sqlite3VdbeMemNumerify(pVal);
75984
+ sqlite3VdbeMemSetNull(pVal);
7593675985
}
7593775986
#ifndef SQLITE_OMIT_BLOB_LITERAL
7593875987
else if( op==TK_BLOB ){
7593975988
int nVal;
7594075989
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
@@ -77847,11 +77896,11 @@
7784777896
}
7784877897
case P4_MEM: {
7784977898
Mem *pMem = pOp->p4.pMem;
7785077899
if( pMem->flags & MEM_Str ){
7785177900
zP4 = pMem->z;
77852
- }else if( pMem->flags & MEM_Int ){
77901
+ }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
7785377902
sqlite3_str_appendf(&x, "%lld", pMem->u.i);
7785477903
}else if( pMem->flags & MEM_Real ){
7785577904
sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
7785677905
}else if( pMem->flags & MEM_Null ){
7785777906
zP4 = "NULL";
@@ -79209,11 +79258,11 @@
7920979258
}
7921079259
}
7921179260
}
7921279261
7921379262
/* Check for immediate foreign key violations. */
79214
- if( p->rc==SQLITE_OK ){
79263
+ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
7921579264
sqlite3VdbeCheckFk(p, 0);
7921679265
}
7921779266
7921879267
/* If the auto-commit flag is set and this is the only active writer
7921979268
** VM, then we do either a commit or rollback of the current transaction.
@@ -79735,10 +79784,12 @@
7973579784
** of SQLite will not understand those serial types.
7973679785
*/
7973779786
7973879787
/*
7973979788
** Return the serial-type for the value stored in pMem.
79789
+**
79790
+** This routine might convert a large MEM_IntReal value into MEM_Real.
7974079791
*/
7974179792
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
7974279793
int flags = pMem->flags;
7974379794
u32 n;
7974479795
@@ -79745,15 +79796,17 @@
7974579796
assert( pLen!=0 );
7974679797
if( flags&MEM_Null ){
7974779798
*pLen = 0;
7974879799
return 0;
7974979800
}
79750
- if( flags&MEM_Int ){
79801
+ if( flags&(MEM_Int|MEM_IntReal) ){
7975179802
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
7975279803
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
7975379804
i64 i = pMem->u.i;
7975479805
u64 u;
79806
+ testcase( flags & MEM_Int );
79807
+ testcase( flags & MEM_IntReal );
7975579808
if( i<0 ){
7975679809
u = ~i;
7975779810
}else{
7975879811
u = i;
7975979812
}
@@ -79769,10 +79822,19 @@
7976979822
if( u<=32767 ){ *pLen = 2; return 2; }
7977079823
if( u<=8388607 ){ *pLen = 3; return 3; }
7977179824
if( u<=2147483647 ){ *pLen = 4; return 4; }
7977279825
if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
7977379826
*pLen = 8;
79827
+ if( flags&MEM_IntReal ){
79828
+ /* If the value is IntReal and is going to take up 8 bytes to store
79829
+ ** as an integer, then we might as well make it an 8-byte floating
79830
+ ** point value */
79831
+ pMem->u.r = (double)pMem->u.i;
79832
+ pMem->flags &= ~MEM_IntReal;
79833
+ pMem->flags |= MEM_Real;
79834
+ return 7;
79835
+ }
7977479836
return 6;
7977579837
}
7977679838
if( flags&MEM_Real ){
7977779839
*pLen = 8;
7977879840
return 7;
@@ -80424,30 +80486,43 @@
8042480486
return (f2&MEM_Null) - (f1&MEM_Null);
8042580487
}
8042680488
8042780489
/* At least one of the two values is a number
8042880490
*/
80429
- if( combined_flags&(MEM_Int|MEM_Real) ){
80430
- if( (f1 & f2 & MEM_Int)!=0 ){
80491
+ if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
80492
+ testcase( combined_flags & MEM_Int );
80493
+ testcase( combined_flags & MEM_Real );
80494
+ testcase( combined_flags & MEM_IntReal );
80495
+ if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
80496
+ testcase( f1 & f2 & MEM_Int );
80497
+ testcase( f1 & f2 & MEM_IntReal );
8043180498
if( pMem1->u.i < pMem2->u.i ) return -1;
8043280499
if( pMem1->u.i > pMem2->u.i ) return +1;
8043380500
return 0;
8043480501
}
8043580502
if( (f1 & f2 & MEM_Real)!=0 ){
8043680503
if( pMem1->u.r < pMem2->u.r ) return -1;
8043780504
if( pMem1->u.r > pMem2->u.r ) return +1;
8043880505
return 0;
8043980506
}
80440
- if( (f1&MEM_Int)!=0 ){
80507
+ if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
80508
+ testcase( f1 & MEM_Int );
80509
+ testcase( f1 & MEM_IntReal );
8044180510
if( (f2&MEM_Real)!=0 ){
8044280511
return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
80512
+ }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
80513
+ if( pMem1->u.i < pMem2->u.i ) return -1;
80514
+ if( pMem1->u.i > pMem2->u.i ) return +1;
80515
+ return 0;
8044380516
}else{
8044480517
return -1;
8044580518
}
8044680519
}
8044780520
if( (f1&MEM_Real)!=0 ){
80448
- if( (f2&MEM_Int)!=0 ){
80521
+ if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
80522
+ testcase( f2 & MEM_Int );
80523
+ testcase( f2 & MEM_IntReal );
8044980524
return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
8045080525
}else{
8045180526
return -1;
8045280527
}
8045380528
}
@@ -80592,11 +80667,13 @@
8059280667
assert( idx1<=szHdr1 || CORRUPT_DB );
8059380668
do{
8059480669
u32 serial_type;
8059580670
8059680671
/* RHS is an integer */
80597
- if( pRhs->flags & MEM_Int ){
80672
+ if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
80673
+ testcase( pRhs->flags & MEM_Int );
80674
+ testcase( pRhs->flags & MEM_IntReal );
8059880675
serial_type = aKey1[idx1];
8059980676
testcase( serial_type==12 );
8060080677
if( serial_type>=10 ){
8060180678
rc = +1;
8060280679
}else if( serial_type==0 ){
@@ -80937,11 +81014,13 @@
8093781014
return vdbeRecordCompareInt;
8093881015
}
8093981016
testcase( flags & MEM_Real );
8094081017
testcase( flags & MEM_Null );
8094181018
testcase( flags & MEM_Blob );
80942
- if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
81019
+ if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
81020
+ && p->pKeyInfo->aColl[0]==0
81021
+ ){
8094381022
assert( flags & MEM_Str );
8094481023
return vdbeRecordCompareString;
8094581024
}
8094681025
}
8094781026
@@ -81527,43 +81606,90 @@
8152781606
** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
8152881607
** point number string BLOB NULL
8152981608
*/
8153081609
SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
8153181610
static const u8 aType[] = {
81532
- SQLITE_BLOB, /* 0x00 */
81533
- SQLITE_NULL, /* 0x01 */
81534
- SQLITE_TEXT, /* 0x02 */
81535
- SQLITE_NULL, /* 0x03 */
81536
- SQLITE_INTEGER, /* 0x04 */
81537
- SQLITE_NULL, /* 0x05 */
81538
- SQLITE_INTEGER, /* 0x06 */
81539
- SQLITE_NULL, /* 0x07 */
81540
- SQLITE_FLOAT, /* 0x08 */
81541
- SQLITE_NULL, /* 0x09 */
81542
- SQLITE_FLOAT, /* 0x0a */
81543
- SQLITE_NULL, /* 0x0b */
81544
- SQLITE_INTEGER, /* 0x0c */
81545
- SQLITE_NULL, /* 0x0d */
81546
- SQLITE_INTEGER, /* 0x0e */
81547
- SQLITE_NULL, /* 0x0f */
81548
- SQLITE_BLOB, /* 0x10 */
81549
- SQLITE_NULL, /* 0x11 */
81550
- SQLITE_TEXT, /* 0x12 */
81551
- SQLITE_NULL, /* 0x13 */
81552
- SQLITE_INTEGER, /* 0x14 */
81553
- SQLITE_NULL, /* 0x15 */
81554
- SQLITE_INTEGER, /* 0x16 */
81555
- SQLITE_NULL, /* 0x17 */
81556
- SQLITE_FLOAT, /* 0x18 */
81557
- SQLITE_NULL, /* 0x19 */
81558
- SQLITE_FLOAT, /* 0x1a */
81559
- SQLITE_NULL, /* 0x1b */
81560
- SQLITE_INTEGER, /* 0x1c */
81561
- SQLITE_NULL, /* 0x1d */
81562
- SQLITE_INTEGER, /* 0x1e */
81563
- SQLITE_NULL, /* 0x1f */
81564
- };
81611
+ SQLITE_BLOB, /* 0x00 (not possible) */
81612
+ SQLITE_NULL, /* 0x01 NULL */
81613
+ SQLITE_TEXT, /* 0x02 TEXT */
81614
+ SQLITE_NULL, /* 0x03 (not possible) */
81615
+ SQLITE_INTEGER, /* 0x04 INTEGER */
81616
+ SQLITE_NULL, /* 0x05 (not possible) */
81617
+ SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */
81618
+ SQLITE_NULL, /* 0x07 (not possible) */
81619
+ SQLITE_FLOAT, /* 0x08 FLOAT */
81620
+ SQLITE_NULL, /* 0x09 (not possible) */
81621
+ SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */
81622
+ SQLITE_NULL, /* 0x0b (not possible) */
81623
+ SQLITE_INTEGER, /* 0x0c (not possible) */
81624
+ SQLITE_NULL, /* 0x0d (not possible) */
81625
+ SQLITE_INTEGER, /* 0x0e (not possible) */
81626
+ SQLITE_NULL, /* 0x0f (not possible) */
81627
+ SQLITE_BLOB, /* 0x10 BLOB */
81628
+ SQLITE_NULL, /* 0x11 (not possible) */
81629
+ SQLITE_TEXT, /* 0x12 (not possible) */
81630
+ SQLITE_NULL, /* 0x13 (not possible) */
81631
+ SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */
81632
+ SQLITE_NULL, /* 0x15 (not possible) */
81633
+ SQLITE_INTEGER, /* 0x16 (not possible) */
81634
+ SQLITE_NULL, /* 0x17 (not possible) */
81635
+ SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */
81636
+ SQLITE_NULL, /* 0x19 (not possible) */
81637
+ SQLITE_FLOAT, /* 0x1a (not possible) */
81638
+ SQLITE_NULL, /* 0x1b (not possible) */
81639
+ SQLITE_INTEGER, /* 0x1c (not possible) */
81640
+ SQLITE_NULL, /* 0x1d (not possible) */
81641
+ SQLITE_INTEGER, /* 0x1e (not possible) */
81642
+ SQLITE_NULL, /* 0x1f (not possible) */
81643
+ SQLITE_FLOAT, /* 0x20 INTREAL */
81644
+ SQLITE_NULL, /* 0x21 (not possible) */
81645
+ SQLITE_TEXT, /* 0x22 INTREAL + TEXT */
81646
+ SQLITE_NULL, /* 0x23 (not possible) */
81647
+ SQLITE_FLOAT, /* 0x24 (not possible) */
81648
+ SQLITE_NULL, /* 0x25 (not possible) */
81649
+ SQLITE_FLOAT, /* 0x26 (not possible) */
81650
+ SQLITE_NULL, /* 0x27 (not possible) */
81651
+ SQLITE_FLOAT, /* 0x28 (not possible) */
81652
+ SQLITE_NULL, /* 0x29 (not possible) */
81653
+ SQLITE_FLOAT, /* 0x2a (not possible) */
81654
+ SQLITE_NULL, /* 0x2b (not possible) */
81655
+ SQLITE_FLOAT, /* 0x2c (not possible) */
81656
+ SQLITE_NULL, /* 0x2d (not possible) */
81657
+ SQLITE_FLOAT, /* 0x2e (not possible) */
81658
+ SQLITE_NULL, /* 0x2f (not possible) */
81659
+ SQLITE_BLOB, /* 0x30 (not possible) */
81660
+ SQLITE_NULL, /* 0x31 (not possible) */
81661
+ SQLITE_TEXT, /* 0x32 (not possible) */
81662
+ SQLITE_NULL, /* 0x33 (not possible) */
81663
+ SQLITE_FLOAT, /* 0x34 (not possible) */
81664
+ SQLITE_NULL, /* 0x35 (not possible) */
81665
+ SQLITE_FLOAT, /* 0x36 (not possible) */
81666
+ SQLITE_NULL, /* 0x37 (not possible) */
81667
+ SQLITE_FLOAT, /* 0x38 (not possible) */
81668
+ SQLITE_NULL, /* 0x39 (not possible) */
81669
+ SQLITE_FLOAT, /* 0x3a (not possible) */
81670
+ SQLITE_NULL, /* 0x3b (not possible) */
81671
+ SQLITE_FLOAT, /* 0x3c (not possible) */
81672
+ SQLITE_NULL, /* 0x3d (not possible) */
81673
+ SQLITE_FLOAT, /* 0x3e (not possible) */
81674
+ SQLITE_NULL, /* 0x3f (not possible) */
81675
+ };
81676
+#ifdef SQLITE_DEBUG
81677
+ {
81678
+ int eType = SQLITE_BLOB;
81679
+ if( pVal->flags & MEM_Null ){
81680
+ eType = SQLITE_NULL;
81681
+ }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
81682
+ eType = SQLITE_FLOAT;
81683
+ }else if( pVal->flags & MEM_Int ){
81684
+ eType = SQLITE_INTEGER;
81685
+ }else if( pVal->flags & MEM_Str ){
81686
+ eType = SQLITE_TEXT;
81687
+ }
81688
+ assert( eType == aType[pVal->flags&MEM_AffMask] );
81689
+ }
81690
+#endif
8156581691
return aType[pVal->flags&MEM_AffMask];
8156681692
}
8156781693
8156881694
/* Return true if a parameter to xUpdate represents an unchanged column */
8156981695
SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
@@ -81808,10 +81934,25 @@
8180881934
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
8180981935
sqlite3VdbeMemSetNull(pCtx->pOut);
8181081936
pCtx->isError = SQLITE_NOMEM_BKPT;
8181181937
sqlite3OomFault(pCtx->pOut->db);
8181281938
}
81939
+
81940
+#ifndef SQLITE_UNTESTABLE
81941
+/* Force the INT64 value currently stored as the result to be
81942
+** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL
81943
+** test-control.
81944
+*/
81945
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){
81946
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
81947
+ if( pCtx->pOut->flags & MEM_Int ){
81948
+ pCtx->pOut->flags &= ~MEM_Int;
81949
+ pCtx->pOut->flags |= MEM_IntReal;
81950
+ }
81951
+}
81952
+#endif
81953
+
8181381954
8181481955
/*
8181581956
** This function is called after a transaction has been committed. It
8181681957
** invokes callbacks registered with sqlite3_wal_hook() as required.
8181781958
*/
@@ -83095,11 +83236,13 @@
8309583236
if( iIdx==p->pTab->iPKey ){
8309683237
sqlite3VdbeMemSetInt64(pMem, p->iKey1);
8309783238
}else if( iIdx>=p->pUnpacked->nField ){
8309883239
*ppValue = (sqlite3_value *)columnNullValue();
8309983240
}else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
83100
- if( pMem->flags & MEM_Int ){
83241
+ if( pMem->flags & (MEM_Int|MEM_IntReal) ){
83242
+ testcase( pMem->flags & MEM_Int );
83243
+ testcase( pMem->flags & MEM_IntReal );
8310183244
sqlite3VdbeMemRealify(pMem);
8310283245
}
8310383246
}
8310483247
8310583248
preupdate_old_out:
@@ -83414,11 +83557,11 @@
8341483557
nextIndex = idx + 1;
8341583558
assert( idx>0 && idx<=p->nVar );
8341683559
pVar = &p->aVar[idx-1];
8341783560
if( pVar->flags & MEM_Null ){
8341883561
sqlite3_str_append(&out, "NULL", 4);
83419
- }else if( pVar->flags & MEM_Int ){
83562
+ }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
8342083563
sqlite3_str_appendf(&out, "%lld", pVar->u.i);
8342183564
}else if( pVar->flags & MEM_Real ){
8342283565
sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
8342383566
}else if( pVar->flags & MEM_Str ){
8342483567
int nOut; /* Number of bytes of the string text to include in output */
@@ -83676,18 +83819,10 @@
8367683819
sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
8367783820
iSrcLine&0xffffff, I, M);
8367883821
}
8367983822
#endif
8368083823
83681
-/*
83682
-** Convert the given register into a string if it isn't one
83683
-** already. Return non-zero if a malloc() fails.
83684
-*/
83685
-#define Stringify(P, enc) \
83686
- if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
83687
- { goto no_mem; }
83688
-
8368983824
/*
8369083825
** An ephemeral string value (signified by the MEM_Ephem flag) contains
8369183826
** a pointer to a dynamically allocated string where some other entity
8369283827
** is responsible for deallocating that string. Because the register
8369383828
** does not control the string, it might be deleted without the register
@@ -83745,11 +83880,11 @@
8374583880
if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
8374683881
/* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
8374783882
** is clear. Otherwise, if this is an ephemeral cursor created by
8374883883
** OP_OpenDup, the cursor will not be closed and will still be part
8374983884
** of a BtShared.pCursor list. */
83750
- p->apCsr[iCur]->isEphemeral = 0;
83885
+ if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
8375183886
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
8375283887
p->apCsr[iCur] = 0;
8375383888
}
8375483889
if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
8375583890
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
@@ -83784,11 +83919,11 @@
8378483919
*/
8378583920
static void applyNumericAffinity(Mem *pRec, int bTryForInt){
8378683921
double rValue;
8378783922
i64 iValue;
8378883923
u8 enc = pRec->enc;
83789
- assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
83924
+ assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
8379083925
if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
8379183926
if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
8379283927
pRec->u.i = iValue;
8379383928
pRec->flags |= MEM_Int;
8379483929
}else{
@@ -83841,15 +83976,18 @@
8384183976
** representation (blob and NULL do not get converted) but no string
8384283977
** representation. It would be harmless to repeat the conversion if
8384383978
** there is already a string rep, but it is pointless to waste those
8384483979
** CPU cycles. */
8384583980
if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
83846
- if( (pRec->flags&(MEM_Real|MEM_Int)) ){
83981
+ if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
83982
+ testcase( pRec->flags & MEM_Int );
83983
+ testcase( pRec->flags & MEM_Real );
83984
+ testcase( pRec->flags & MEM_IntReal );
8384783985
sqlite3VdbeMemStringify(pRec, enc, 1);
8384883986
}
8384983987
}
83850
- pRec->flags &= ~(MEM_Real|MEM_Int);
83988
+ pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
8385183989
}
8385283990
}
8385383991
8385483992
/*
8385583993
** Try to convert the type of a function argument or a result column
@@ -83884,11 +84022,11 @@
8388484022
** interpret as a string if we want to). Compute its corresponding
8388584023
** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields
8388684024
** accordingly.
8388784025
*/
8388884026
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
83889
- assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
84027
+ assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
8389084028
assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
8389184029
ExpandBlob(pMem);
8389284030
if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
8389384031
return 0;
8389484032
}
@@ -83904,14 +84042,19 @@
8390484042
**
8390584043
** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
8390684044
** But it does set pMem->u.r and pMem->u.i appropriately.
8390784045
*/
8390884046
static u16 numericType(Mem *pMem){
83909
- if( pMem->flags & (MEM_Int|MEM_Real) ){
83910
- return pMem->flags & (MEM_Int|MEM_Real);
84047
+ if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
84048
+ testcase( pMem->flags & MEM_Int );
84049
+ testcase( pMem->flags & MEM_Real );
84050
+ testcase( pMem->flags & MEM_IntReal );
84051
+ return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
8391184052
}
8391284053
if( pMem->flags & (MEM_Str|MEM_Blob) ){
84054
+ testcase( pMem->flags & MEM_Str );
84055
+ testcase( pMem->flags & MEM_Blob );
8391384056
return computeNumericType(pMem);
8391484057
}
8391584058
return 0;
8391684059
}
8391784060
@@ -84003,10 +84146,12 @@
8400384146
printf(" undefined");
8400484147
}else if( p->flags & MEM_Null ){
8400584148
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
8400684149
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
8400784150
printf(" si:%lld", p->u.i);
84151
+ }else if( (p->flags & (MEM_IntReal))!=0 ){
84152
+ printf(" ir:%lld", p->u.i);
8400884153
}else if( p->flags & MEM_Int ){
8400984154
printf(" i:%lld", p->u.i);
8401084155
#ifndef SQLITE_OMIT_FLOATING_POINT
8401184156
}else if( p->flags & MEM_Real ){
8401284157
printf(" r:%g", p->u.r);
@@ -85033,23 +85178,42 @@
8503385178
** It is illegal for P1 and P3 to be the same register. Sometimes,
8503485179
** if P3 is the same register as P2, the implementation is able
8503585180
** to avoid a memcpy().
8503685181
*/
8503785182
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
85038
- i64 nByte;
85183
+ i64 nByte; /* Total size of the output string or blob */
85184
+ u16 flags1; /* Initial flags for P1 */
85185
+ u16 flags2; /* Initial flags for P2 */
8503985186
8504085187
pIn1 = &aMem[pOp->p1];
8504185188
pIn2 = &aMem[pOp->p2];
8504285189
pOut = &aMem[pOp->p3];
85190
+ testcase( pIn1==pIn2 );
85191
+ testcase( pOut==pIn2 );
8504385192
assert( pIn1!=pOut );
85044
- if( (pIn1->flags | pIn2->flags) & MEM_Null ){
85193
+ flags1 = pIn1->flags;
85194
+ testcase( flags1 & MEM_Null );
85195
+ testcase( pIn2->flags & MEM_Null );
85196
+ if( (flags1 | pIn2->flags) & MEM_Null ){
8504585197
sqlite3VdbeMemSetNull(pOut);
8504685198
break;
8504785199
}
85048
- if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
85049
- Stringify(pIn1, encoding);
85050
- Stringify(pIn2, encoding);
85200
+ if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
85201
+ if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
85202
+ flags1 = pIn1->flags & ~MEM_Str;
85203
+ }else if( (flags1 & MEM_Zero)!=0 ){
85204
+ if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
85205
+ flags1 = pIn1->flags & ~MEM_Str;
85206
+ }
85207
+ flags2 = pIn2->flags;
85208
+ if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
85209
+ if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
85210
+ flags2 = pIn2->flags & ~MEM_Str;
85211
+ }else if( (flags2 & MEM_Zero)!=0 ){
85212
+ if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
85213
+ flags2 = pIn2->flags & ~MEM_Str;
85214
+ }
8505185215
nByte = pIn1->n + pIn2->n;
8505285216
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
8505385217
goto too_big;
8505485218
}
8505585219
if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
@@ -85056,12 +85220,16 @@
8505685220
goto no_mem;
8505785221
}
8505885222
MemSetTypeFlag(pOut, MEM_Str);
8505985223
if( pOut!=pIn2 ){
8506085224
memcpy(pOut->z, pIn2->z, pIn2->n);
85225
+ assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
85226
+ pIn2->flags = flags2;
8506185227
}
8506285228
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
85229
+ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
85230
+ pIn1->flags = flags1;
8506385231
pOut->z[nByte]=0;
8506485232
pOut->z[nByte+1] = 0;
8506585233
pOut->flags |= MEM_Term;
8506685234
pOut->n = (int)nByte;
8506785235
pOut->enc = encoding;
@@ -85183,11 +85351,11 @@
8518385351
if( sqlite3IsNaN(rB) ){
8518485352
goto arithmetic_result_is_null;
8518585353
}
8518685354
pOut->u.r = rB;
8518785355
MemSetTypeFlag(pOut, MEM_Real);
85188
- if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
85356
+ if( ((type1|type2)&(MEM_Real|MEM_IntReal))==0 && !bIntint ){
8518985357
sqlite3VdbeIntegerAffinity(pOut);
8519085358
}
8519185359
#endif
8519285360
}
8519385361
break;
@@ -85354,11 +85522,13 @@
8535485522
** integers, for space efficiency, but after extraction we want them
8535585523
** to have only a real value.
8535685524
*/
8535785525
case OP_RealAffinity: { /* in1 */
8535885526
pIn1 = &aMem[pOp->p1];
85359
- if( pIn1->flags & MEM_Int ){
85527
+ if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
85528
+ testcase( pIn1->flags & MEM_Int );
85529
+ testcase( pIn1->flags & MEM_IntReal );
8536085530
sqlite3VdbeMemRealify(pIn1);
8536185531
}
8536285532
break;
8536385533
}
8536485534
#endif
@@ -85546,21 +85716,21 @@
8554685716
}else{
8554785717
/* Neither operand is NULL. Do a comparison. */
8554885718
affinity = pOp->p5 & SQLITE_AFF_MASK;
8554985719
if( affinity>=SQLITE_AFF_NUMERIC ){
8555085720
if( (flags1 | flags3)&MEM_Str ){
85551
- if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
85721
+ if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
8555285722
applyNumericAffinity(pIn1,0);
8555385723
assert( flags3==pIn3->flags );
8555485724
/* testcase( flags3!=pIn3->flags );
8555585725
** this used to be possible with pIn1==pIn3, but not since
8555685726
** the column cache was removed. The following assignment
8555785727
** is essentially a no-op. But, it provides defense-in-depth
8555885728
** in case our analysis is incorrect, so it is left in. */
8555985729
flags3 = pIn3->flags;
8556085730
}
85561
- if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
85731
+ if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
8556285732
applyNumericAffinity(pIn3,0);
8556385733
}
8556485734
}
8556585735
/* Handle the common case of integer comparison here, as an
8556685736
** optimization, to avoid a call to sqlite3MemCompare() */
@@ -85569,21 +85739,23 @@
8556985739
if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
8557085740
res = 0;
8557185741
goto compare_op;
8557285742
}
8557385743
}else if( affinity==SQLITE_AFF_TEXT ){
85574
- if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
85744
+ if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
8557585745
testcase( pIn1->flags & MEM_Int );
8557685746
testcase( pIn1->flags & MEM_Real );
85747
+ testcase( pIn1->flags & MEM_IntReal );
8557785748
sqlite3VdbeMemStringify(pIn1, encoding, 1);
8557885749
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
8557985750
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
8558085751
assert( pIn1!=pIn3 );
8558185752
}
85582
- if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
85753
+ if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
8558385754
testcase( pIn3->flags & MEM_Int );
8558485755
testcase( pIn3->flags & MEM_Real );
85756
+ testcase( pIn3->flags & MEM_IntReal );
8558585757
sqlite3VdbeMemStringify(pIn3, encoding, 1);
8558685758
testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
8558785759
flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
8558885760
}
8558985761
}
@@ -86335,16 +86507,25 @@
8633586507
zAffinity = pOp->p4.z;
8633686508
assert( zAffinity!=0 );
8633786509
assert( pOp->p2>0 );
8633886510
assert( zAffinity[pOp->p2]==0 );
8633986511
pIn1 = &aMem[pOp->p1];
86340
- do{
86512
+ while( 1 /*edit-by-break*/ ){
8634186513
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
8634286514
assert( memIsValid(pIn1) );
86343
- applyAffinity(pIn1, *(zAffinity++), encoding);
86515
+ applyAffinity(pIn1, zAffinity[0], encoding);
86516
+ if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
86517
+ /* When applying REAL affinity, if the result is still MEM_Int,
86518
+ ** indicate that REAL is actually desired */
86519
+ pIn1->flags |= MEM_IntReal;
86520
+ pIn1->flags &= ~MEM_Int;
86521
+ }
86522
+ REGISTER_TRACE((int)(pIn1-aMem), pIn1);
86523
+ zAffinity++;
86524
+ if( zAffinity[0]==0 ) break;
8634486525
pIn1++;
86345
- }while( zAffinity[0] );
86526
+ }
8634686527
break;
8634786528
}
8634886529
8634986530
/* Opcode: MakeRecord P1 P2 P3 P4 *
8635086531
** Synopsis: r[P3]=mkrec(r[P1@P2])
@@ -86361,11 +86542,10 @@
8636186542
** macros defined in sqliteInt.h.
8636286543
**
8636386544
** If P4 is NULL then all index fields have the affinity BLOB.
8636486545
*/
8636586546
case OP_MakeRecord: {
86366
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
8636786547
Mem *pRec; /* The new record */
8636886548
u64 nData; /* Number of bytes of data space */
8636986549
int nHdr; /* Number of bytes of header space */
8637086550
i64 nByte; /* Data space required for this record */
8637186551
i64 nZero; /* Number of zero bytes at the end of the record */
@@ -86374,13 +86554,13 @@
8637486554
Mem *pData0; /* First field to be combined into the record */
8637586555
Mem *pLast; /* Last field of the record */
8637686556
int nField; /* Number of fields in the record */
8637786557
char *zAffinity; /* The affinity string for the record */
8637886558
int file_format; /* File format to use for encoding */
86379
- int i; /* Space used in zNewRecord[] header */
86380
- int j; /* Space used in zNewRecord[] content */
8638186559
u32 len; /* Length of a field */
86560
+ u8 *zHdr; /* Where to write next byte of the header */
86561
+ u8 *zPayload; /* Where to write next byte of the payload */
8638286562
8638386563
/* Assuming the record contains N fields, the record format looks
8638486564
** like this:
8638586565
**
8638686566
** ------------------------------------------------------------------------
@@ -86415,11 +86595,14 @@
8641586595
*/
8641686596
assert( pData0<=pLast );
8641786597
if( zAffinity ){
8641886598
pRec = pData0;
8641986599
do{
86420
- applyAffinity(pRec++, *(zAffinity++), encoding);
86600
+ applyAffinity(pRec, zAffinity[0], encoding);
86601
+ REGISTER_TRACE((int)(pRec-aMem), pRec);
86602
+ zAffinity++;
86603
+ pRec++;
8642186604
assert( zAffinity[0]==0 || pRec<=pLast );
8642286605
}while( zAffinity[0] );
8642386606
}
8642486607
8642586608
#ifdef SQLITE_ENABLE_NULL_TRIM
@@ -86503,38 +86686,38 @@
8650386686
}
8650486687
if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
8650586688
goto no_mem;
8650686689
}
8650786690
}
86508
- zNewRecord = (u8 *)pOut->z;
86691
+ pOut->n = (int)nByte;
86692
+ pOut->flags = MEM_Blob;
86693
+ if( nZero ){
86694
+ pOut->u.nZero = nZero;
86695
+ pOut->flags |= MEM_Zero;
86696
+ }
86697
+ UPDATE_MAX_BLOBSIZE(pOut);
86698
+ zHdr = (u8 *)pOut->z;
86699
+ zPayload = zHdr + nHdr;
8650986700
8651086701
/* Write the record */
86511
- i = putVarint32(zNewRecord, nHdr);
86512
- j = nHdr;
86702
+ zHdr += putVarint32(zHdr, nHdr);
8651386703
assert( pData0<=pLast );
8651486704
pRec = pData0;
8651586705
do{
8651686706
serial_type = pRec->uTemp;
8651786707
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
8651886708
** additional varints, one per column. */
86519
- i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
86709
+ zHdr += putVarint32(zHdr, serial_type); /* serial type */
8652086710
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
8652186711
** immediately follow the header. */
86522
- j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
86712
+ zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
8652386713
}while( (++pRec)<=pLast );
86524
- assert( i==nHdr );
86525
- assert( j==nByte );
86714
+ assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
86715
+ assert( nByte==(int)(zPayload - (u8*)pOut->z) );
8652686716
8652786717
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
86528
- pOut->n = (int)nByte;
86529
- pOut->flags = MEM_Blob;
86530
- if( nZero ){
86531
- pOut->u.nZero = nZero;
86532
- pOut->flags |= MEM_Zero;
86533
- }
8653486718
REGISTER_TRACE(pOp->p3, pOut);
86535
- UPDATE_MAX_BLOBSIZE(pOut);
8653686719
break;
8653786720
}
8653886721
8653986722
/* Opcode: Count P1 P2 * * *
8654086723
** Synopsis: r[P2]=count()
@@ -86560,12 +86743,13 @@
8656086743
#endif
8656186744
8656286745
/* Opcode: Savepoint P1 * * P4 *
8656386746
**
8656486747
** Open, release or rollback the savepoint named by parameter P4, depending
86565
-** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
86566
-** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
86748
+** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
86749
+** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
86750
+** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
8656786751
*/
8656886752
case OP_Savepoint: {
8656986753
int p1; /* Value of P1 operand */
8657086754
char *zName; /* Name of savepoint */
8657186755
int nName;
@@ -86629,10 +86813,11 @@
8662986813
pNew->nDeferredCons = db->nDeferredCons;
8663086814
pNew->nDeferredImmCons = db->nDeferredImmCons;
8663186815
}
8663286816
}
8663386817
}else{
86818
+ assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
8663486819
iSavepoint = 0;
8663586820
8663686821
/* Find the named savepoint. If there is no such savepoint, then an
8663786822
** an error is returned to the user. */
8663886823
for(
@@ -86682,10 +86867,11 @@
8668286867
SQLITE_ABORT_ROLLBACK,
8668386868
isSchemaChange==0);
8668486869
if( rc!=SQLITE_OK ) goto abort_due_to_error;
8668586870
}
8668686871
}else{
86872
+ assert( p1==SAVEPOINT_RELEASE );
8668786873
isSchemaChange = 0;
8668886874
}
8668986875
for(ii=0; ii<db->nDb; ii++){
8669086876
rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
8669186877
if( rc!=SQLITE_OK ){
@@ -86718,10 +86904,11 @@
8671886904
sqlite3DbFree(db, pSavepoint);
8671986905
if( !isTransaction ){
8672086906
db->nSavepoint--;
8672186907
}
8672286908
}else{
86909
+ assert( p1==SAVEPOINT_ROLLBACK );
8672386910
db->nDeferredCons = pSavepoint->nDeferredCons;
8672486911
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
8672586912
}
8672686913
8672786914
if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
@@ -87256,11 +87443,14 @@
8725687443
assert( pOp->p2>=0 );
8725787444
pCx = p->apCsr[pOp->p1];
8725887445
if( pCx ){
8725987446
/* If the ephermeral table is already open, erase all existing content
8726087447
** so that the table is empty again, rather than creating a new table. */
87261
- rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
87448
+ assert( pCx->isEphemeral );
87449
+ if( pCx->pBtx ){
87450
+ rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
87451
+ }
8726287452
}else{
8726387453
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
8726487454
if( pCx==0 ) goto no_mem;
8726587455
pCx->nullRow = 1;
8726687456
pCx->isEphemeral = 1;
@@ -87533,24 +87723,28 @@
8753387723
8753487724
/* The input value in P3 might be of any type: integer, real, string,
8753587725
** blob, or NULL. But it needs to be an integer before we can do
8753687726
** the seek, so convert it. */
8753787727
pIn3 = &aMem[pOp->p3];
87538
- if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
87728
+ if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
8753987729
applyNumericAffinity(pIn3, 0);
8754087730
}
8754187731
iKey = sqlite3VdbeIntValue(pIn3);
8754287732
8754387733
/* If the P3 value could not be converted into an integer without
8754487734
** loss of information, then special processing is required... */
87545
- if( (pIn3->flags & MEM_Int)==0 ){
87735
+ if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
8754687736
if( (pIn3->flags & MEM_Real)==0 ){
87547
- /* If the P3 value cannot be converted into any kind of a number,
87548
- ** then the seek is not possible, so jump to P2 */
87549
- VdbeBranchTaken(1,2); goto jump_to_p2;
87550
- break;
87551
- }
87737
+ if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
87738
+ VdbeBranchTaken(1,2); goto jump_to_p2;
87739
+ break;
87740
+ }else{
87741
+ rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
87742
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
87743
+ goto seek_not_found;
87744
+ }
87745
+ }else
8755287746
8755387747
/* If the approximation iKey is larger than the actual real search
8755487748
** term, substitute >= for > and < for <=. e.g. if the search term
8755587749
** is 4.9 and the integer approximation 5:
8755687750
**
@@ -87570,11 +87764,11 @@
8757087764
assert( OP_SeekLE==(OP_SeekLT+1) );
8757187765
assert( OP_SeekGT==(OP_SeekGE+1) );
8757287766
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
8757387767
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
8757487768
}
87575
- }
87769
+ }
8757687770
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
8757787771
pC->movetoTarget = iKey; /* Used by OP_Delete */
8757887772
if( rc!=SQLITE_OK ){
8757987773
goto abort_due_to_error;
8758087774
}
@@ -87925,11 +88119,13 @@
8792588119
BtCursor *pCrsr;
8792688120
int res;
8792788121
u64 iKey;
8792888122
8792988123
pIn3 = &aMem[pOp->p3];
87930
- if( (pIn3->flags & MEM_Int)==0 ){
88124
+ testcase( pIn3->flags & MEM_Int );
88125
+ testcase( pIn3->flags & MEM_IntReal );
88126
+ if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
8793188127
/* Make sure pIn3->u.i contains a valid integer representation of
8793288128
** the key value, but do not change the datatype of the register, as
8793388129
** other parts of the perpared statement might be depending on the
8793488130
** current datatype. */
8793588131
u16 origFlags = pIn3->flags;
@@ -95977,11 +96173,13 @@
9597796173
sqlite3WalkExprList(pWalker, pList);
9597896174
if( is_agg ){
9597996175
#ifndef SQLITE_OMIT_WINDOWFUNC
9598096176
if( pExpr->y.pWin ){
9598196177
Select *pSel = pNC->pWinSelect;
95982
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
96178
+ if( IN_RENAME_OBJECT==0 ){
96179
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
96180
+ }
9598396181
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
9598496182
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
9598596183
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
9598696184
if( 0==pSel->pWin
9598796185
|| 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
@@ -97660,11 +97858,11 @@
9766097858
memset(pNew, 0, sizeof(Expr));
9766197859
pNew->op = (u8)op;
9766297860
pNew->iAgg = -1;
9766397861
if( pToken ){
9766497862
if( nExtra==0 ){
97665
- pNew->flags |= EP_IntValue|EP_Leaf;
97863
+ pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
9766697864
pNew->u.iValue = iValue;
9766797865
}else{
9766897866
pNew->u.zToken = (char*)&pNew[1];
9766997867
assert( pToken->z!=0 || pToken->n==0 );
9767097868
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
@@ -97737,24 +97935,20 @@
9773797935
int op, /* Expression opcode */
9773897936
Expr *pLeft, /* Left operand */
9773997937
Expr *pRight /* Right operand */
9774097938
){
9774197939
Expr *p;
97742
- if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
97743
- /* Take advantage of short-circuit false optimization for AND */
97744
- p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
97745
- }else{
97746
- p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
97747
- if( p ){
97748
- memset(p, 0, sizeof(Expr));
97749
- p->op = op & 0xff;
97750
- p->iAgg = -1;
97751
- }
97940
+ p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
97941
+ if( p ){
97942
+ memset(p, 0, sizeof(Expr));
97943
+ p->op = op & 0xff;
97944
+ p->iAgg = -1;
9775297945
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
97753
- }
97754
- if( p ) {
9775597946
sqlite3ExprCheckHeight(pParse, p->nHeight);
97947
+ }else{
97948
+ sqlite3ExprDelete(pParse->db, pLeft);
97949
+ sqlite3ExprDelete(pParse->db, pRight);
9775697950
}
9775797951
return p;
9775897952
}
9775997953
9776097954
/*
@@ -97771,58 +97965,32 @@
9777197965
sqlite3SelectDelete(pParse->db, pSelect);
9777297966
}
9777397967
}
9777497968
9777597969
97776
-/*
97777
-** If the expression is always either TRUE or FALSE (respectively),
97778
-** then return 1. If one cannot determine the truth value of the
97779
-** expression at compile-time return 0.
97780
-**
97781
-** This is an optimization. If is OK to return 0 here even if
97782
-** the expression really is always false or false (a false negative).
97783
-** But it is a bug to return 1 if the expression might have different
97784
-** boolean values in different circumstances (a false positive.)
97785
-**
97786
-** Note that if the expression is part of conditional for a
97787
-** LEFT JOIN, then we cannot determine at compile-time whether or not
97788
-** is it true or false, so always return 0.
97789
-*/
97790
-static int exprAlwaysTrue(Expr *p){
97791
- int v = 0;
97792
- if( ExprHasProperty(p, EP_FromJoin) ) return 0;
97793
- if( !sqlite3ExprIsInteger(p, &v) ) return 0;
97794
- return v!=0;
97795
-}
97796
-static int exprAlwaysFalse(Expr *p){
97797
- int v = 0;
97798
- if( ExprHasProperty(p, EP_FromJoin) ) return 0;
97799
- if( !sqlite3ExprIsInteger(p, &v) ) return 0;
97800
- return v==0;
97801
-}
97802
-
9780397970
/*
9780497971
** Join two expressions using an AND operator. If either expression is
9780597972
** NULL, then just return the other expression.
9780697973
**
9780797974
** If one side or the other of the AND is known to be false, then instead
9780897975
** of returning an AND expression, just return a constant expression with
9780997976
** a value of false.
9781097977
*/
97811
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
97812
- if( pLeft==0 ){
97978
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
97979
+ sqlite3 *db = pParse->db;
97980
+ if( pLeft==0 ){
9781397981
return pRight;
9781497982
}else if( pRight==0 ){
9781597983
return pLeft;
97816
- }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
97984
+ }else if( pParse->nErr || IN_RENAME_OBJECT ){
97985
+ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
97986
+ }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
9781797987
sqlite3ExprDelete(db, pLeft);
9781897988
sqlite3ExprDelete(db, pRight);
9781997989
return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
9782097990
}else{
97821
- Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
97822
- sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
97823
- return pNew;
97991
+ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
9782497992
}
9782597993
}
9782697994
9782797995
/*
9782897996
** Construct a new expression node for a function with multiple
@@ -98708,10 +98876,11 @@
9870898876
if( !ExprHasProperty(pExpr, EP_Quoted)
9870998877
&& (sqlite3StrICmp(pExpr->u.zToken, "true")==0
9871098878
|| sqlite3StrICmp(pExpr->u.zToken, "false")==0)
9871198879
){
9871298880
pExpr->op = TK_TRUEFALSE;
98881
+ ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
9871398882
return 1;
9871498883
}
9871598884
return 0;
9871698885
}
9871798886
@@ -98723,10 +98892,37 @@
9872398892
assert( pExpr->op==TK_TRUEFALSE );
9872498893
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
9872598894
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
9872698895
return pExpr->u.zToken[4]==0;
9872798896
}
98897
+
98898
+/*
98899
+** If pExpr is an AND or OR expression, try to simplify it by eliminating
98900
+** terms that are always true or false. Return the simplified expression.
98901
+** Or return the original expression if no simplification is possible.
98902
+**
98903
+** Examples:
98904
+**
98905
+** (x<10) AND true => (x<10)
98906
+** (x<10) AND false => false
98907
+** (x<10) AND (y=22 OR false) => (x<10) AND (y=22)
98908
+** (x<10) AND (y=22 OR true) => (x<10)
98909
+** (y=22) OR true => true
98910
+*/
98911
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
98912
+ assert( pExpr!=0 );
98913
+ if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
98914
+ Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
98915
+ Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
98916
+ if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
98917
+ pExpr = pExpr->op==TK_AND ? pRight : pLeft;
98918
+ }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
98919
+ pExpr = pExpr->op==TK_AND ? pLeft : pRight;
98920
+ }
98921
+ }
98922
+ return pExpr;
98923
+}
9872898924
9872998925
9873098926
/*
9873198927
** These routines are Walker callbacks used to check expressions to
9873298928
** see if they are "constant" for some definition of constant. The
@@ -98968,11 +99164,11 @@
9896899164
** in *pValue. If the expression is not an integer or if it is too big
9896999165
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
9897099166
*/
9897199167
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
9897299168
int rc = 0;
98973
- if( p==0 ) return 0; /* Can only happen following on OOM */
99169
+ if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */
9897499170
9897599171
/* If an expression is an integer literal that fits in a signed 32-bit
9897699172
** integer, then the EP_IntValue flag will have already been set */
9897799173
assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
9897899174
|| sqlite3GetInt32(p->u.zToken, &rc)==0 );
@@ -101315,22 +101511,27 @@
101315101511
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
101316101512
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
101317101513
if( NEVER(pExpr==0) ) return; /* No way this can happen */
101318101514
op = pExpr->op;
101319101515
switch( op ){
101320
- case TK_AND: {
101321
- int d2 = sqlite3VdbeMakeLabel(pParse);
101322
- testcase( jumpIfNull==0 );
101323
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
101324
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
101325
- sqlite3VdbeResolveLabel(v, d2);
101326
- break;
101327
- }
101516
+ case TK_AND:
101328101517
case TK_OR: {
101329
- testcase( jumpIfNull==0 );
101330
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
101331
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
101518
+ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
101519
+ if( pAlt!=pExpr ){
101520
+ sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
101521
+ }else if( op==TK_AND ){
101522
+ int d2 = sqlite3VdbeMakeLabel(pParse);
101523
+ testcase( jumpIfNull==0 );
101524
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
101525
+ jumpIfNull^SQLITE_JUMPIFNULL);
101526
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
101527
+ sqlite3VdbeResolveLabel(v, d2);
101528
+ }else{
101529
+ testcase( jumpIfNull==0 );
101530
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
101531
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
101532
+ }
101332101533
break;
101333101534
}
101334101535
case TK_NOT: {
101335101536
testcase( jumpIfNull==0 );
101336101537
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -101412,13 +101613,13 @@
101412101613
break;
101413101614
}
101414101615
#endif
101415101616
default: {
101416101617
default_expr:
101417
- if( exprAlwaysTrue(pExpr) ){
101618
+ if( ExprAlwaysTrue(pExpr) ){
101418101619
sqlite3VdbeGoto(v, dest);
101419
- }else if( exprAlwaysFalse(pExpr) ){
101620
+ }else if( ExprAlwaysFalse(pExpr) ){
101420101621
/* No-op */
101421101622
}else{
101422101623
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
101423101624
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
101424101625
VdbeCoverage(v);
@@ -101482,22 +101683,27 @@
101482101683
assert( pExpr->op!=TK_LE || op==OP_Gt );
101483101684
assert( pExpr->op!=TK_GT || op==OP_Le );
101484101685
assert( pExpr->op!=TK_GE || op==OP_Lt );
101485101686
101486101687
switch( pExpr->op ){
101487
- case TK_AND: {
101488
- testcase( jumpIfNull==0 );
101489
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
101490
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101491
- break;
101492
- }
101688
+ case TK_AND:
101493101689
case TK_OR: {
101494
- int d2 = sqlite3VdbeMakeLabel(pParse);
101495
- testcase( jumpIfNull==0 );
101496
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
101497
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101498
- sqlite3VdbeResolveLabel(v, d2);
101690
+ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
101691
+ if( pAlt!=pExpr ){
101692
+ sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
101693
+ }else if( pExpr->op==TK_AND ){
101694
+ testcase( jumpIfNull==0 );
101695
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
101696
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101697
+ }else{
101698
+ int d2 = sqlite3VdbeMakeLabel(pParse);
101699
+ testcase( jumpIfNull==0 );
101700
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
101701
+ jumpIfNull^SQLITE_JUMPIFNULL);
101702
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101703
+ sqlite3VdbeResolveLabel(v, d2);
101704
+ }
101499101705
break;
101500101706
}
101501101707
case TK_NOT: {
101502101708
testcase( jumpIfNull==0 );
101503101709
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -101582,13 +101788,13 @@
101582101788
break;
101583101789
}
101584101790
#endif
101585101791
default: {
101586101792
default_expr:
101587
- if( exprAlwaysFalse(pExpr) ){
101793
+ if( ExprAlwaysFalse(pExpr) ){
101588101794
sqlite3VdbeGoto(v, dest);
101589
- }else if( exprAlwaysTrue(pExpr) ){
101795
+ }else if( ExprAlwaysTrue(pExpr) ){
101590101796
/* no-op */
101591101797
}else{
101592101798
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
101593101799
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
101594101800
VdbeCoverage(v);
@@ -101822,11 +102028,15 @@
101822102028
&& (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
101823102029
|| sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
101824102030
){
101825102031
return 1;
101826102032
}
101827
- if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
102033
+ if( pE2->op==TK_NOTNULL
102034
+ && pE1->op!=TK_ISNULL
102035
+ && pE1->op!=TK_IS
102036
+ && pE1->op!=TK_OR
102037
+ ){
101828102038
Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
101829102039
testcase( pX!=pE1->pLeft );
101830102040
if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
101831102041
}
101832102042
return 0;
@@ -102399,11 +102609,11 @@
102399102609
*/
102400102610
static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
102401102611
sqlite3NestedParse(pParse,
102402102612
"SELECT 1 "
102403102613
"FROM \"%w\".%s "
102404
- "WHERE name NOT LIKE 'sqlite_%%'"
102614
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
102405102615
" AND sql NOT LIKE 'create virtual%%'"
102406102616
" AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
102407102617
zDb, MASTER_NAME,
102408102618
zDb, bTemp
102409102619
);
@@ -102410,11 +102620,11 @@
102410102620
102411102621
if( bTemp==0 ){
102412102622
sqlite3NestedParse(pParse,
102413102623
"SELECT 1 "
102414102624
"FROM temp.%s "
102415
- "WHERE name NOT LIKE 'sqlite_%%'"
102625
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
102416102626
" AND sql NOT LIKE 'create virtual%%'"
102417102627
" AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
102418102628
MASTER_NAME, zDb
102419102629
);
102420102630
}
@@ -102531,11 +102741,11 @@
102531102741
** the schema to use the new table name. */
102532102742
sqlite3NestedParse(pParse,
102533102743
"UPDATE \"%w\".%s SET "
102534102744
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
102535102745
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
102536
- "AND name NOT LIKE 'sqlite_%%'"
102746
+ "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
102537102747
, zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
102538102748
);
102539102749
102540102750
/* Update the tbl_name and name columns of the sqlite_master table
102541102751
** as required. */
@@ -102542,11 +102752,12 @@
102542102752
sqlite3NestedParse(pParse,
102543102753
"UPDATE %Q.%s SET "
102544102754
"tbl_name = %Q, "
102545102755
"name = CASE "
102546102756
"WHEN type='table' THEN %Q "
102547
- "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
102757
+ "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
102758
+ " AND type='index' THEN "
102548102759
"'sqlite_autoindex_' || %Q || substr(name,%d+18) "
102549102760
"ELSE name END "
102550102761
"WHERE tbl_name=%Q COLLATE nocase AND "
102551102762
"(type='table' OR type='index' OR type='trigger');",
102552102763
zDb, MASTER_NAME,
@@ -102916,11 +103127,12 @@
102916103127
assert( pNew->n>0 );
102917103128
bQuote = sqlite3Isquote(pNew->z[0]);
102918103129
sqlite3NestedParse(pParse,
102919103130
"UPDATE \"%w\".%s SET "
102920103131
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
102921
- "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
103132
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
103133
+ " AND (type != 'index' OR tbl_name = %Q)"
102922103134
" AND sql NOT LIKE 'create virtual%%'",
102923103135
zDb, MASTER_NAME,
102924103136
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
102925103137
pTab->zName
102926103138
);
@@ -108168,11 +108380,11 @@
108168108380
**
108169108381
** This is goofy. But to preserve backwards compatibility we continue to
108170108382
** accept it. This routine does the necessary conversion. It converts
108171108383
** the expression given in its argument from a TK_STRING into a TK_ID
108172108384
** if the expression is just a TK_STRING with an optional COLLATE clause.
108173
-** If the epxression is anything other than TK_STRING, the expression is
108385
+** If the expression is anything other than TK_STRING, the expression is
108174108386
** unchanged.
108175108387
*/
108176108388
static void sqlite3StringToId(Expr *p){
108177108389
if( p->op==TK_STRING ){
108178108390
p->op = TK_ID;
@@ -108565,14 +108777,55 @@
108565108777
wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
108566108778
}
108567108779
pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
108568108780
}
108569108781
108570
-/* Return true if value x is found any of the first nCol entries of aiCol[]
108782
+/* Return true if column number x is any of the first nCol entries of aiCol[].
108783
+** This is used to determine if the column number x appears in any of the
108784
+** first nCol entries of an index.
108571108785
*/
108572108786
static int hasColumn(const i16 *aiCol, int nCol, int x){
108573
- while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
108787
+ while( nCol-- > 0 ){
108788
+ assert( aiCol[0]>=0 );
108789
+ if( x==*(aiCol++) ){
108790
+ return 1;
108791
+ }
108792
+ }
108793
+ return 0;
108794
+}
108795
+
108796
+/*
108797
+** Return true if any of the first nKey entries of index pIdx exactly
108798
+** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID
108799
+** PRIMARY KEY index. pIdx is an index on the same table. pIdx may
108800
+** or may not be the same index as pPk.
108801
+**
108802
+** The first nKey entries of pIdx are guaranteed to be ordinary columns,
108803
+** not a rowid or expression.
108804
+**
108805
+** This routine differs from hasColumn() in that both the column and the
108806
+** collating sequence must match for this routine, but for hasColumn() only
108807
+** the column name must match.
108808
+*/
108809
+static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
108810
+ int i, j;
108811
+ assert( nKey<=pIdx->nColumn );
108812
+ assert( iCol<MAX(pPk->nColumn,pPk->nKeyCol) );
108813
+ assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
108814
+ assert( pPk->pTable->tabFlags & TF_WithoutRowid );
108815
+ assert( pPk->pTable==pIdx->pTable );
108816
+ testcase( pPk==pIdx );
108817
+ j = pPk->aiColumn[iCol];
108818
+ assert( j!=XN_ROWID && j!=XN_EXPR );
108819
+ for(i=0; i<nKey; i++){
108820
+ assert( pIdx->aiColumn[i]>=0 || j>=0 );
108821
+ if( pIdx->aiColumn[i]==j
108822
+ && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
108823
+ ){
108824
+ return 1;
108825
+ }
108826
+ }
108574108827
return 0;
108575108828
}
108576108829
108577108830
/* Recompute the colNotIdxed field of the Index.
108578108831
**
@@ -108657,17 +108910,20 @@
108657108910
Token ipkToken;
108658108911
sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
108659108912
pList = sqlite3ExprListAppend(pParse, 0,
108660108913
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
108661108914
if( pList==0 ) return;
108915
+ if( IN_RENAME_OBJECT ){
108916
+ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
108917
+ }
108662108918
pList->a[0].sortOrder = pParse->iPkSortOrder;
108663108919
assert( pParse->pNewTable==pTab );
108920
+ pTab->iPKey = -1;
108664108921
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
108665108922
SQLITE_IDXTYPE_PRIMARYKEY);
108666108923
if( db->mallocFailed || pParse->nErr ) return;
108667108924
pPk = sqlite3PrimaryKeyIndex(pTab);
108668
- pTab->iPKey = -1;
108669108925
}else{
108670108926
pPk = sqlite3PrimaryKeyIndex(pTab);
108671108927
assert( pPk!=0 );
108672108928
108673108929
/*
@@ -108674,13 +108930,14 @@
108674108930
** Remove all redundant columns from the PRIMARY KEY. For example, change
108675108931
** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
108676108932
** code assumes the PRIMARY KEY contains no repeated columns.
108677108933
*/
108678108934
for(i=j=1; i<pPk->nKeyCol; i++){
108679
- if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
108935
+ if( isDupColumn(pPk, j, pPk, i) ){
108680108936
pPk->nColumn--;
108681108937
}else{
108938
+ testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
108682108939
pPk->aiColumn[j++] = pPk->aiColumn[i];
108683108940
}
108684108941
}
108685108942
pPk->nKeyCol = j;
108686108943
}
@@ -108706,20 +108963,24 @@
108706108963
*/
108707108964
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
108708108965
int n;
108709108966
if( IsPrimaryKeyIndex(pIdx) ) continue;
108710108967
for(i=n=0; i<nPk; i++){
108711
- if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
108968
+ if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
108969
+ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
108970
+ n++;
108971
+ }
108712108972
}
108713108973
if( n==0 ){
108714108974
/* This index is a superset of the primary key */
108715108975
pIdx->nColumn = pIdx->nKeyCol;
108716108976
continue;
108717108977
}
108718108978
if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
108719108979
for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
108720
- if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
108980
+ if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
108981
+ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
108721108982
pIdx->aiColumn[j] = pPk->aiColumn[i];
108722108983
pIdx->azColl[j] = pPk->azColl[i];
108723108984
j++;
108724108985
}
108725108986
}
@@ -110231,13 +110492,14 @@
110231110492
*/
110232110493
if( pPk ){
110233110494
for(j=0; j<pPk->nKeyCol; j++){
110234110495
int x = pPk->aiColumn[j];
110235110496
assert( x>=0 );
110236
- if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
110497
+ if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
110237110498
pIndex->nColumn--;
110238110499
}else{
110500
+ testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
110239110501
pIndex->aiColumn[i] = x;
110240110502
pIndex->azColl[i] = pPk->azColl[j];
110241110503
pIndex->aSortOrder[i] = pPk->aSortOrder[j];
110242110504
i++;
110243110505
}
@@ -113004,10 +113266,11 @@
113004113266
** time functions, are implemented separately.)
113005113267
*/
113006113268
/* #include "sqliteInt.h" */
113007113269
/* #include <stdlib.h> */
113008113270
/* #include <assert.h> */
113271
+/* #include <math.h> */
113009113272
/* #include "vdbeInt.h" */
113010113273
113011113274
/*
113012113275
** Return the collating function associated with a function.
113013113276
*/
@@ -113384,11 +113647,14 @@
113384113647
zBuf = sqlite3_mprintf("%.*f",n,r);
113385113648
if( zBuf==0 ){
113386113649
sqlite3_result_error_nomem(context);
113387113650
return;
113388113651
}
113389
- sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
113652
+ if( !sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8) ){
113653
+ assert( sqlite3_strglob("*Inf", zBuf)==0 );
113654
+ r = zBuf[0]=='-' ? -HUGE_VAL : +HUGE_VAL;
113655
+ }
113390113656
sqlite3_free(zBuf);
113391113657
}
113392113658
sqlite3_result_double(context, r);
113393113659
}
113394113660
#endif
@@ -113831,12 +114097,10 @@
113831114097
#endif
113832114098
sqlite3_result_int(context, 0);
113833114099
return;
113834114100
}
113835114101
#endif
113836
- zB = sqlite3_value_text(argv[0]);
113837
- zA = sqlite3_value_text(argv[1]);
113838114102
113839114103
/* Limit the length of the LIKE or GLOB pattern to avoid problems
113840114104
** of deep recursion and N*N behavior in patternCompare().
113841114105
*/
113842114106
nPat = sqlite3_value_bytes(argv[0]);
@@ -113844,12 +114108,10 @@
113844114108
testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
113845114109
if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
113846114110
sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
113847114111
return;
113848114112
}
113849
- assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
113850
-
113851114113
if( argc==3 ){
113852114114
/* The escape character string must consist of a single UTF-8 character.
113853114115
** Otherwise, return an error.
113854114116
*/
113855114117
const unsigned char *zEsc = sqlite3_value_text(argv[2]);
@@ -113861,10 +114123,12 @@
113861114123
}
113862114124
escape = sqlite3Utf8Read(&zEsc);
113863114125
}else{
113864114126
escape = pInfo->matchSet;
113865114127
}
114128
+ zB = sqlite3_value_text(argv[0]);
114129
+ zA = sqlite3_value_text(argv[1]);
113866114130
if( zA && zB ){
113867114131
#ifdef SQLITE_TEST
113868114132
sqlite3_like_count++;
113869114133
#endif
113870114134
sqlite3_result_int(context,
@@ -114786,43 +115050,28 @@
114786115050
sqlite3OomFault(db);
114787115051
}
114788115052
}
114789115053
114790115054
/*
114791
-** Set the LIKEOPT flag on the 2-argument function with the given name.
114792
-*/
114793
-static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
114794
- FuncDef *pDef;
114795
- pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
114796
- if( ALWAYS(pDef) ){
114797
- pDef->funcFlags |= flagVal;
114798
- }
114799
- pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0);
114800
- if( pDef ){
114801
- pDef->funcFlags |= flagVal;
114802
- }
114803
-}
114804
-
114805
-/*
114806
-** Register the built-in LIKE and GLOB functions. The caseSensitive
115055
+** Re-register the built-in LIKE functions. The caseSensitive
114807115056
** parameter determines whether or not the LIKE operator is case
114808
-** sensitive. GLOB is always case sensitive.
115057
+** sensitive.
114809115058
*/
114810115059
SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
114811115060
struct compareInfo *pInfo;
115061
+ int flags;
114812115062
if( caseSensitive ){
114813115063
pInfo = (struct compareInfo*)&likeInfoAlt;
115064
+ flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
114814115065
}else{
114815115066
pInfo = (struct compareInfo*)&likeInfoNorm;
115067
+ flags = SQLITE_FUNC_LIKE;
114816115068
}
114817115069
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
114818115070
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
114819
- sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
114820
- (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
114821
- setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
114822
- setLikeOptFlag(db, "like",
114823
- caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
115071
+ sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
115072
+ sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
114824115073
}
114825115074
114826115075
/*
114827115076
** pExpr points to an expression which implements a function. If
114828115077
** it is appropriate to apply the LIKE optimization to that function
@@ -115608,11 +115857,11 @@
115608115857
iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
115609115858
assert( iCol>=0 );
115610115859
zCol = pFKey->pFrom->aCol[iCol].zName;
115611115860
pRight = sqlite3Expr(db, TK_ID, zCol);
115612115861
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
115613
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
115862
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
115614115863
}
115615115864
115616115865
/* If the child table is the same as the parent table, then add terms
115617115866
** to the WHERE clause that prevent this entry from being scanned.
115618115867
** The added WHERE clause terms are like this:
@@ -115642,15 +115891,15 @@
115642115891
i16 iCol = pIdx->aiColumn[i];
115643115892
assert( iCol>=0 );
115644115893
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
115645115894
pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
115646115895
pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
115647
- pAll = sqlite3ExprAnd(db, pAll, pEq);
115896
+ pAll = sqlite3ExprAnd(pParse, pAll, pEq);
115648115897
}
115649115898
pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
115650115899
}
115651
- pWhere = sqlite3ExprAnd(db, pWhere, pNe);
115900
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
115652115901
}
115653115902
115654115903
/* Resolve the references in the WHERE clause. */
115655115904
memset(&sNameContext, 0, sizeof(NameContext));
115656115905
sNameContext.pSrcList = pSrc;
@@ -116252,11 +116501,11 @@
116252116501
sqlite3PExpr(pParse, TK_DOT,
116253116502
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
116254116503
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
116255116504
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
116256116505
);
116257
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
116506
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
116258116507
116259116508
/* For ON UPDATE, construct the next term of the WHEN clause.
116260116509
** The final WHEN clause will be like this:
116261116510
**
116262116511
** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
@@ -116268,11 +116517,11 @@
116268116517
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
116269116518
sqlite3PExpr(pParse, TK_DOT,
116270116519
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
116271116520
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
116272116521
);
116273
- pWhen = sqlite3ExprAnd(db, pWhen, pEq);
116522
+ pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
116274116523
}
116275116524
116276116525
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
116277116526
Expr *pNew;
116278116527
if( action==OE_Cascade ){
@@ -117265,19 +117514,20 @@
117265117514
/* If this is not a view, open the table and and all indices */
117266117515
if( !isView ){
117267117516
int nIdx;
117268117517
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
117269117518
&iDataCur, &iIdxCur);
117270
- aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
117519
+ aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
117271117520
if( aRegIdx==0 ){
117272117521
goto insert_cleanup;
117273117522
}
117274117523
for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
117275117524
assert( pIdx );
117276117525
aRegIdx[i] = ++pParse->nMem;
117277117526
pParse->nMem += pIdx->nColumn;
117278117527
}
117528
+ aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
117279117529
}
117280117530
#ifndef SQLITE_OMIT_UPSERT
117281117531
if( pUpsert ){
117282117532
if( IsVirtual(pTab) ){
117283117533
sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
@@ -117676,10 +117926,18 @@
117676117926
** The code generated by this routine will store new index entries into
117677117927
** registers identified by aRegIdx[]. No index entry is created for
117678117928
** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
117679117929
** the same as the order of indices on the linked list of indices
117680117930
** at pTab->pIndex.
117931
+**
117932
+** (2019-05-07) The generated code also creates a new record for the
117933
+** main table, if pTab is a rowid table, and stores that record in the
117934
+** register identified by aRegIdx[nIdx] - in other words in the first
117935
+** entry of aRegIdx[] past the last index. It is important that the
117936
+** record be generated during constraint checks to avoid affinity changes
117937
+** to the register content that occur after constraint checks but before
117938
+** the new record is inserted.
117681117939
**
117682117940
** The caller must have already opened writeable cursors on the main
117683117941
** table and all applicable indices (that is to say, all indices for which
117684117942
** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
117685117943
** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
@@ -118295,10 +118553,20 @@
118295118553
if( ipkTop ){
118296118554
sqlite3VdbeGoto(v, ipkTop);
118297118555
VdbeComment((v, "Do IPK REPLACE"));
118298118556
sqlite3VdbeJumpHere(v, ipkBottom);
118299118557
}
118558
+
118559
+ /* Generate the table record */
118560
+ if( HasRowid(pTab) ){
118561
+ int regRec = aRegIdx[ix];
118562
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec);
118563
+ sqlite3SetMakeRecordP5(v, pTab);
118564
+ if( !bAffinityDone ){
118565
+ sqlite3TableAffinity(v, pTab, 0);
118566
+ }
118567
+ }
118300118568
118301118569
*pbMayReplace = seenReplace;
118302118570
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
118303118571
}
118304118572
@@ -118345,14 +118613,11 @@
118345118613
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
118346118614
){
118347118615
Vdbe *v; /* Prepared statements under construction */
118348118616
Index *pIdx; /* An index being inserted or updated */
118349118617
u8 pik_flags; /* flag values passed to the btree insert */
118350
- int regData; /* Content registers (after the rowid) */
118351
- int regRec; /* Register holding assembled record for the table */
118352118618
int i; /* Loop counter */
118353
- u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
118354118619
118355118620
assert( update_flags==0
118356118621
|| update_flags==OPFLAG_ISUPDATE
118357118622
|| update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
118358118623
);
@@ -118360,11 +118625,10 @@
118360118625
v = sqlite3GetVdbe(pParse);
118361118626
assert( v!=0 );
118362118627
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
118363118628
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
118364118629
if( aRegIdx[i]==0 ) continue;
118365
- bAffinityDone = 1;
118366118630
if( pIdx->pPartIdxWhere ){
118367118631
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
118368118632
VdbeCoverage(v);
118369118633
}
118370118634
pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
@@ -118388,17 +118652,10 @@
118388118652
aRegIdx[i]+1,
118389118653
pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
118390118654
sqlite3VdbeChangeP5(v, pik_flags);
118391118655
}
118392118656
if( !HasRowid(pTab) ) return;
118393
- regData = regNewData + 1;
118394
- regRec = sqlite3GetTempReg(pParse);
118395
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
118396
- sqlite3SetMakeRecordP5(v, pTab);
118397
- if( !bAffinityDone ){
118398
- sqlite3TableAffinity(v, pTab, 0);
118399
- }
118400118657
if( pParse->nested ){
118401118658
pik_flags = 0;
118402118659
}else{
118403118660
pik_flags = OPFLAG_NCHANGE;
118404118661
pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
@@ -118407,11 +118664,11 @@
118407118664
pik_flags |= OPFLAG_APPEND;
118408118665
}
118409118666
if( useSeekResult ){
118410118667
pik_flags |= OPFLAG_USESEEKRESULT;
118411118668
}
118412
- sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
118669
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
118413118670
if( !pParse->nested ){
118414118671
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
118415118672
}
118416118673
sqlite3VdbeChangeP5(v, pik_flags);
118417118674
}
@@ -120725,15 +120982,17 @@
120725120982
/* ePragTyp: */ PragTyp_CACHE_SPILL,
120726120983
/* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
120727120984
/* ColNames: */ 0, 0,
120728120985
/* iArg: */ 0 },
120729120986
#endif
120987
+#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
120730120988
{/* zName: */ "case_sensitive_like",
120731120989
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
120732120990
/* ePragFlg: */ PragFlg_NoColumns,
120733120991
/* ColNames: */ 0, 0,
120734120992
/* iArg: */ 0 },
120993
+#endif
120735120994
{/* zName: */ "cell_size_check",
120736120995
/* ePragTyp: */ PragTyp_FLAG,
120737120996
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
120738120997
/* ColNames: */ 0, 0,
120739120998
/* iArg: */ SQLITE_CellSizeCk },
@@ -122610,19 +122869,21 @@
122610122869
}
122611122870
break;
122612122871
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
122613122872
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
122614122873
122874
+#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
122615122875
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
122616122876
** used will be case sensitive or not depending on the RHS.
122617122877
*/
122618122878
case PragTyp_CASE_SENSITIVE_LIKE: {
122619122879
if( zRight ){
122620122880
sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
122621122881
}
122622122882
}
122623122883
break;
122884
+#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
122624122885
122625122886
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
122626122887
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
122627122888
#endif
122628122889
@@ -124974,11 +125235,11 @@
124974125235
ExprSetProperty(pEq, EP_FromJoin);
124975125236
assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
124976125237
ExprSetVVAProperty(pEq, EP_NoReduce);
124977125238
pEq->iRightJoinTable = (i16)pE2->iTable;
124978125239
}
124979
- *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
125240
+ *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
124980125241
}
124981125242
124982125243
/*
124983125244
** Set the EP_FromJoin property on all terms of the given expression.
124984125245
** And set the Expr.iRightJoinTable to iTable for every term in the
@@ -125108,11 +125369,11 @@
125108125369
/* Add the ON clause to the end of the WHERE clause, connected by
125109125370
** an AND operator.
125110125371
*/
125111125372
if( pRight->pOn ){
125112125373
if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
125113
- p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
125374
+ p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
125114125375
pRight->pOn = 0;
125115125376
}
125116125377
125117125378
/* Create extra terms on the WHERE clause for each column named
125118125379
** in the USING clause. Example: If the two tables to be joined are
@@ -128653,11 +128914,11 @@
128653128914
pWhere = pSub->pWhere;
128654128915
pSub->pWhere = 0;
128655128916
if( isLeftJoin>0 ){
128656128917
setJoinExpr(pWhere, iNewParent);
128657128918
}
128658
- pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
128919
+ pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere);
128659128920
if( db->mallocFailed==0 ){
128660128921
SubstContext x;
128661128922
x.pParse = pParse;
128662128923
x.iTable = iParent;
128663128924
x.iNewTable = iNewParent;
@@ -128988,13 +129249,13 @@
128988129249
x.iNewTable = iCursor;
128989129250
x.isLeftJoin = 0;
128990129251
x.pEList = pSubq->pEList;
128991129252
pNew = substExpr(&x, pNew);
128992129253
if( pSubq->selFlags & SF_Aggregate ){
128993
- pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
129254
+ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
128994129255
}else{
128995
- pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
129256
+ pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
128996129257
}
128997129258
pSubq = pSubq->pPrior;
128998129259
}
128999129260
}
129000129261
return nChng;
@@ -129416,11 +129677,11 @@
129416129677
sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
129417129678
pTab->iPKey = -1;
129418129679
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
129419129680
pTab->tabFlags |= TF_Ephemeral;
129420129681
129421
- return SQLITE_OK;
129682
+ return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
129422129683
}
129423129684
129424129685
/*
129425129686
** This routine is a Walker callback for "expanding" a SELECT statement.
129426129687
** "Expanding" means to do the following:
@@ -130037,11 +130298,11 @@
130037130298
sqlite3 *db = pWalker->pParse->db;
130038130299
Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
130039130300
if( pNew ){
130040130301
Expr *pWhere = pS->pWhere;
130041130302
SWAP(Expr, *pNew, *pExpr);
130042
- pNew = sqlite3ExprAnd(db, pWhere, pNew);
130303
+ pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
130043130304
pS->pWhere = pNew;
130044130305
pWalker->eCode = 1;
130045130306
}
130046130307
}
130047130308
return WRC_Prune;
@@ -130100,11 +130361,13 @@
130100130361
if( pThis->pSelect->selId!=pS1->selId ){
130101130362
/* The query flattener left two different CTE tables with identical
130102130363
** names in the same FROM clause. */
130103130364
continue;
130104130365
}
130105
- if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
130366
+ if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
130367
+ || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1)
130368
+ ){
130106130369
/* The view was modified by some other optimization such as
130107130370
** pushDownWhereTerms() */
130108130371
continue;
130109130372
}
130110130373
return pItem;
@@ -132786,15 +133049,16 @@
132786133049
WhereInfo *pWInfo; /* Information about the WHERE clause */
132787133050
Vdbe *v; /* The virtual database engine */
132788133051
Index *pIdx; /* For looping over indices */
132789133052
Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
132790133053
int nIdx; /* Number of indices that need updating */
133054
+ int nAllIdx; /* Total number of indexes */
132791133055
int iBaseCur; /* Base cursor number */
132792133056
int iDataCur; /* Cursor for the canonical data btree */
132793133057
int iIdxCur; /* Cursor for the first index */
132794133058
sqlite3 *db; /* The database structure */
132795
- int *aRegIdx = 0; /* First register in array assigned to each index */
133059
+ int *aRegIdx = 0; /* Registers for to each index and the main table */
132796133060
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
132797133061
** an expression for the i-th column of the table.
132798133062
** aXRef[i]==-1 if the i-th column is not changed. */
132799133063
u8 *aToOpen; /* 1 for tables and indices to be opened */
132800133064
u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */
@@ -132904,14 +133168,14 @@
132904133168
pTabList->a[0].iCursor = iDataCur;
132905133169
132906133170
/* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
132907133171
** Initialize aXRef[] and aToOpen[] to their default values.
132908133172
*/
132909
- aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
133173
+ aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
132910133174
if( aXRef==0 ) goto update_cleanup;
132911133175
aRegIdx = aXRef+pTab->nCol;
132912
- aToOpen = (u8*)(aRegIdx+nIdx);
133176
+ aToOpen = (u8*)(aRegIdx+nIdx+1);
132913133177
memset(aToOpen, 1, nIdx+1);
132914133178
aToOpen[nIdx+1] = 0;
132915133179
for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
132916133180
132917133181
/* Initialize the name-context */
@@ -132986,11 +133250,11 @@
132986133250
/* There is one entry in the aRegIdx[] array for each index on the table
132987133251
** being updated. Fill in aRegIdx[] with a register number that will hold
132988133252
** the key for accessing each index.
132989133253
*/
132990133254
if( onError==OE_Replace ) bReplace = 1;
132991
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
133255
+ for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
132992133256
int reg;
132993133257
if( chngKey || hasFK>1 || pIdx==pPk
132994133258
|| indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
132995133259
){
132996133260
reg = ++pParse->nMem;
@@ -133006,13 +133270,14 @@
133006133270
}
133007133271
break;
133008133272
}
133009133273
}
133010133274
}
133011
- if( reg==0 ) aToOpen[j+1] = 0;
133012
- aRegIdx[j] = reg;
133275
+ if( reg==0 ) aToOpen[nAllIdx+1] = 0;
133276
+ aRegIdx[nAllIdx] = reg;
133013133277
}
133278
+ aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */
133014133279
if( bReplace ){
133015133280
/* If REPLACE conflict resolution might be invoked, open cursors on all
133016133281
** indexes in case they are needed to delete records. */
133017133282
memset(aToOpen, 1, nIdx+1);
133018133283
}
@@ -133023,11 +133288,17 @@
133023133288
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
133024133289
sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
133025133290
133026133291
/* Allocate required registers. */
133027133292
if( !IsVirtual(pTab) ){
133028
- regRowSet = ++pParse->nMem;
133293
+ /* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
133294
+ ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
133295
+ ** reallocated. aRegIdx[nAllIdx] is the register in which the main
133296
+ ** table record is written. regRowSet holds the RowSet for the
133297
+ ** two-pass update algorithm. */
133298
+ assert( aRegIdx[nAllIdx]==pParse->nMem );
133299
+ regRowSet = aRegIdx[nAllIdx];
133029133300
regOldRowid = regNewRowid = ++pParse->nMem;
133030133301
if( chngPk || pTrigger || hasFK ){
133031133302
regOld = pParse->nMem + 1;
133032133303
pParse->nMem += pTab->nCol;
133033133304
}
@@ -133153,10 +133424,12 @@
133153133424
/* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
133154133425
** mode, write the rowid into the FIFO. In either of the one-pass modes,
133155133426
** leave it in register regOldRowid. */
133156133427
sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
133157133428
if( eOnePass==ONEPASS_OFF ){
133429
+ /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
133430
+ aRegIdx[nAllIdx] = ++pParse->nMem;
133158133431
sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
133159133432
}
133160133433
}else{
133161133434
/* Read the PK of the current row into an array of registers. In
133162133435
** ONEPASS_OFF mode, serialize the array into a record and store it in
@@ -133984,10 +134257,11 @@
133984134257
*/
133985134258
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
133986134259
Vdbe *v = sqlite3GetVdbe(pParse);
133987134260
int iDb = 0;
133988134261
if( v==0 ) goto build_vacuum_end;
134262
+ if( pParse->nErr ) goto build_vacuum_end;
133989134263
if( pNm ){
133990134264
#ifndef SQLITE_BUG_COMPATIBLE_20160819
133991134265
/* Default behavior: Report an error if the argument to VACUUM is
133992134266
** not recognized */
133993134267
iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
@@ -135136,18 +135410,20 @@
135136135410
}
135137135411
}
135138135412
p = vtabDisconnectAll(db, pTab);
135139135413
xDestroy = p->pMod->pModule->xDestroy;
135140135414
assert( xDestroy!=0 ); /* Checked before the virtual table is created */
135415
+ pTab->nTabRef++;
135141135416
rc = xDestroy(p->pVtab);
135142135417
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
135143135418
if( rc==SQLITE_OK ){
135144135419
assert( pTab->pVTable==p && p->pNext==0 );
135145135420
p->pVtab = 0;
135146135421
pTab->pVTable = 0;
135147135422
sqlite3VtabUnlock(p);
135148135423
}
135424
+ sqlite3DeleteTable(db, pTab);
135149135425
}
135150135426
135151135427
return rc;
135152135428
}
135153135429
@@ -135586,10 +135862,12 @@
135586135862
**
135587135863
** This file contains structure and macro definitions for the query
135588135864
** planner logic in "where.c". These definitions are broken out into
135589135865
** a separate source file for easier editing.
135590135866
*/
135867
+#ifndef SQLITE_WHEREINT_H
135868
+#define SQLITE_WHEREINT_H
135591135869
135592135870
/*
135593135871
** Trace output macros
135594135872
*/
135595135873
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
@@ -136156,10 +136434,12 @@
136156136434
#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
136157136435
#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
136158136436
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
136159136437
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
136160136438
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
136439
+
136440
+#endif /* !defined(SQLITE_WHEREINT_H) */
136161136441
136162136442
/************** End of whereInt.h ********************************************/
136163136443
/************** Continuing where we left off in wherecode.c ******************/
136164136444
136165136445
#ifndef SQLITE_OMIT_EXPLAIN
@@ -137139,11 +137419,11 @@
137139137419
sqlite3WalkExpr(&sWalker, pTerm->pExpr);
137140137420
if( sWalker.eCode ) continue;
137141137421
}
137142137422
137143137423
/* If we survive all prior tests, that means this term is worth hinting */
137144
- pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
137424
+ pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
137145137425
}
137146137426
if( pExpr!=0 ){
137147137427
sWalker.xExprCallback = codeCursorHintFixExpr;
137148137428
sqlite3WalkExpr(&sWalker, pExpr);
137149137429
sqlite3VdbeAddOp4(v, OP_CursorHint,
@@ -138104,11 +138384,11 @@
138104138384
testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
138105138385
if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
138106138386
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
138107138387
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
138108138388
pExpr = sqlite3ExprDup(db, pExpr, 0);
138109
- pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
138389
+ pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
138110138390
}
138111138391
if( pAndExpr ){
138112138392
/* The extra 0x10000 bit on the opcode is masked off and does not
138113138393
** become part of the new Expr.op. However, it does make the
138114138394
** op==TK_AND comparison inside of sqlite3PExpr() false, and this
@@ -138255,11 +138535,11 @@
138255138535
}
138256138536
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
138257138537
sqlite3VdbeGoto(v, pLevel->addrBrk);
138258138538
sqlite3VdbeResolveLabel(v, iLoopBody);
138259138539
138260
- if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
138540
+ if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
138261138541
if( !untestedTerms ) disableTerm(pLevel, pTerm);
138262138542
}else
138263138543
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
138264138544
138265138545
{
@@ -138688,26 +138968,28 @@
138688138968
for(iFrom=iTo=0; iFrom<cnt; iFrom++){
138689138969
if( zNew[iFrom]==wc[3] ) iFrom++;
138690138970
zNew[iTo++] = zNew[iFrom];
138691138971
}
138692138972
zNew[iTo] = 0;
138973
+ assert( iTo>0 );
138693138974
138694
- /* If the RHS begins with a digit or a minus sign, then the LHS must be
138975
+ /* If the RHS begins with a digit or a +/- sign, then the LHS must be
138695138976
** an ordinary column (not a virtual table column) with TEXT affinity.
138696138977
** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
138697138978
** even though "lhs LIKE rhs" is true. But if the RHS does not start
138698
- ** with a digit or '-', then "lhs LIKE rhs" will always be false if
138979
+ ** with a digit or +/-, then "lhs LIKE rhs" will always be false if
138699138980
** the LHS is numeric and so the optimization still works.
138700138981
**
138701138982
** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
138702138983
** The RHS pattern must not be '/%' because the termination condition
138703138984
** will then become "x<'0'" and if the affinity is numeric, will then
138704138985
** be converted into "x<0", which is incorrect.
138705138986
*/
138706138987
if( sqlite3Isdigit(zNew[0])
138707138988
|| zNew[0]=='-'
138708
- || (zNew[0]+1=='0' && iTo==1)
138989
+ || zNew[0]=='+'
138990
+ || zNew[iTo-1]=='0'-1
138709138991
){
138710138992
if( pLeft->op!=TK_COLUMN
138711138993
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
138712138994
|| IsVirtual(pLeft->y.pTab) /* Value might be numeric */
138713138995
){
@@ -140770,11 +141052,11 @@
140770141052
|| pLoop->prereq!=0 ); /* table of a LEFT JOIN */
140771141053
if( pLoop->prereq==0
140772141054
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
140773141055
&& !ExprHasProperty(pExpr, EP_FromJoin)
140774141056
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
140775
- pPartial = sqlite3ExprAnd(pParse->db, pPartial,
141057
+ pPartial = sqlite3ExprAnd(pParse, pPartial,
140776141058
sqlite3ExprDup(pParse->db, pExpr, 0));
140777141059
}
140778141060
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
140779141061
int iCol = pTerm->u.leftColumn;
140780141062
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
@@ -146275,17 +146557,22 @@
146275146557
** expression list pList. Return a pointer to the result list.
146276146558
*/
146277146559
static ExprList *exprListAppendList(
146278146560
Parse *pParse, /* Parsing context */
146279146561
ExprList *pList, /* List to which to append. Might be NULL */
146280
- ExprList *pAppend /* List of values to append. Might be NULL */
146562
+ ExprList *pAppend, /* List of values to append. Might be NULL */
146563
+ int bIntToNull
146281146564
){
146282146565
if( pAppend ){
146283146566
int i;
146284146567
int nInit = pList ? pList->nExpr : 0;
146285146568
for(i=0; i<pAppend->nExpr; i++){
146286146569
Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
146570
+ if( bIntToNull && pDup && pDup->op==TK_INTEGER ){
146571
+ pDup->op = TK_NULL;
146572
+ pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
146573
+ }
146287146574
pList = sqlite3ExprListAppend(pParse, pList, pDup);
146288146575
if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
146289146576
}
146290146577
}
146291146578
return pList;
@@ -146321,11 +146608,11 @@
146321146608
146322146609
/* Create the ORDER BY clause for the sub-select. This is the concatenation
146323146610
** of the window PARTITION and ORDER BY clauses. Then, if this makes it
146324146611
** redundant, remove the ORDER BY from the parent SELECT. */
146325146612
pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
146326
- pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
146613
+ pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
146327146614
if( pSort && p->pOrderBy ){
146328146615
if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
146329146616
sqlite3ExprListDelete(db, p->pOrderBy);
146330146617
p->pOrderBy = 0;
146331146618
}
@@ -146342,20 +146629,20 @@
146342146629
pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
146343146630
146344146631
/* Append the PARTITION BY and ORDER BY expressions to the to the
146345146632
** sub-select expression list. They are required to figure out where
146346146633
** boundaries for partitions and sets of peer rows lie. */
146347
- pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
146348
- pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
146634
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
146635
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
146349146636
146350146637
/* Append the arguments passed to each window function to the
146351146638
** sub-select expression list. Also allocate two registers for each
146352146639
** window function - one for the accumulator, another for interim
146353146640
** results. */
146354146641
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
146355146642
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
146356
- pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
146643
+ pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
146357146644
if( pWin->pFilter ){
146358146645
Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
146359146646
pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
146360146647
}
146361146648
pWin->regAccum = ++pParse->nMem;
@@ -152081,11 +152368,13 @@
152081152368
sqlite3ExprListDelete(pParse->db, pList);
152082152369
}
152083152370
}
152084152371
break;
152085152372
case 179: /* expr ::= expr AND expr */
152086
- case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180);
152373
+{yymsp[-2].minor.yy524=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy524,yymsp[0].minor.yy524);}
152374
+ break;
152375
+ case 180: /* expr ::= expr OR expr */
152087152376
case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
152088152377
case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
152089152378
case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
152090152379
case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
152091152380
case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
@@ -158717,10 +159006,26 @@
158717159006
FILE *out = va_arg(ap, FILE*);
158718159007
if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
158719159008
break;
158720159009
}
158721159010
#endif /* defined(YYCOVERAGE) */
159011
+
159012
+ /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
159013
+ **
159014
+ ** This test-control causes the most recent sqlite3_result_int64() value
159015
+ ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally,
159016
+ ** MEM_IntReal values only arise during an INSERT operation of integer
159017
+ ** values into a REAL column, so they can be challenging to test. This
159018
+ ** test-control enables us to write an intreal() SQL function that can
159019
+ ** inject an intreal() value at arbitrary places in an SQL statement,
159020
+ ** for testing purposes.
159021
+ */
159022
+ case SQLITE_TESTCTRL_RESULT_INTREAL: {
159023
+ sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
159024
+ sqlite3ResultIntReal(pCtx);
159025
+ break;
159026
+ }
158722159027
}
158723159028
va_end(ap);
158724159029
#endif /* SQLITE_UNTESTABLE */
158725159030
return rc;
158726159031
}
@@ -174130,11 +174435,11 @@
174130174435
if( bFirst==0 ){
174131174436
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
174132174437
}
174133174438
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
174134174439
174135
- if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
174440
+ if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
174136174441
return FTS_CORRUPT_VTAB;
174137174442
}
174138174443
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
174139174444
if( rc==SQLITE_OK ){
174140174445
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -174149,11 +174454,11 @@
174149174454
p->iOff += p->nDoclist;
174150174455
}
174151174456
}
174152174457
}
174153174458
174154
- assert( p->iOff<=p->nNode );
174459
+ assert_fts3_nc( p->iOff<=p->nNode );
174155174460
return rc;
174156174461
}
174157174462
174158174463
/*
174159174464
** Release all dynamic resources held by node-reader object *p.
@@ -189790,11 +190095,12 @@
189790190095
assert( argc==1 || argc==2 );
189791190096
189792190097
zIn = (const char*)sqlite3_value_text(argv[0]);
189793190098
if( zIn ){
189794190099
if( rbuIsVacuum(p) ){
189795
- if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
190100
+ assert( argc==2 );
190101
+ if( 0==sqlite3_value_int(argv[1]) ){
189796190102
sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
189797190103
}
189798190104
}else{
189799190105
if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
189800190106
int i;
@@ -190241,11 +190547,12 @@
190241190547
SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
190242190548
SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
190243190549
}
190244190550
190245190551
pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
190246
- pIter->abTblPk[iOrder] = (iPk!=0);
190552
+ assert( iPk>=0 );
190553
+ pIter->abTblPk[iOrder] = (u8)iPk;
190247190554
pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
190248190555
iOrder++;
190249190556
}
190250190557
}
190251190558
@@ -190275,10 +190582,217 @@
190275190582
zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
190276190583
zSep = ", ";
190277190584
}
190278190585
return zList;
190279190586
}
190587
+
190588
+/*
190589
+** Return a comma separated list of the quoted PRIMARY KEY column names,
190590
+** in order, for the current table. Before each column name, add the text
190591
+** zPre. After each column name, add the zPost text. Use zSeparator as
190592
+** the separator text (usually ", ").
190593
+*/
190594
+static char *rbuObjIterGetPkList(
190595
+ sqlite3rbu *p, /* RBU object */
190596
+ RbuObjIter *pIter, /* Object iterator for column names */
190597
+ const char *zPre, /* Before each quoted column name */
190598
+ const char *zSeparator, /* Separator to use between columns */
190599
+ const char *zPost /* After each quoted column name */
190600
+){
190601
+ int iPk = 1;
190602
+ char *zRet = 0;
190603
+ const char *zSep = "";
190604
+ while( 1 ){
190605
+ int i;
190606
+ for(i=0; i<pIter->nTblCol; i++){
190607
+ if( (int)pIter->abTblPk[i]==iPk ){
190608
+ const char *zCol = pIter->azTblCol[i];
190609
+ zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
190610
+ zSep = zSeparator;
190611
+ break;
190612
+ }
190613
+ }
190614
+ if( i==pIter->nTblCol ) break;
190615
+ iPk++;
190616
+ }
190617
+ return zRet;
190618
+}
190619
+
190620
+/*
190621
+** This function is called as part of restarting an RBU vacuum within
190622
+** stage 1 of the process (while the *-oal file is being built) while
190623
+** updating a table (not an index). The table may be a rowid table or
190624
+** a WITHOUT ROWID table. It queries the target database to find the
190625
+** largest key that has already been written to the target table and
190626
+** constructs a WHERE clause that can be used to extract the remaining
190627
+** rows from the source table. For a rowid table, the WHERE clause
190628
+** is of the form:
190629
+**
190630
+** "WHERE _rowid_ > ?"
190631
+**
190632
+** and for WITHOUT ROWID tables:
190633
+**
190634
+** "WHERE (key1, key2) > (?, ?)"
190635
+**
190636
+** Instead of "?" placeholders, the actual WHERE clauses created by
190637
+** this function contain literal SQL values.
190638
+*/
190639
+static char *rbuVacuumTableStart(
190640
+ sqlite3rbu *p, /* RBU handle */
190641
+ RbuObjIter *pIter, /* RBU iterator object */
190642
+ int bRowid, /* True for a rowid table */
190643
+ const char *zWrite /* Target table name prefix */
190644
+){
190645
+ sqlite3_stmt *pMax = 0;
190646
+ char *zRet = 0;
190647
+ if( bRowid ){
190648
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
190649
+ sqlite3_mprintf(
190650
+ "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
190651
+ )
190652
+ );
190653
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
190654
+ sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
190655
+ zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
190656
+ }
190657
+ rbuFinalize(p, pMax);
190658
+ }else{
190659
+ char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
190660
+ char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
190661
+ char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
190662
+
190663
+ if( p->rc==SQLITE_OK ){
190664
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
190665
+ sqlite3_mprintf(
190666
+ "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1",
190667
+ zSelect, zWrite, pIter->zTbl, zOrder
190668
+ )
190669
+ );
190670
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
190671
+ const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
190672
+ zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
190673
+ }
190674
+ rbuFinalize(p, pMax);
190675
+ }
190676
+
190677
+ sqlite3_free(zOrder);
190678
+ sqlite3_free(zSelect);
190679
+ sqlite3_free(zList);
190680
+ }
190681
+ return zRet;
190682
+}
190683
+
190684
+/*
190685
+** This function is called as part of restating an RBU vacuum when the
190686
+** current operation is writing content to an index. If possible, it
190687
+** queries the target index b-tree for the largest key already written to
190688
+** it, then composes and returns an expression that can be used in a WHERE
190689
+** clause to select the remaining required rows from the source table.
190690
+** It is only possible to return such an expression if:
190691
+**
190692
+** * The index contains no DESC columns, and
190693
+** * The last key written to the index before the operation was
190694
+** suspended does not contain any NULL values.
190695
+**
190696
+** The expression is of the form:
190697
+**
190698
+** (index-field1, index-field2, ...) > (?, ?, ...)
190699
+**
190700
+** except that the "?" placeholders are replaced with literal values.
190701
+**
190702
+** If the expression cannot be created, NULL is returned. In this case,
190703
+** the caller has to use an OFFSET clause to extract only the required
190704
+** rows from the sourct table, just as it does for an RBU update operation.
190705
+*/
190706
+char *rbuVacuumIndexStart(
190707
+ sqlite3rbu *p, /* RBU handle */
190708
+ RbuObjIter *pIter /* RBU iterator object */
190709
+){
190710
+ char *zOrder = 0;
190711
+ char *zLhs = 0;
190712
+ char *zSelect = 0;
190713
+ char *zVector = 0;
190714
+ char *zRet = 0;
190715
+ int bFailed = 0;
190716
+ const char *zSep = "";
190717
+ int iCol = 0;
190718
+ sqlite3_stmt *pXInfo = 0;
190719
+
190720
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
190721
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
190722
+ );
190723
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
190724
+ int iCid = sqlite3_column_int(pXInfo, 1);
190725
+ const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
190726
+ const char *zCol;
190727
+ if( sqlite3_column_int(pXInfo, 3) ){
190728
+ bFailed = 1;
190729
+ break;
190730
+ }
190731
+
190732
+ if( iCid<0 ){
190733
+ if( pIter->eType==RBU_PK_IPK ){
190734
+ int i;
190735
+ for(i=0; pIter->abTblPk[i]==0; i++);
190736
+ assert( i<pIter->nTblCol );
190737
+ zCol = pIter->azTblCol[i];
190738
+ }else{
190739
+ zCol = "_rowid_";
190740
+ }
190741
+ }else{
190742
+ zCol = pIter->azTblCol[iCid];
190743
+ }
190744
+
190745
+ zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
190746
+ zLhs, zSep, zCol, zCollate
190747
+ );
190748
+ zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
190749
+ zOrder, zSep, iCol, zCol, zCollate
190750
+ );
190751
+ zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
190752
+ zSelect, zSep, iCol, zCol
190753
+ );
190754
+ zSep = ", ";
190755
+ iCol++;
190756
+ }
190757
+ rbuFinalize(p, pXInfo);
190758
+ if( bFailed ) goto index_start_out;
190759
+
190760
+ if( p->rc==SQLITE_OK ){
190761
+ sqlite3_stmt *pSel = 0;
190762
+
190763
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
190764
+ sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
190765
+ zSelect, pIter->zTbl, zOrder
190766
+ )
190767
+ );
190768
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
190769
+ zSep = "";
190770
+ for(iCol=0; iCol<pIter->nCol; iCol++){
190771
+ const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
190772
+ if( zQuoted[0]=='N' ){
190773
+ bFailed = 1;
190774
+ break;
190775
+ }
190776
+ zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
190777
+ zSep = ", ";
190778
+ }
190779
+
190780
+ if( !bFailed ){
190781
+ zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
190782
+ }
190783
+ }
190784
+ rbuFinalize(p, pSel);
190785
+ }
190786
+
190787
+ index_start_out:
190788
+ sqlite3_free(zOrder);
190789
+ sqlite3_free(zSelect);
190790
+ sqlite3_free(zVector);
190791
+ sqlite3_free(zLhs);
190792
+ return zRet;
190793
+}
190280190794
190281190795
/*
190282190796
** This function is used to create a SELECT list (the list of SQL
190283190797
** expressions that follows a SELECT keyword) for a SELECT statement
190284190798
** used to read from an data_xxx or rbu_tmp_xxx table while updating the
@@ -190952,16 +191466,28 @@
190952191466
190953191467
/* Create the SELECT statement to read keys in sorted order */
190954191468
if( p->rc==SQLITE_OK ){
190955191469
char *zSql;
190956191470
if( rbuIsVacuum(p) ){
191471
+ char *zStart = 0;
191472
+ if( nOffset ){
191473
+ zStart = rbuVacuumIndexStart(p, pIter);
191474
+ if( zStart ){
191475
+ sqlite3_free(zLimit);
191476
+ zLimit = 0;
191477
+ }
191478
+ }
191479
+
190957191480
zSql = sqlite3_mprintf(
190958
- "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
191481
+ "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
190959191482
zCollist,
190960191483
pIter->zDataTbl,
190961
- zPart, zCollist, zLimit
191484
+ zPart,
191485
+ (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
191486
+ zCollist, zLimit
190962191487
);
191488
+ sqlite3_free(zStart);
190963191489
}else
190964191490
190965191491
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
190966191492
zSql = sqlite3_mprintf(
190967191493
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
@@ -190980,11 +191506,15 @@
190980191506
zPart,
190981191507
(zPart ? "AND" : "WHERE"),
190982191508
zCollist, zLimit
190983191509
);
190984191510
}
190985
- p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
191511
+ if( p->rc==SQLITE_OK ){
191512
+ p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
191513
+ }else{
191514
+ sqlite3_free(zSql);
191515
+ }
190986191516
}
190987191517
190988191518
sqlite3_free(zImposterCols);
190989191519
sqlite3_free(zImposterPK);
190990191520
sqlite3_free(zWhere);
@@ -191080,22 +191610,46 @@
191080191610
}
191081191611
191082191612
/* Create the SELECT statement to read keys from data_xxx */
191083191613
if( p->rc==SQLITE_OK ){
191084191614
const char *zRbuRowid = "";
191615
+ char *zStart = 0;
191616
+ char *zOrder = 0;
191085191617
if( bRbuRowid ){
191086191618
zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
191087191619
}
191088
- p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
191089
- sqlite3_mprintf(
191090
- "SELECT %s,%s rbu_control%s FROM '%q'%s",
191091
- zCollist,
191092
- (rbuIsVacuum(p) ? "0 AS " : ""),
191093
- zRbuRowid,
191094
- pIter->zDataTbl, zLimit
191095
- )
191096
- );
191620
+
191621
+ if( rbuIsVacuum(p) ){
191622
+ if( nOffset ){
191623
+ zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
191624
+ if( zStart ){
191625
+ sqlite3_free(zLimit);
191626
+ zLimit = 0;
191627
+ }
191628
+ }
191629
+ if( bRbuRowid ){
191630
+ zOrder = rbuMPrintf(p, "_rowid_");
191631
+ }else{
191632
+ zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
191633
+ }
191634
+ }
191635
+
191636
+ if( p->rc==SQLITE_OK ){
191637
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
191638
+ sqlite3_mprintf(
191639
+ "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
191640
+ zCollist,
191641
+ (rbuIsVacuum(p) ? "0 AS " : ""),
191642
+ zRbuRowid,
191643
+ pIter->zDataTbl, (zStart ? zStart : ""),
191644
+ (zOrder ? "ORDER BY" : ""), zOrder,
191645
+ zLimit
191646
+ )
191647
+ );
191648
+ }
191649
+ sqlite3_free(zStart);
191650
+ sqlite3_free(zOrder);
191097191651
}
191098191652
191099191653
sqlite3_free(zWhere);
191100191654
sqlite3_free(zOldlist);
191101191655
sqlite3_free(zNewlist);
@@ -193661,11 +194215,12 @@
193661194215
** be intercepted (see the rbuVfsOpen() function) and the *-oal
193662194216
** file opened instead.
193663194217
*/
193664194218
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
193665194219
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
193666
- if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
194220
+ if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
194221
+ assert( pDb->pRbu );
193667194222
if( *pResOut ){
193668194223
rc = SQLITE_CANTOPEN;
193669194224
}else{
193670194225
sqlite3_int64 sz = 0;
193671194226
rc = rbuVfsFileSize(&pDb->base, &sz);
@@ -204285,11 +204840,15 @@
204285204840
return 1;
204286204841
}else{
204287204842
i64 iOff = *piOff;
204288204843
int iVal;
204289204844
fts5FastGetVarint32(a, i, iVal);
204290
- if( iVal==1 ){
204845
+ if( iVal<=1 ){
204846
+ if( iVal==0 ){
204847
+ *pi = i;
204848
+ return 0;
204849
+ }
204291204850
fts5FastGetVarint32(a, i, iVal);
204292204851
iOff = ((i64)iVal) << 32;
204293204852
fts5FastGetVarint32(a, i, iVal);
204294204853
}
204295204854
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
@@ -218101,11 +218660,11 @@
218101218660
int nArg, /* Number of args */
218102218661
sqlite3_value **apUnused /* Function arguments */
218103218662
){
218104218663
assert( nArg==0 );
218105218664
UNUSED_PARAM2(nArg, apUnused);
218106
- sqlite3_result_text(pCtx, "fts5: 2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50", -1, SQLITE_TRANSIENT);
218665
+ sqlite3_result_text(pCtx, "fts5: 2019-05-10 17:50:33 2846bc0429c0956473bfe99dde135f2c206720f0be4c2800118b280e446ce325", -1, SQLITE_TRANSIENT);
218107218666
}
218108218667
218109218668
/*
218110218669
** Return true if zName is the extension on one of the shadow tables used
218111218670
** by this module.
@@ -222865,12 +223424,12 @@
222865223424
}
222866223425
#endif /* SQLITE_CORE */
222867223426
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
222868223427
222869223428
/************** End of stmt.c ************************************************/
222870
-#if __LINE__!=222870
223429
+#if __LINE__!=223429
222871223430
#undef SQLITE_SOURCE_ID
222872
-#define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f8315alt2"
223431
+#define SQLITE_SOURCE_ID "2019-05-10 17:54:58 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000falt2"
222873223432
#endif
222874223433
/* Return the source-id for this library */
222875223434
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
222876223435
/************************** End of sqlite3.c ******************************/
222877223436
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.28.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -886,10 +886,15 @@
886 #pragma warning(disable : 4306)
887 #pragma warning(disable : 4702)
888 #pragma warning(disable : 4706)
889 #endif /* defined(_MSC_VER) */
890
 
 
 
 
 
891 #endif /* SQLITE_MSVC_H */
892
893 /************** End of msvc.h ************************************************/
894 /************** Continuing where we left off in sqliteInt.h ******************/
895
@@ -1160,13 +1165,13 @@
1160 **
1161 ** See also: [sqlite3_libversion()],
1162 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1163 ** [sqlite_version()] and [sqlite_source_id()].
1164 */
1165 #define SQLITE_VERSION "3.28.0"
1166 #define SQLITE_VERSION_NUMBER 3028000
1167 #define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50"
1168
1169 /*
1170 ** CAPI3REF: Run-Time Library Version Numbers
1171 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1172 **
@@ -8356,11 +8361,12 @@
8356 #define SQLITE_TESTCTRL_BYTEORDER 22
8357 #define SQLITE_TESTCTRL_ISINIT 23
8358 #define SQLITE_TESTCTRL_SORTER_MMAP 24
8359 #define SQLITE_TESTCTRL_IMPOSTER 25
8360 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26
8361 #define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
 
8362
8363 /*
8364 ** CAPI3REF: SQL Keyword Checking
8365 **
8366 ** These routines provide access to the set of SQL language keywords
@@ -17451,10 +17457,12 @@
17451 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
17452 #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
17453 #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
17454 #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
17455 #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
 
 
17456
17457 /*
17458 ** The EP_Propagate mask is a set of properties that automatically propagate
17459 ** upwards into parent nodes.
17460 */
@@ -17466,10 +17474,12 @@
17466 */
17467 #define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
17468 #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
17469 #define ExprSetProperty(E,P) (E)->flags|=(P)
17470 #define ExprClearProperty(E,P) (E)->flags&=~(P)
 
 
17471
17472 /* The ExprSetVVAProperty() macro is used for Verification, Validation,
17473 ** and Accreditation only. It works like ExprSetProperty() during VVA
17474 ** processes but is a no-op for delivery.
17475 */
@@ -18775,11 +18785,12 @@
18775 SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
18776 SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
18777 SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
18778 SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
18779 SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
18780 SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
 
18781 SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
18782 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
18783 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
18784 SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
18785 SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
@@ -19188,10 +19199,13 @@
19188 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
19189 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
19190 void(*)(void*));
19191 SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
19192 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
 
 
 
19193 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
19194 #ifndef SQLITE_OMIT_UTF16
19195 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
19196 #endif
19197 SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
@@ -20178,16 +20192,16 @@
20178 #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
20179 #define MEM_Str 0x0002 /* Value is a string */
20180 #define MEM_Int 0x0004 /* Value is an integer */
20181 #define MEM_Real 0x0008 /* Value is a real number */
20182 #define MEM_Blob 0x0010 /* Value is a BLOB */
20183 #define MEM_AffMask 0x001f /* Mask of affinity bits */
20184 #define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
20185 /* Available 0x0040 */
20186 #define MEM_Undefined 0x0080 /* Value is undefined */
20187 #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
20188 #define MEM_TypeMask 0xc1df /* Mask of type bits */
20189
20190
20191 /* Whenever Mem contains a valid string or blob representation, one of
20192 ** the following flags must be set to determine the memory management
20193 ** policy for Mem.z. The MEM_Term flag tells us whether or not the
@@ -30210,13 +30224,11 @@
30210 ** strings, and stuff like that.
30211 **
30212 */
30213 /* #include "sqliteInt.h" */
30214 /* #include <stdarg.h> */
30215 #if HAVE_ISNAN || SQLITE_HAVE_ISNAN
30216 # include <math.h>
30217 #endif
30218
30219 /*
30220 ** Routine needed to support the testcase() macro.
30221 */
30222 #ifdef SQLITE_COVERAGE_TEST
@@ -30515,16 +30527,22 @@
30515 }
30516 return sqlite3StrICmp(zLeft, zRight);
30517 }
30518 SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
30519 unsigned char *a, *b;
30520 int c;
30521 a = (unsigned char *)zLeft;
30522 b = (unsigned char *)zRight;
30523 for(;;){
30524 c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
30525 if( c || *a==0 ) break;
 
 
 
 
 
 
30526 a++;
30527 b++;
30528 }
30529 return c;
30530 }
@@ -31105,36 +31123,26 @@
31105 ** Return the number of bytes read. The value is stored in *v.
31106 */
31107 SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
31108 u32 a,b,s;
31109
31110 a = *p;
31111 /* a: p0 (unmasked) */
31112 if (!(a&0x80))
31113 {
31114 *v = a;
31115 return 1;
31116 }
31117
31118 p++;
31119 b = *p;
31120 /* b: p1 (unmasked) */
31121 if (!(b&0x80))
31122 {
31123 a &= 0x7f;
31124 a = a<<7;
31125 a |= b;
31126 *v = a;
31127 return 2;
31128 }
31129
31130 /* Verify that constants are precomputed correctly */
31131 assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
31132 assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
31133
31134 p++;
31135 a = a<<14;
 
31136 a |= *p;
31137 /* a: p0<<14 | p2 (unmasked) */
31138 if (!(a&0x80))
31139 {
31140 a &= SLOT_2_0;
@@ -61220,13 +61228,13 @@
61220 if( rc!=SQLITE_OK ){
61221 return rc;
61222 }
61223 nCollide = HASHTABLE_NSLOT;
61224 for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
61225 u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
61226 if( iFrame<=iLast && iFrame>=pWal->minFrame
61227 && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
61228 assert( iFrame>iRead || CORRUPT_DB );
61229 iRead = iFrame;
61230 }
61231 if( (nCollide--)==0 ){
61232 return SQLITE_CORRUPT_BKPT;
@@ -64814,11 +64822,11 @@
64814 ** and the reserved space is zero (the usual value for reserved space)
64815 ** then the cell content offset of an empty page wants to be 65536.
64816 ** However, that integer is too large to be stored in a 2-byte unsigned
64817 ** integer, so a value of 0 is used in its place. */
64818 top = get2byte(&data[hdr+5]);
64819 assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
64820 if( gap>top ){
64821 if( top==0 && pPage->pBt->usableSize==65536 ){
64822 top = 65536;
64823 }else{
64824 return SQLITE_CORRUPT_PAGE(pPage);
@@ -65111,11 +65119,11 @@
65111 ** the cell-content area. If this is greater than the usable-size
65112 ** of the page, then the page must be corrupted. This check also
65113 ** serves to verify that the offset to the start of the cell-content
65114 ** area, according to the page header, lies within the page.
65115 */
65116 if( nFree>usableSize ){
65117 return SQLITE_CORRUPT_PAGE(pPage);
65118 }
65119 pPage->nFree = (u16)(nFree - iCellFirst);
65120 return SQLITE_OK;
65121 }
@@ -67338,10 +67346,22 @@
67338 }
67339 sqlite3BtreeLeave(pBtree);
67340 }
67341 return rc;
67342 }
 
 
 
 
 
 
 
 
 
 
 
 
67343
67344 /*
67345 ** Rollback the transaction in progress.
67346 **
67347 ** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
@@ -67384,15 +67404,11 @@
67384
67385 /* The rollback may have destroyed the pPage1->aData value. So
67386 ** call btreeGetPage() on page 1 again to make
67387 ** sure pPage1->aData is set correctly. */
67388 if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
67389 int nPage = get4byte(28+(u8*)pPage1->aData);
67390 testcase( nPage==0 );
67391 if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
67392 testcase( pBt->nPage!=nPage );
67393 pBt->nPage = nPage;
67394 releasePageOne(pPage1);
67395 }
67396 assert( countValidCursors(pBt, 1)==0 );
67397 pBt->inTransaction = TRANS_READ;
67398 btreeClearHasContent(pBt);
@@ -67468,16 +67484,15 @@
67468 if( rc==SQLITE_OK ){
67469 if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
67470 pBt->nPage = 0;
67471 }
67472 rc = newDatabase(pBt);
67473 pBt->nPage = get4byte(28 + pBt->pPage1->aData);
67474
67475 /* The database size was written into the offset 28 of the header
67476 ** when the transaction started, so we know that the value at offset
67477 ** 28 is nonzero. */
67478 assert( pBt->nPage>0 );
67479 }
67480 sqlite3BtreeLeave(p);
67481 }
67482 return rc;
67483 }
@@ -68481,10 +68496,11 @@
68481 assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
68482 }
68483 assert( pCur->ix==pCur->pPage->nCell-1 );
68484 assert( pCur->pPage->leaf );
68485 #endif
 
68486 return SQLITE_OK;
68487 }
68488
68489 rc = moveToRoot(pCur);
68490 if( rc==SQLITE_OK ){
@@ -70823,10 +70839,11 @@
70823 int limit = pOld->nCell;
70824 u8 *aData = pOld->aData;
70825 u16 maskPage = pOld->maskPage;
70826 u8 *piCell = aData + pOld->cellOffset;
70827 u8 *piEnd;
 
70828
70829 /* Verify that all sibling pages are of the same "type" (table-leaf,
70830 ** table-interior, index-leaf, or index-interior).
70831 */
70832 if( pOld->aData[0]!=apOld[0]->aData[0] ){
@@ -70851,10 +70868,14 @@
70851 ** long be able to find the cells if a pointer to each cell is not saved
70852 ** first.
70853 */
70854 memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
70855 if( pOld->nOverflow>0 ){
 
 
 
 
70856 limit = pOld->aiOvfl[0];
70857 for(j=0; j<limit; j++){
70858 b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
70859 piCell += 2;
70860 b.nCell++;
@@ -70870,10 +70891,11 @@
70870 assert( b.nCell<nMaxCells );
70871 b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
70872 piCell += 2;
70873 b.nCell++;
70874 }
 
70875
70876 cntOld[i] = b.nCell;
70877 if( i<nOld-1 && !leafData){
70878 u16 sz = (u16)szNew[i];
70879 u8 *pTemp;
@@ -71170,10 +71192,11 @@
71170 for(i=0; i<b.nCell; i++){
71171 u8 *pCell = b.apCell[i];
71172 while( i==cntOldNext ){
71173 iOld++;
71174 assert( iOld<nNew || iOld<nOld );
 
71175 pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
71176 cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
71177 }
71178 if( i==cntNew[iNew] ){
71179 pNew = apNew[++iNew];
@@ -73890,11 +73913,11 @@
73890 ** then the backup cannot proceed.
73891 */
73892 if( nSrcReserve!=nDestReserve ){
73893 u32 newPgsz = nSrcPgsz;
73894 rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
73895 if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
73896 }
73897 #endif
73898
73899 /* This loop runs once for each destination page spanned by the source
73900 ** page. For each iteration, variable iOff is set to the byte offset
@@ -74437,10 +74460,15 @@
74437 ** name sqlite_value
74438 */
74439 /* #include "sqliteInt.h" */
74440 /* #include "vdbeInt.h" */
74441
 
 
 
 
 
74442 #ifdef SQLITE_DEBUG
74443 /*
74444 ** Check invariants on a Mem object.
74445 **
74446 ** This routine is intended for use inside of assert() statements, like
@@ -74456,12 +74484,12 @@
74456 ** ensure that if Mem.szMalloc>0 then it is safe to do
74457 ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
74458 ** That saves a few cycles in inner loops. */
74459 assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
74460
74461 /* Cannot be both MEM_Int and MEM_Real at the same time */
74462 assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
74463
74464 if( p->flags & MEM_Null ){
74465 /* Cannot be both MEM_Null and some other type */
74466 assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
74467
@@ -74510,10 +74538,29 @@
74510 );
74511 }
74512 return 1;
74513 }
74514 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74515
74516 #ifdef SQLITE_DEBUG
74517 /*
74518 ** Check that string value of pMem agrees with its integer or real value.
74519 **
@@ -74536,16 +74583,12 @@
74536 SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
74537 char zBuf[100];
74538 char *z;
74539 int i, j, incr;
74540 if( (p->flags & MEM_Str)==0 ) return 1;
74541 if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
74542 if( p->flags & MEM_Int ){
74543 sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
74544 }else{
74545 sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
74546 }
74547 z = p->z;
74548 i = j = 0;
74549 incr = 1;
74550 if( p->enc!=SQLITE_UTF8 ){
74551 incr = 2;
@@ -74653,12 +74696,12 @@
74653 ** If pMem->zMalloc already meets or exceeds the requested size, this
74654 ** routine is a no-op.
74655 **
74656 ** Any prior string or blob content in the pMem object may be discarded.
74657 ** The pMem->xDel destructor is called, if it exists. Though MEM_Str
74658 ** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
74659 ** values are preserved.
74660 **
74661 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
74662 ** if unable to complete the resizing.
74663 */
74664 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
@@ -74667,24 +74710,30 @@
74667 if( pMem->szMalloc<szNew ){
74668 return sqlite3VdbeMemGrow(pMem, szNew, 0);
74669 }
74670 assert( (pMem->flags & MEM_Dyn)==0 );
74671 pMem->z = pMem->zMalloc;
74672 pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
74673 return SQLITE_OK;
74674 }
74675
74676 /*
74677 ** It is already known that pMem contains an unterminated string.
74678 ** Add the zero terminator.
 
 
 
 
 
74679 */
74680 static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
74681 if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
74682 return SQLITE_NOMEM_BKPT;
74683 }
74684 pMem->z[pMem->n] = 0;
74685 pMem->z[pMem->n+1] = 0;
 
74686 pMem->flags |= MEM_Term;
74687 return SQLITE_OK;
74688 }
74689
74690 /*
@@ -74754,57 +74803,45 @@
74754 return vdbeMemAddTerminator(pMem);
74755 }
74756 }
74757
74758 /*
74759 ** Add MEM_Str to the set of representations for the given Mem. Numbers
74760 ** are converted using sqlite3_snprintf(). Converting a BLOB to a string
74761 ** is a no-op.
74762 **
74763 ** Existing representations MEM_Int and MEM_Real are invalidated if
74764 ** bForce is true but are retained if bForce is false.
74765 **
74766 ** A MEM_Null value will never be passed to this function. This function is
74767 ** used for converting values to text for returning to the user (i.e. via
74768 ** sqlite3_value_text()), or for ensuring that values to be used as btree
74769 ** keys are strings. In the former case a NULL pointer is returned the
74770 ** user and the latter is an internal programming error.
74771 */
74772 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
74773 int fg = pMem->flags;
74774 const int nByte = 32;
74775
74776 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
74777 assert( !(fg&MEM_Zero) );
74778 assert( !(fg&(MEM_Str|MEM_Blob)) );
74779 assert( fg&(MEM_Int|MEM_Real) );
74780 assert( !sqlite3VdbeMemIsRowSet(pMem) );
74781 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
74782
74783
74784 if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
74785 pMem->enc = 0;
74786 return SQLITE_NOMEM_BKPT;
74787 }
74788
74789 /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
74790 ** string representation of the value. Then, if the required encoding
74791 ** is UTF-16le or UTF-16be do a translation.
74792 **
74793 ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
74794 */
74795 if( fg & MEM_Int ){
74796 sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
74797 }else{
74798 assert( fg & MEM_Real );
74799 sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
74800 }
74801 assert( pMem->z!=0 );
74802 pMem->n = sqlite3Strlen30NN(pMem->z);
74803 pMem->enc = SQLITE_UTF8;
74804 pMem->flags |= MEM_Str|MEM_Term;
74805 if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
74806 sqlite3VdbeChangeEncoding(pMem, enc);
74807 return SQLITE_OK;
74808 }
74809
74810 /*
@@ -74974,11 +75011,12 @@
74974 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
74975 int flags;
74976 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
74977 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
74978 flags = pMem->flags;
74979 if( flags & MEM_Int ){
 
74980 return pMem->u.i;
74981 }else if( flags & MEM_Real ){
74982 return doubleToInt64(pMem->u.r);
74983 }else if( flags & (MEM_Str|MEM_Blob) ){
74984 assert( pMem->z || pMem->n==0 );
@@ -75003,11 +75041,12 @@
75003 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
75004 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
75005 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
75006 if( pMem->flags & MEM_Real ){
75007 return pMem->u.r;
75008 }else if( pMem->flags & MEM_Int ){
 
75009 return (double)pMem->u.i;
75010 }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
75011 return memRealValue(pMem);
75012 }else{
75013 /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
@@ -75018,11 +75057,12 @@
75018 /*
75019 ** Return 1 if pMem represents true, and return 0 if pMem represents false.
75020 ** Return the value ifNull if pMem is NULL.
75021 */
75022 SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
75023 if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
 
75024 if( pMem->flags & MEM_Null ) return ifNull;
75025 return sqlite3VdbeRealValue(pMem)!=0.0;
75026 }
75027
75028 /*
@@ -75091,19 +75131,23 @@
75091 double r2 = (double)i;
75092 return memcmp(&r1, &r2, sizeof(r1))==0;
75093 }
75094
75095 /*
75096 ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
75097 ** Invalidate any prior representations.
75098 **
75099 ** Every effort is made to force the conversion, even if the input
75100 ** is a string that does not look completely like a number. Convert
75101 ** as much of the string as we can and ignore the rest.
75102 */
75103 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
75104 if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
 
 
 
 
75105 int rc;
75106 assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
75107 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
75108 rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
75109 if( rc==0 ){
@@ -75117,11 +75161,11 @@
75117 }else{
75118 MemSetTypeFlag(pMem, MEM_Real);
75119 }
75120 }
75121 }
75122 assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
75123 pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
75124 return SQLITE_OK;
75125 }
75126
75127 /*
@@ -75160,11 +75204,11 @@
75160 assert( aff==SQLITE_AFF_TEXT );
75161 assert( MEM_Str==(MEM_Blob>>3) );
75162 pMem->flags |= (pMem->flags&MEM_Blob)>>3;
75163 sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
75164 assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
75165 pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
75166 break;
75167 }
75168 }
75169 }
75170
@@ -75344,11 +75388,11 @@
75344 ** A significant change would indicated a missed call to this
75345 ** function for pX. Minor changes, such as adding or removing a
75346 ** dual type, are allowed, as long as the underlying value is the
75347 ** same. */
75348 u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
75349 assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
75350 assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
75351 assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
75352 assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
75353
75354 /* pMem is the register that is changing. But also mark pX as
@@ -75907,11 +75951,16 @@
75907 if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
75908 sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
75909 }else{
75910 sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
75911 }
75912 if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
 
 
 
 
 
75913 if( enc!=SQLITE_UTF8 ){
75914 rc = sqlite3VdbeChangeEncoding(pVal, enc);
75915 }
75916 }else if( op==TK_UMINUS ) {
75917 /* This branch happens for multiple negative signs. Ex: -(-5) */
@@ -75930,11 +75979,11 @@
75930 sqlite3ValueApplyAffinity(pVal, affinity, enc);
75931 }
75932 }else if( op==TK_NULL ){
75933 pVal = valueNew(db, pCtx);
75934 if( pVal==0 ) goto no_mem;
75935 sqlite3VdbeMemNumerify(pVal);
75936 }
75937 #ifndef SQLITE_OMIT_BLOB_LITERAL
75938 else if( op==TK_BLOB ){
75939 int nVal;
75940 assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
@@ -77847,11 +77896,11 @@
77847 }
77848 case P4_MEM: {
77849 Mem *pMem = pOp->p4.pMem;
77850 if( pMem->flags & MEM_Str ){
77851 zP4 = pMem->z;
77852 }else if( pMem->flags & MEM_Int ){
77853 sqlite3_str_appendf(&x, "%lld", pMem->u.i);
77854 }else if( pMem->flags & MEM_Real ){
77855 sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
77856 }else if( pMem->flags & MEM_Null ){
77857 zP4 = "NULL";
@@ -79209,11 +79258,11 @@
79209 }
79210 }
79211 }
79212
79213 /* Check for immediate foreign key violations. */
79214 if( p->rc==SQLITE_OK ){
79215 sqlite3VdbeCheckFk(p, 0);
79216 }
79217
79218 /* If the auto-commit flag is set and this is the only active writer
79219 ** VM, then we do either a commit or rollback of the current transaction.
@@ -79735,10 +79784,12 @@
79735 ** of SQLite will not understand those serial types.
79736 */
79737
79738 /*
79739 ** Return the serial-type for the value stored in pMem.
 
 
79740 */
79741 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
79742 int flags = pMem->flags;
79743 u32 n;
79744
@@ -79745,15 +79796,17 @@
79745 assert( pLen!=0 );
79746 if( flags&MEM_Null ){
79747 *pLen = 0;
79748 return 0;
79749 }
79750 if( flags&MEM_Int ){
79751 /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
79752 # define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
79753 i64 i = pMem->u.i;
79754 u64 u;
 
 
79755 if( i<0 ){
79756 u = ~i;
79757 }else{
79758 u = i;
79759 }
@@ -79769,10 +79822,19 @@
79769 if( u<=32767 ){ *pLen = 2; return 2; }
79770 if( u<=8388607 ){ *pLen = 3; return 3; }
79771 if( u<=2147483647 ){ *pLen = 4; return 4; }
79772 if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
79773 *pLen = 8;
 
 
 
 
 
 
 
 
 
79774 return 6;
79775 }
79776 if( flags&MEM_Real ){
79777 *pLen = 8;
79778 return 7;
@@ -80424,30 +80486,43 @@
80424 return (f2&MEM_Null) - (f1&MEM_Null);
80425 }
80426
80427 /* At least one of the two values is a number
80428 */
80429 if( combined_flags&(MEM_Int|MEM_Real) ){
80430 if( (f1 & f2 & MEM_Int)!=0 ){
 
 
 
 
 
80431 if( pMem1->u.i < pMem2->u.i ) return -1;
80432 if( pMem1->u.i > pMem2->u.i ) return +1;
80433 return 0;
80434 }
80435 if( (f1 & f2 & MEM_Real)!=0 ){
80436 if( pMem1->u.r < pMem2->u.r ) return -1;
80437 if( pMem1->u.r > pMem2->u.r ) return +1;
80438 return 0;
80439 }
80440 if( (f1&MEM_Int)!=0 ){
 
 
80441 if( (f2&MEM_Real)!=0 ){
80442 return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
 
 
 
 
80443 }else{
80444 return -1;
80445 }
80446 }
80447 if( (f1&MEM_Real)!=0 ){
80448 if( (f2&MEM_Int)!=0 ){
 
 
80449 return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
80450 }else{
80451 return -1;
80452 }
80453 }
@@ -80592,11 +80667,13 @@
80592 assert( idx1<=szHdr1 || CORRUPT_DB );
80593 do{
80594 u32 serial_type;
80595
80596 /* RHS is an integer */
80597 if( pRhs->flags & MEM_Int ){
 
 
80598 serial_type = aKey1[idx1];
80599 testcase( serial_type==12 );
80600 if( serial_type>=10 ){
80601 rc = +1;
80602 }else if( serial_type==0 ){
@@ -80937,11 +81014,13 @@
80937 return vdbeRecordCompareInt;
80938 }
80939 testcase( flags & MEM_Real );
80940 testcase( flags & MEM_Null );
80941 testcase( flags & MEM_Blob );
80942 if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
 
 
80943 assert( flags & MEM_Str );
80944 return vdbeRecordCompareString;
80945 }
80946 }
80947
@@ -81527,43 +81606,90 @@
81527 ** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
81528 ** point number string BLOB NULL
81529 */
81530 SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
81531 static const u8 aType[] = {
81532 SQLITE_BLOB, /* 0x00 */
81533 SQLITE_NULL, /* 0x01 */
81534 SQLITE_TEXT, /* 0x02 */
81535 SQLITE_NULL, /* 0x03 */
81536 SQLITE_INTEGER, /* 0x04 */
81537 SQLITE_NULL, /* 0x05 */
81538 SQLITE_INTEGER, /* 0x06 */
81539 SQLITE_NULL, /* 0x07 */
81540 SQLITE_FLOAT, /* 0x08 */
81541 SQLITE_NULL, /* 0x09 */
81542 SQLITE_FLOAT, /* 0x0a */
81543 SQLITE_NULL, /* 0x0b */
81544 SQLITE_INTEGER, /* 0x0c */
81545 SQLITE_NULL, /* 0x0d */
81546 SQLITE_INTEGER, /* 0x0e */
81547 SQLITE_NULL, /* 0x0f */
81548 SQLITE_BLOB, /* 0x10 */
81549 SQLITE_NULL, /* 0x11 */
81550 SQLITE_TEXT, /* 0x12 */
81551 SQLITE_NULL, /* 0x13 */
81552 SQLITE_INTEGER, /* 0x14 */
81553 SQLITE_NULL, /* 0x15 */
81554 SQLITE_INTEGER, /* 0x16 */
81555 SQLITE_NULL, /* 0x17 */
81556 SQLITE_FLOAT, /* 0x18 */
81557 SQLITE_NULL, /* 0x19 */
81558 SQLITE_FLOAT, /* 0x1a */
81559 SQLITE_NULL, /* 0x1b */
81560 SQLITE_INTEGER, /* 0x1c */
81561 SQLITE_NULL, /* 0x1d */
81562 SQLITE_INTEGER, /* 0x1e */
81563 SQLITE_NULL, /* 0x1f */
81564 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81565 return aType[pVal->flags&MEM_AffMask];
81566 }
81567
81568 /* Return true if a parameter to xUpdate represents an unchanged column */
81569 SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
@@ -81808,10 +81934,25 @@
81808 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
81809 sqlite3VdbeMemSetNull(pCtx->pOut);
81810 pCtx->isError = SQLITE_NOMEM_BKPT;
81811 sqlite3OomFault(pCtx->pOut->db);
81812 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81813
81814 /*
81815 ** This function is called after a transaction has been committed. It
81816 ** invokes callbacks registered with sqlite3_wal_hook() as required.
81817 */
@@ -83095,11 +83236,13 @@
83095 if( iIdx==p->pTab->iPKey ){
83096 sqlite3VdbeMemSetInt64(pMem, p->iKey1);
83097 }else if( iIdx>=p->pUnpacked->nField ){
83098 *ppValue = (sqlite3_value *)columnNullValue();
83099 }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
83100 if( pMem->flags & MEM_Int ){
 
 
83101 sqlite3VdbeMemRealify(pMem);
83102 }
83103 }
83104
83105 preupdate_old_out:
@@ -83414,11 +83557,11 @@
83414 nextIndex = idx + 1;
83415 assert( idx>0 && idx<=p->nVar );
83416 pVar = &p->aVar[idx-1];
83417 if( pVar->flags & MEM_Null ){
83418 sqlite3_str_append(&out, "NULL", 4);
83419 }else if( pVar->flags & MEM_Int ){
83420 sqlite3_str_appendf(&out, "%lld", pVar->u.i);
83421 }else if( pVar->flags & MEM_Real ){
83422 sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
83423 }else if( pVar->flags & MEM_Str ){
83424 int nOut; /* Number of bytes of the string text to include in output */
@@ -83676,18 +83819,10 @@
83676 sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
83677 iSrcLine&0xffffff, I, M);
83678 }
83679 #endif
83680
83681 /*
83682 ** Convert the given register into a string if it isn't one
83683 ** already. Return non-zero if a malloc() fails.
83684 */
83685 #define Stringify(P, enc) \
83686 if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
83687 { goto no_mem; }
83688
83689 /*
83690 ** An ephemeral string value (signified by the MEM_Ephem flag) contains
83691 ** a pointer to a dynamically allocated string where some other entity
83692 ** is responsible for deallocating that string. Because the register
83693 ** does not control the string, it might be deleted without the register
@@ -83745,11 +83880,11 @@
83745 if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
83746 /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
83747 ** is clear. Otherwise, if this is an ephemeral cursor created by
83748 ** OP_OpenDup, the cursor will not be closed and will still be part
83749 ** of a BtShared.pCursor list. */
83750 p->apCsr[iCur]->isEphemeral = 0;
83751 sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
83752 p->apCsr[iCur] = 0;
83753 }
83754 if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
83755 p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
@@ -83784,11 +83919,11 @@
83784 */
83785 static void applyNumericAffinity(Mem *pRec, int bTryForInt){
83786 double rValue;
83787 i64 iValue;
83788 u8 enc = pRec->enc;
83789 assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
83790 if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
83791 if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
83792 pRec->u.i = iValue;
83793 pRec->flags |= MEM_Int;
83794 }else{
@@ -83841,15 +83976,18 @@
83841 ** representation (blob and NULL do not get converted) but no string
83842 ** representation. It would be harmless to repeat the conversion if
83843 ** there is already a string rep, but it is pointless to waste those
83844 ** CPU cycles. */
83845 if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
83846 if( (pRec->flags&(MEM_Real|MEM_Int)) ){
 
 
 
83847 sqlite3VdbeMemStringify(pRec, enc, 1);
83848 }
83849 }
83850 pRec->flags &= ~(MEM_Real|MEM_Int);
83851 }
83852 }
83853
83854 /*
83855 ** Try to convert the type of a function argument or a result column
@@ -83884,11 +84022,11 @@
83884 ** interpret as a string if we want to). Compute its corresponding
83885 ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields
83886 ** accordingly.
83887 */
83888 static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
83889 assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
83890 assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
83891 ExpandBlob(pMem);
83892 if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
83893 return 0;
83894 }
@@ -83904,14 +84042,19 @@
83904 **
83905 ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
83906 ** But it does set pMem->u.r and pMem->u.i appropriately.
83907 */
83908 static u16 numericType(Mem *pMem){
83909 if( pMem->flags & (MEM_Int|MEM_Real) ){
83910 return pMem->flags & (MEM_Int|MEM_Real);
 
 
 
83911 }
83912 if( pMem->flags & (MEM_Str|MEM_Blob) ){
 
 
83913 return computeNumericType(pMem);
83914 }
83915 return 0;
83916 }
83917
@@ -84003,10 +84146,12 @@
84003 printf(" undefined");
84004 }else if( p->flags & MEM_Null ){
84005 printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
84006 }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
84007 printf(" si:%lld", p->u.i);
 
 
84008 }else if( p->flags & MEM_Int ){
84009 printf(" i:%lld", p->u.i);
84010 #ifndef SQLITE_OMIT_FLOATING_POINT
84011 }else if( p->flags & MEM_Real ){
84012 printf(" r:%g", p->u.r);
@@ -85033,23 +85178,42 @@
85033 ** It is illegal for P1 and P3 to be the same register. Sometimes,
85034 ** if P3 is the same register as P2, the implementation is able
85035 ** to avoid a memcpy().
85036 */
85037 case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
85038 i64 nByte;
 
 
85039
85040 pIn1 = &aMem[pOp->p1];
85041 pIn2 = &aMem[pOp->p2];
85042 pOut = &aMem[pOp->p3];
 
 
85043 assert( pIn1!=pOut );
85044 if( (pIn1->flags | pIn2->flags) & MEM_Null ){
 
 
 
85045 sqlite3VdbeMemSetNull(pOut);
85046 break;
85047 }
85048 if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
85049 Stringify(pIn1, encoding);
85050 Stringify(pIn2, encoding);
 
 
 
 
 
 
 
 
 
 
 
 
85051 nByte = pIn1->n + pIn2->n;
85052 if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
85053 goto too_big;
85054 }
85055 if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
@@ -85056,12 +85220,16 @@
85056 goto no_mem;
85057 }
85058 MemSetTypeFlag(pOut, MEM_Str);
85059 if( pOut!=pIn2 ){
85060 memcpy(pOut->z, pIn2->z, pIn2->n);
 
 
85061 }
85062 memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
 
 
85063 pOut->z[nByte]=0;
85064 pOut->z[nByte+1] = 0;
85065 pOut->flags |= MEM_Term;
85066 pOut->n = (int)nByte;
85067 pOut->enc = encoding;
@@ -85183,11 +85351,11 @@
85183 if( sqlite3IsNaN(rB) ){
85184 goto arithmetic_result_is_null;
85185 }
85186 pOut->u.r = rB;
85187 MemSetTypeFlag(pOut, MEM_Real);
85188 if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
85189 sqlite3VdbeIntegerAffinity(pOut);
85190 }
85191 #endif
85192 }
85193 break;
@@ -85354,11 +85522,13 @@
85354 ** integers, for space efficiency, but after extraction we want them
85355 ** to have only a real value.
85356 */
85357 case OP_RealAffinity: { /* in1 */
85358 pIn1 = &aMem[pOp->p1];
85359 if( pIn1->flags & MEM_Int ){
 
 
85360 sqlite3VdbeMemRealify(pIn1);
85361 }
85362 break;
85363 }
85364 #endif
@@ -85546,21 +85716,21 @@
85546 }else{
85547 /* Neither operand is NULL. Do a comparison. */
85548 affinity = pOp->p5 & SQLITE_AFF_MASK;
85549 if( affinity>=SQLITE_AFF_NUMERIC ){
85550 if( (flags1 | flags3)&MEM_Str ){
85551 if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
85552 applyNumericAffinity(pIn1,0);
85553 assert( flags3==pIn3->flags );
85554 /* testcase( flags3!=pIn3->flags );
85555 ** this used to be possible with pIn1==pIn3, but not since
85556 ** the column cache was removed. The following assignment
85557 ** is essentially a no-op. But, it provides defense-in-depth
85558 ** in case our analysis is incorrect, so it is left in. */
85559 flags3 = pIn3->flags;
85560 }
85561 if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
85562 applyNumericAffinity(pIn3,0);
85563 }
85564 }
85565 /* Handle the common case of integer comparison here, as an
85566 ** optimization, to avoid a call to sqlite3MemCompare() */
@@ -85569,21 +85739,23 @@
85569 if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
85570 res = 0;
85571 goto compare_op;
85572 }
85573 }else if( affinity==SQLITE_AFF_TEXT ){
85574 if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
85575 testcase( pIn1->flags & MEM_Int );
85576 testcase( pIn1->flags & MEM_Real );
 
85577 sqlite3VdbeMemStringify(pIn1, encoding, 1);
85578 testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
85579 flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
85580 assert( pIn1!=pIn3 );
85581 }
85582 if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
85583 testcase( pIn3->flags & MEM_Int );
85584 testcase( pIn3->flags & MEM_Real );
 
85585 sqlite3VdbeMemStringify(pIn3, encoding, 1);
85586 testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
85587 flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
85588 }
85589 }
@@ -86335,16 +86507,25 @@
86335 zAffinity = pOp->p4.z;
86336 assert( zAffinity!=0 );
86337 assert( pOp->p2>0 );
86338 assert( zAffinity[pOp->p2]==0 );
86339 pIn1 = &aMem[pOp->p1];
86340 do{
86341 assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
86342 assert( memIsValid(pIn1) );
86343 applyAffinity(pIn1, *(zAffinity++), encoding);
 
 
 
 
 
 
 
 
 
86344 pIn1++;
86345 }while( zAffinity[0] );
86346 break;
86347 }
86348
86349 /* Opcode: MakeRecord P1 P2 P3 P4 *
86350 ** Synopsis: r[P3]=mkrec(r[P1@P2])
@@ -86361,11 +86542,10 @@
86361 ** macros defined in sqliteInt.h.
86362 **
86363 ** If P4 is NULL then all index fields have the affinity BLOB.
86364 */
86365 case OP_MakeRecord: {
86366 u8 *zNewRecord; /* A buffer to hold the data for the new record */
86367 Mem *pRec; /* The new record */
86368 u64 nData; /* Number of bytes of data space */
86369 int nHdr; /* Number of bytes of header space */
86370 i64 nByte; /* Data space required for this record */
86371 i64 nZero; /* Number of zero bytes at the end of the record */
@@ -86374,13 +86554,13 @@
86374 Mem *pData0; /* First field to be combined into the record */
86375 Mem *pLast; /* Last field of the record */
86376 int nField; /* Number of fields in the record */
86377 char *zAffinity; /* The affinity string for the record */
86378 int file_format; /* File format to use for encoding */
86379 int i; /* Space used in zNewRecord[] header */
86380 int j; /* Space used in zNewRecord[] content */
86381 u32 len; /* Length of a field */
 
 
86382
86383 /* Assuming the record contains N fields, the record format looks
86384 ** like this:
86385 **
86386 ** ------------------------------------------------------------------------
@@ -86415,11 +86595,14 @@
86415 */
86416 assert( pData0<=pLast );
86417 if( zAffinity ){
86418 pRec = pData0;
86419 do{
86420 applyAffinity(pRec++, *(zAffinity++), encoding);
 
 
 
86421 assert( zAffinity[0]==0 || pRec<=pLast );
86422 }while( zAffinity[0] );
86423 }
86424
86425 #ifdef SQLITE_ENABLE_NULL_TRIM
@@ -86503,38 +86686,38 @@
86503 }
86504 if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
86505 goto no_mem;
86506 }
86507 }
86508 zNewRecord = (u8 *)pOut->z;
 
 
 
 
 
 
 
 
86509
86510 /* Write the record */
86511 i = putVarint32(zNewRecord, nHdr);
86512 j = nHdr;
86513 assert( pData0<=pLast );
86514 pRec = pData0;
86515 do{
86516 serial_type = pRec->uTemp;
86517 /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
86518 ** additional varints, one per column. */
86519 i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
86520 /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
86521 ** immediately follow the header. */
86522 j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
86523 }while( (++pRec)<=pLast );
86524 assert( i==nHdr );
86525 assert( j==nByte );
86526
86527 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
86528 pOut->n = (int)nByte;
86529 pOut->flags = MEM_Blob;
86530 if( nZero ){
86531 pOut->u.nZero = nZero;
86532 pOut->flags |= MEM_Zero;
86533 }
86534 REGISTER_TRACE(pOp->p3, pOut);
86535 UPDATE_MAX_BLOBSIZE(pOut);
86536 break;
86537 }
86538
86539 /* Opcode: Count P1 P2 * * *
86540 ** Synopsis: r[P2]=count()
@@ -86560,12 +86743,13 @@
86560 #endif
86561
86562 /* Opcode: Savepoint P1 * * P4 *
86563 **
86564 ** Open, release or rollback the savepoint named by parameter P4, depending
86565 ** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
86566 ** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
 
86567 */
86568 case OP_Savepoint: {
86569 int p1; /* Value of P1 operand */
86570 char *zName; /* Name of savepoint */
86571 int nName;
@@ -86629,10 +86813,11 @@
86629 pNew->nDeferredCons = db->nDeferredCons;
86630 pNew->nDeferredImmCons = db->nDeferredImmCons;
86631 }
86632 }
86633 }else{
 
86634 iSavepoint = 0;
86635
86636 /* Find the named savepoint. If there is no such savepoint, then an
86637 ** an error is returned to the user. */
86638 for(
@@ -86682,10 +86867,11 @@
86682 SQLITE_ABORT_ROLLBACK,
86683 isSchemaChange==0);
86684 if( rc!=SQLITE_OK ) goto abort_due_to_error;
86685 }
86686 }else{
 
86687 isSchemaChange = 0;
86688 }
86689 for(ii=0; ii<db->nDb; ii++){
86690 rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
86691 if( rc!=SQLITE_OK ){
@@ -86718,10 +86904,11 @@
86718 sqlite3DbFree(db, pSavepoint);
86719 if( !isTransaction ){
86720 db->nSavepoint--;
86721 }
86722 }else{
 
86723 db->nDeferredCons = pSavepoint->nDeferredCons;
86724 db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
86725 }
86726
86727 if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
@@ -87256,11 +87443,14 @@
87256 assert( pOp->p2>=0 );
87257 pCx = p->apCsr[pOp->p1];
87258 if( pCx ){
87259 /* If the ephermeral table is already open, erase all existing content
87260 ** so that the table is empty again, rather than creating a new table. */
87261 rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
 
 
 
87262 }else{
87263 pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
87264 if( pCx==0 ) goto no_mem;
87265 pCx->nullRow = 1;
87266 pCx->isEphemeral = 1;
@@ -87533,24 +87723,28 @@
87533
87534 /* The input value in P3 might be of any type: integer, real, string,
87535 ** blob, or NULL. But it needs to be an integer before we can do
87536 ** the seek, so convert it. */
87537 pIn3 = &aMem[pOp->p3];
87538 if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
87539 applyNumericAffinity(pIn3, 0);
87540 }
87541 iKey = sqlite3VdbeIntValue(pIn3);
87542
87543 /* If the P3 value could not be converted into an integer without
87544 ** loss of information, then special processing is required... */
87545 if( (pIn3->flags & MEM_Int)==0 ){
87546 if( (pIn3->flags & MEM_Real)==0 ){
87547 /* If the P3 value cannot be converted into any kind of a number,
87548 ** then the seek is not possible, so jump to P2 */
87549 VdbeBranchTaken(1,2); goto jump_to_p2;
87550 break;
87551 }
 
 
 
 
87552
87553 /* If the approximation iKey is larger than the actual real search
87554 ** term, substitute >= for > and < for <=. e.g. if the search term
87555 ** is 4.9 and the integer approximation 5:
87556 **
@@ -87570,11 +87764,11 @@
87570 assert( OP_SeekLE==(OP_SeekLT+1) );
87571 assert( OP_SeekGT==(OP_SeekGE+1) );
87572 assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
87573 if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
87574 }
87575 }
87576 rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
87577 pC->movetoTarget = iKey; /* Used by OP_Delete */
87578 if( rc!=SQLITE_OK ){
87579 goto abort_due_to_error;
87580 }
@@ -87925,11 +88119,13 @@
87925 BtCursor *pCrsr;
87926 int res;
87927 u64 iKey;
87928
87929 pIn3 = &aMem[pOp->p3];
87930 if( (pIn3->flags & MEM_Int)==0 ){
 
 
87931 /* Make sure pIn3->u.i contains a valid integer representation of
87932 ** the key value, but do not change the datatype of the register, as
87933 ** other parts of the perpared statement might be depending on the
87934 ** current datatype. */
87935 u16 origFlags = pIn3->flags;
@@ -95977,11 +96173,13 @@
95977 sqlite3WalkExprList(pWalker, pList);
95978 if( is_agg ){
95979 #ifndef SQLITE_OMIT_WINDOWFUNC
95980 if( pExpr->y.pWin ){
95981 Select *pSel = pNC->pWinSelect;
95982 sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
 
 
95983 sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
95984 sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
95985 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
95986 if( 0==pSel->pWin
95987 || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
@@ -97660,11 +97858,11 @@
97660 memset(pNew, 0, sizeof(Expr));
97661 pNew->op = (u8)op;
97662 pNew->iAgg = -1;
97663 if( pToken ){
97664 if( nExtra==0 ){
97665 pNew->flags |= EP_IntValue|EP_Leaf;
97666 pNew->u.iValue = iValue;
97667 }else{
97668 pNew->u.zToken = (char*)&pNew[1];
97669 assert( pToken->z!=0 || pToken->n==0 );
97670 if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
@@ -97737,24 +97935,20 @@
97737 int op, /* Expression opcode */
97738 Expr *pLeft, /* Left operand */
97739 Expr *pRight /* Right operand */
97740 ){
97741 Expr *p;
97742 if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
97743 /* Take advantage of short-circuit false optimization for AND */
97744 p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
97745 }else{
97746 p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
97747 if( p ){
97748 memset(p, 0, sizeof(Expr));
97749 p->op = op & 0xff;
97750 p->iAgg = -1;
97751 }
97752 sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
97753 }
97754 if( p ) {
97755 sqlite3ExprCheckHeight(pParse, p->nHeight);
 
 
 
97756 }
97757 return p;
97758 }
97759
97760 /*
@@ -97771,58 +97965,32 @@
97771 sqlite3SelectDelete(pParse->db, pSelect);
97772 }
97773 }
97774
97775
97776 /*
97777 ** If the expression is always either TRUE or FALSE (respectively),
97778 ** then return 1. If one cannot determine the truth value of the
97779 ** expression at compile-time return 0.
97780 **
97781 ** This is an optimization. If is OK to return 0 here even if
97782 ** the expression really is always false or false (a false negative).
97783 ** But it is a bug to return 1 if the expression might have different
97784 ** boolean values in different circumstances (a false positive.)
97785 **
97786 ** Note that if the expression is part of conditional for a
97787 ** LEFT JOIN, then we cannot determine at compile-time whether or not
97788 ** is it true or false, so always return 0.
97789 */
97790 static int exprAlwaysTrue(Expr *p){
97791 int v = 0;
97792 if( ExprHasProperty(p, EP_FromJoin) ) return 0;
97793 if( !sqlite3ExprIsInteger(p, &v) ) return 0;
97794 return v!=0;
97795 }
97796 static int exprAlwaysFalse(Expr *p){
97797 int v = 0;
97798 if( ExprHasProperty(p, EP_FromJoin) ) return 0;
97799 if( !sqlite3ExprIsInteger(p, &v) ) return 0;
97800 return v==0;
97801 }
97802
97803 /*
97804 ** Join two expressions using an AND operator. If either expression is
97805 ** NULL, then just return the other expression.
97806 **
97807 ** If one side or the other of the AND is known to be false, then instead
97808 ** of returning an AND expression, just return a constant expression with
97809 ** a value of false.
97810 */
97811 SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
97812 if( pLeft==0 ){
 
97813 return pRight;
97814 }else if( pRight==0 ){
97815 return pLeft;
97816 }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
 
 
97817 sqlite3ExprDelete(db, pLeft);
97818 sqlite3ExprDelete(db, pRight);
97819 return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
97820 }else{
97821 Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
97822 sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
97823 return pNew;
97824 }
97825 }
97826
97827 /*
97828 ** Construct a new expression node for a function with multiple
@@ -98708,10 +98876,11 @@
98708 if( !ExprHasProperty(pExpr, EP_Quoted)
98709 && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
98710 || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
98711 ){
98712 pExpr->op = TK_TRUEFALSE;
 
98713 return 1;
98714 }
98715 return 0;
98716 }
98717
@@ -98723,10 +98892,37 @@
98723 assert( pExpr->op==TK_TRUEFALSE );
98724 assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
98725 || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
98726 return pExpr->u.zToken[4]==0;
98727 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98728
98729
98730 /*
98731 ** These routines are Walker callbacks used to check expressions to
98732 ** see if they are "constant" for some definition of constant. The
@@ -98968,11 +99164,11 @@
98968 ** in *pValue. If the expression is not an integer or if it is too big
98969 ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
98970 */
98971 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
98972 int rc = 0;
98973 if( p==0 ) return 0; /* Can only happen following on OOM */
98974
98975 /* If an expression is an integer literal that fits in a signed 32-bit
98976 ** integer, then the EP_IntValue flag will have already been set */
98977 assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
98978 || sqlite3GetInt32(p->u.zToken, &rc)==0 );
@@ -101315,22 +101511,27 @@
101315 assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
101316 if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
101317 if( NEVER(pExpr==0) ) return; /* No way this can happen */
101318 op = pExpr->op;
101319 switch( op ){
101320 case TK_AND: {
101321 int d2 = sqlite3VdbeMakeLabel(pParse);
101322 testcase( jumpIfNull==0 );
101323 sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
101324 sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
101325 sqlite3VdbeResolveLabel(v, d2);
101326 break;
101327 }
101328 case TK_OR: {
101329 testcase( jumpIfNull==0 );
101330 sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
101331 sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
 
 
 
 
 
 
 
 
 
 
 
 
101332 break;
101333 }
101334 case TK_NOT: {
101335 testcase( jumpIfNull==0 );
101336 sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -101412,13 +101613,13 @@
101412 break;
101413 }
101414 #endif
101415 default: {
101416 default_expr:
101417 if( exprAlwaysTrue(pExpr) ){
101418 sqlite3VdbeGoto(v, dest);
101419 }else if( exprAlwaysFalse(pExpr) ){
101420 /* No-op */
101421 }else{
101422 r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
101423 sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
101424 VdbeCoverage(v);
@@ -101482,22 +101683,27 @@
101482 assert( pExpr->op!=TK_LE || op==OP_Gt );
101483 assert( pExpr->op!=TK_GT || op==OP_Le );
101484 assert( pExpr->op!=TK_GE || op==OP_Lt );
101485
101486 switch( pExpr->op ){
101487 case TK_AND: {
101488 testcase( jumpIfNull==0 );
101489 sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
101490 sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101491 break;
101492 }
101493 case TK_OR: {
101494 int d2 = sqlite3VdbeMakeLabel(pParse);
101495 testcase( jumpIfNull==0 );
101496 sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
101497 sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101498 sqlite3VdbeResolveLabel(v, d2);
 
 
 
 
 
 
 
 
 
 
101499 break;
101500 }
101501 case TK_NOT: {
101502 testcase( jumpIfNull==0 );
101503 sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -101582,13 +101788,13 @@
101582 break;
101583 }
101584 #endif
101585 default: {
101586 default_expr:
101587 if( exprAlwaysFalse(pExpr) ){
101588 sqlite3VdbeGoto(v, dest);
101589 }else if( exprAlwaysTrue(pExpr) ){
101590 /* no-op */
101591 }else{
101592 r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
101593 sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
101594 VdbeCoverage(v);
@@ -101822,11 +102028,15 @@
101822 && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
101823 || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
101824 ){
101825 return 1;
101826 }
101827 if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
 
 
 
 
101828 Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
101829 testcase( pX!=pE1->pLeft );
101830 if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
101831 }
101832 return 0;
@@ -102399,11 +102609,11 @@
102399 */
102400 static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
102401 sqlite3NestedParse(pParse,
102402 "SELECT 1 "
102403 "FROM \"%w\".%s "
102404 "WHERE name NOT LIKE 'sqlite_%%'"
102405 " AND sql NOT LIKE 'create virtual%%'"
102406 " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
102407 zDb, MASTER_NAME,
102408 zDb, bTemp
102409 );
@@ -102410,11 +102620,11 @@
102410
102411 if( bTemp==0 ){
102412 sqlite3NestedParse(pParse,
102413 "SELECT 1 "
102414 "FROM temp.%s "
102415 "WHERE name NOT LIKE 'sqlite_%%'"
102416 " AND sql NOT LIKE 'create virtual%%'"
102417 " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
102418 MASTER_NAME, zDb
102419 );
102420 }
@@ -102531,11 +102741,11 @@
102531 ** the schema to use the new table name. */
102532 sqlite3NestedParse(pParse,
102533 "UPDATE \"%w\".%s SET "
102534 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
102535 "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
102536 "AND name NOT LIKE 'sqlite_%%'"
102537 , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
102538 );
102539
102540 /* Update the tbl_name and name columns of the sqlite_master table
102541 ** as required. */
@@ -102542,11 +102752,12 @@
102542 sqlite3NestedParse(pParse,
102543 "UPDATE %Q.%s SET "
102544 "tbl_name = %Q, "
102545 "name = CASE "
102546 "WHEN type='table' THEN %Q "
102547 "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
 
102548 "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
102549 "ELSE name END "
102550 "WHERE tbl_name=%Q COLLATE nocase AND "
102551 "(type='table' OR type='index' OR type='trigger');",
102552 zDb, MASTER_NAME,
@@ -102916,11 +103127,12 @@
102916 assert( pNew->n>0 );
102917 bQuote = sqlite3Isquote(pNew->z[0]);
102918 sqlite3NestedParse(pParse,
102919 "UPDATE \"%w\".%s SET "
102920 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
102921 "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
 
102922 " AND sql NOT LIKE 'create virtual%%'",
102923 zDb, MASTER_NAME,
102924 zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
102925 pTab->zName
102926 );
@@ -108168,11 +108380,11 @@
108168 **
108169 ** This is goofy. But to preserve backwards compatibility we continue to
108170 ** accept it. This routine does the necessary conversion. It converts
108171 ** the expression given in its argument from a TK_STRING into a TK_ID
108172 ** if the expression is just a TK_STRING with an optional COLLATE clause.
108173 ** If the epxression is anything other than TK_STRING, the expression is
108174 ** unchanged.
108175 */
108176 static void sqlite3StringToId(Expr *p){
108177 if( p->op==TK_STRING ){
108178 p->op = TK_ID;
@@ -108565,14 +108777,55 @@
108565 wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
108566 }
108567 pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
108568 }
108569
108570 /* Return true if value x is found any of the first nCol entries of aiCol[]
 
 
108571 */
108572 static int hasColumn(const i16 *aiCol, int nCol, int x){
108573 while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108574 return 0;
108575 }
108576
108577 /* Recompute the colNotIdxed field of the Index.
108578 **
@@ -108657,17 +108910,20 @@
108657 Token ipkToken;
108658 sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
108659 pList = sqlite3ExprListAppend(pParse, 0,
108660 sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
108661 if( pList==0 ) return;
 
 
 
108662 pList->a[0].sortOrder = pParse->iPkSortOrder;
108663 assert( pParse->pNewTable==pTab );
 
108664 sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
108665 SQLITE_IDXTYPE_PRIMARYKEY);
108666 if( db->mallocFailed || pParse->nErr ) return;
108667 pPk = sqlite3PrimaryKeyIndex(pTab);
108668 pTab->iPKey = -1;
108669 }else{
108670 pPk = sqlite3PrimaryKeyIndex(pTab);
108671 assert( pPk!=0 );
108672
108673 /*
@@ -108674,13 +108930,14 @@
108674 ** Remove all redundant columns from the PRIMARY KEY. For example, change
108675 ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
108676 ** code assumes the PRIMARY KEY contains no repeated columns.
108677 */
108678 for(i=j=1; i<pPk->nKeyCol; i++){
108679 if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
108680 pPk->nColumn--;
108681 }else{
 
108682 pPk->aiColumn[j++] = pPk->aiColumn[i];
108683 }
108684 }
108685 pPk->nKeyCol = j;
108686 }
@@ -108706,20 +108963,24 @@
108706 */
108707 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
108708 int n;
108709 if( IsPrimaryKeyIndex(pIdx) ) continue;
108710 for(i=n=0; i<nPk; i++){
108711 if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
 
 
 
108712 }
108713 if( n==0 ){
108714 /* This index is a superset of the primary key */
108715 pIdx->nColumn = pIdx->nKeyCol;
108716 continue;
108717 }
108718 if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
108719 for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
108720 if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
 
108721 pIdx->aiColumn[j] = pPk->aiColumn[i];
108722 pIdx->azColl[j] = pPk->azColl[i];
108723 j++;
108724 }
108725 }
@@ -110231,13 +110492,14 @@
110231 */
110232 if( pPk ){
110233 for(j=0; j<pPk->nKeyCol; j++){
110234 int x = pPk->aiColumn[j];
110235 assert( x>=0 );
110236 if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
110237 pIndex->nColumn--;
110238 }else{
 
110239 pIndex->aiColumn[i] = x;
110240 pIndex->azColl[i] = pPk->azColl[j];
110241 pIndex->aSortOrder[i] = pPk->aSortOrder[j];
110242 i++;
110243 }
@@ -113004,10 +113266,11 @@
113004 ** time functions, are implemented separately.)
113005 */
113006 /* #include "sqliteInt.h" */
113007 /* #include <stdlib.h> */
113008 /* #include <assert.h> */
 
113009 /* #include "vdbeInt.h" */
113010
113011 /*
113012 ** Return the collating function associated with a function.
113013 */
@@ -113384,11 +113647,14 @@
113384 zBuf = sqlite3_mprintf("%.*f",n,r);
113385 if( zBuf==0 ){
113386 sqlite3_result_error_nomem(context);
113387 return;
113388 }
113389 sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
 
 
 
113390 sqlite3_free(zBuf);
113391 }
113392 sqlite3_result_double(context, r);
113393 }
113394 #endif
@@ -113831,12 +114097,10 @@
113831 #endif
113832 sqlite3_result_int(context, 0);
113833 return;
113834 }
113835 #endif
113836 zB = sqlite3_value_text(argv[0]);
113837 zA = sqlite3_value_text(argv[1]);
113838
113839 /* Limit the length of the LIKE or GLOB pattern to avoid problems
113840 ** of deep recursion and N*N behavior in patternCompare().
113841 */
113842 nPat = sqlite3_value_bytes(argv[0]);
@@ -113844,12 +114108,10 @@
113844 testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
113845 if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
113846 sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
113847 return;
113848 }
113849 assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
113850
113851 if( argc==3 ){
113852 /* The escape character string must consist of a single UTF-8 character.
113853 ** Otherwise, return an error.
113854 */
113855 const unsigned char *zEsc = sqlite3_value_text(argv[2]);
@@ -113861,10 +114123,12 @@
113861 }
113862 escape = sqlite3Utf8Read(&zEsc);
113863 }else{
113864 escape = pInfo->matchSet;
113865 }
 
 
113866 if( zA && zB ){
113867 #ifdef SQLITE_TEST
113868 sqlite3_like_count++;
113869 #endif
113870 sqlite3_result_int(context,
@@ -114786,43 +115050,28 @@
114786 sqlite3OomFault(db);
114787 }
114788 }
114789
114790 /*
114791 ** Set the LIKEOPT flag on the 2-argument function with the given name.
114792 */
114793 static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
114794 FuncDef *pDef;
114795 pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
114796 if( ALWAYS(pDef) ){
114797 pDef->funcFlags |= flagVal;
114798 }
114799 pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0);
114800 if( pDef ){
114801 pDef->funcFlags |= flagVal;
114802 }
114803 }
114804
114805 /*
114806 ** Register the built-in LIKE and GLOB functions. The caseSensitive
114807 ** parameter determines whether or not the LIKE operator is case
114808 ** sensitive. GLOB is always case sensitive.
114809 */
114810 SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
114811 struct compareInfo *pInfo;
 
114812 if( caseSensitive ){
114813 pInfo = (struct compareInfo*)&likeInfoAlt;
 
114814 }else{
114815 pInfo = (struct compareInfo*)&likeInfoNorm;
 
114816 }
114817 sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
114818 sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
114819 sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
114820 (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
114821 setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
114822 setLikeOptFlag(db, "like",
114823 caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
114824 }
114825
114826 /*
114827 ** pExpr points to an expression which implements a function. If
114828 ** it is appropriate to apply the LIKE optimization to that function
@@ -115608,11 +115857,11 @@
115608 iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
115609 assert( iCol>=0 );
115610 zCol = pFKey->pFrom->aCol[iCol].zName;
115611 pRight = sqlite3Expr(db, TK_ID, zCol);
115612 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
115613 pWhere = sqlite3ExprAnd(db, pWhere, pEq);
115614 }
115615
115616 /* If the child table is the same as the parent table, then add terms
115617 ** to the WHERE clause that prevent this entry from being scanned.
115618 ** The added WHERE clause terms are like this:
@@ -115642,15 +115891,15 @@
115642 i16 iCol = pIdx->aiColumn[i];
115643 assert( iCol>=0 );
115644 pLeft = exprTableRegister(pParse, pTab, regData, iCol);
115645 pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
115646 pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
115647 pAll = sqlite3ExprAnd(db, pAll, pEq);
115648 }
115649 pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
115650 }
115651 pWhere = sqlite3ExprAnd(db, pWhere, pNe);
115652 }
115653
115654 /* Resolve the references in the WHERE clause. */
115655 memset(&sNameContext, 0, sizeof(NameContext));
115656 sNameContext.pSrcList = pSrc;
@@ -116252,11 +116501,11 @@
116252 sqlite3PExpr(pParse, TK_DOT,
116253 sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
116254 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
116255 sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
116256 );
116257 pWhere = sqlite3ExprAnd(db, pWhere, pEq);
116258
116259 /* For ON UPDATE, construct the next term of the WHEN clause.
116260 ** The final WHEN clause will be like this:
116261 **
116262 ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
@@ -116268,11 +116517,11 @@
116268 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
116269 sqlite3PExpr(pParse, TK_DOT,
116270 sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
116271 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
116272 );
116273 pWhen = sqlite3ExprAnd(db, pWhen, pEq);
116274 }
116275
116276 if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
116277 Expr *pNew;
116278 if( action==OE_Cascade ){
@@ -117265,19 +117514,20 @@
117265 /* If this is not a view, open the table and and all indices */
117266 if( !isView ){
117267 int nIdx;
117268 nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
117269 &iDataCur, &iIdxCur);
117270 aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
117271 if( aRegIdx==0 ){
117272 goto insert_cleanup;
117273 }
117274 for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
117275 assert( pIdx );
117276 aRegIdx[i] = ++pParse->nMem;
117277 pParse->nMem += pIdx->nColumn;
117278 }
 
117279 }
117280 #ifndef SQLITE_OMIT_UPSERT
117281 if( pUpsert ){
117282 if( IsVirtual(pTab) ){
117283 sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
@@ -117676,10 +117926,18 @@
117676 ** The code generated by this routine will store new index entries into
117677 ** registers identified by aRegIdx[]. No index entry is created for
117678 ** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
117679 ** the same as the order of indices on the linked list of indices
117680 ** at pTab->pIndex.
 
 
 
 
 
 
 
 
117681 **
117682 ** The caller must have already opened writeable cursors on the main
117683 ** table and all applicable indices (that is to say, all indices for which
117684 ** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
117685 ** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
@@ -118295,10 +118553,20 @@
118295 if( ipkTop ){
118296 sqlite3VdbeGoto(v, ipkTop);
118297 VdbeComment((v, "Do IPK REPLACE"));
118298 sqlite3VdbeJumpHere(v, ipkBottom);
118299 }
 
 
 
 
 
 
 
 
 
 
118300
118301 *pbMayReplace = seenReplace;
118302 VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
118303 }
118304
@@ -118345,14 +118613,11 @@
118345 int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
118346 ){
118347 Vdbe *v; /* Prepared statements under construction */
118348 Index *pIdx; /* An index being inserted or updated */
118349 u8 pik_flags; /* flag values passed to the btree insert */
118350 int regData; /* Content registers (after the rowid) */
118351 int regRec; /* Register holding assembled record for the table */
118352 int i; /* Loop counter */
118353 u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
118354
118355 assert( update_flags==0
118356 || update_flags==OPFLAG_ISUPDATE
118357 || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
118358 );
@@ -118360,11 +118625,10 @@
118360 v = sqlite3GetVdbe(pParse);
118361 assert( v!=0 );
118362 assert( pTab->pSelect==0 ); /* This table is not a VIEW */
118363 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
118364 if( aRegIdx[i]==0 ) continue;
118365 bAffinityDone = 1;
118366 if( pIdx->pPartIdxWhere ){
118367 sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
118368 VdbeCoverage(v);
118369 }
118370 pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
@@ -118388,17 +118652,10 @@
118388 aRegIdx[i]+1,
118389 pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
118390 sqlite3VdbeChangeP5(v, pik_flags);
118391 }
118392 if( !HasRowid(pTab) ) return;
118393 regData = regNewData + 1;
118394 regRec = sqlite3GetTempReg(pParse);
118395 sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
118396 sqlite3SetMakeRecordP5(v, pTab);
118397 if( !bAffinityDone ){
118398 sqlite3TableAffinity(v, pTab, 0);
118399 }
118400 if( pParse->nested ){
118401 pik_flags = 0;
118402 }else{
118403 pik_flags = OPFLAG_NCHANGE;
118404 pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
@@ -118407,11 +118664,11 @@
118407 pik_flags |= OPFLAG_APPEND;
118408 }
118409 if( useSeekResult ){
118410 pik_flags |= OPFLAG_USESEEKRESULT;
118411 }
118412 sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
118413 if( !pParse->nested ){
118414 sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
118415 }
118416 sqlite3VdbeChangeP5(v, pik_flags);
118417 }
@@ -120725,15 +120982,17 @@
120725 /* ePragTyp: */ PragTyp_CACHE_SPILL,
120726 /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
120727 /* ColNames: */ 0, 0,
120728 /* iArg: */ 0 },
120729 #endif
 
120730 {/* zName: */ "case_sensitive_like",
120731 /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
120732 /* ePragFlg: */ PragFlg_NoColumns,
120733 /* ColNames: */ 0, 0,
120734 /* iArg: */ 0 },
 
120735 {/* zName: */ "cell_size_check",
120736 /* ePragTyp: */ PragTyp_FLAG,
120737 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
120738 /* ColNames: */ 0, 0,
120739 /* iArg: */ SQLITE_CellSizeCk },
@@ -122610,19 +122869,21 @@
122610 }
122611 break;
122612 #endif /* !defined(SQLITE_OMIT_TRIGGER) */
122613 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
122614
 
122615 /* Reinstall the LIKE and GLOB functions. The variant of LIKE
122616 ** used will be case sensitive or not depending on the RHS.
122617 */
122618 case PragTyp_CASE_SENSITIVE_LIKE: {
122619 if( zRight ){
122620 sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
122621 }
122622 }
122623 break;
 
122624
122625 #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
122626 # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
122627 #endif
122628
@@ -124974,11 +125235,11 @@
124974 ExprSetProperty(pEq, EP_FromJoin);
124975 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
124976 ExprSetVVAProperty(pEq, EP_NoReduce);
124977 pEq->iRightJoinTable = (i16)pE2->iTable;
124978 }
124979 *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
124980 }
124981
124982 /*
124983 ** Set the EP_FromJoin property on all terms of the given expression.
124984 ** And set the Expr.iRightJoinTable to iTable for every term in the
@@ -125108,11 +125369,11 @@
125108 /* Add the ON clause to the end of the WHERE clause, connected by
125109 ** an AND operator.
125110 */
125111 if( pRight->pOn ){
125112 if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
125113 p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
125114 pRight->pOn = 0;
125115 }
125116
125117 /* Create extra terms on the WHERE clause for each column named
125118 ** in the USING clause. Example: If the two tables to be joined are
@@ -128653,11 +128914,11 @@
128653 pWhere = pSub->pWhere;
128654 pSub->pWhere = 0;
128655 if( isLeftJoin>0 ){
128656 setJoinExpr(pWhere, iNewParent);
128657 }
128658 pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
128659 if( db->mallocFailed==0 ){
128660 SubstContext x;
128661 x.pParse = pParse;
128662 x.iTable = iParent;
128663 x.iNewTable = iNewParent;
@@ -128988,13 +129249,13 @@
128988 x.iNewTable = iCursor;
128989 x.isLeftJoin = 0;
128990 x.pEList = pSubq->pEList;
128991 pNew = substExpr(&x, pNew);
128992 if( pSubq->selFlags & SF_Aggregate ){
128993 pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
128994 }else{
128995 pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
128996 }
128997 pSubq = pSubq->pPrior;
128998 }
128999 }
129000 return nChng;
@@ -129416,11 +129677,11 @@
129416 sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
129417 pTab->iPKey = -1;
129418 pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
129419 pTab->tabFlags |= TF_Ephemeral;
129420
129421 return SQLITE_OK;
129422 }
129423
129424 /*
129425 ** This routine is a Walker callback for "expanding" a SELECT statement.
129426 ** "Expanding" means to do the following:
@@ -130037,11 +130298,11 @@
130037 sqlite3 *db = pWalker->pParse->db;
130038 Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
130039 if( pNew ){
130040 Expr *pWhere = pS->pWhere;
130041 SWAP(Expr, *pNew, *pExpr);
130042 pNew = sqlite3ExprAnd(db, pWhere, pNew);
130043 pS->pWhere = pNew;
130044 pWalker->eCode = 1;
130045 }
130046 }
130047 return WRC_Prune;
@@ -130100,11 +130361,13 @@
130100 if( pThis->pSelect->selId!=pS1->selId ){
130101 /* The query flattener left two different CTE tables with identical
130102 ** names in the same FROM clause. */
130103 continue;
130104 }
130105 if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
 
 
130106 /* The view was modified by some other optimization such as
130107 ** pushDownWhereTerms() */
130108 continue;
130109 }
130110 return pItem;
@@ -132786,15 +133049,16 @@
132786 WhereInfo *pWInfo; /* Information about the WHERE clause */
132787 Vdbe *v; /* The virtual database engine */
132788 Index *pIdx; /* For looping over indices */
132789 Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
132790 int nIdx; /* Number of indices that need updating */
 
132791 int iBaseCur; /* Base cursor number */
132792 int iDataCur; /* Cursor for the canonical data btree */
132793 int iIdxCur; /* Cursor for the first index */
132794 sqlite3 *db; /* The database structure */
132795 int *aRegIdx = 0; /* First register in array assigned to each index */
132796 int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
132797 ** an expression for the i-th column of the table.
132798 ** aXRef[i]==-1 if the i-th column is not changed. */
132799 u8 *aToOpen; /* 1 for tables and indices to be opened */
132800 u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */
@@ -132904,14 +133168,14 @@
132904 pTabList->a[0].iCursor = iDataCur;
132905
132906 /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
132907 ** Initialize aXRef[] and aToOpen[] to their default values.
132908 */
132909 aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
132910 if( aXRef==0 ) goto update_cleanup;
132911 aRegIdx = aXRef+pTab->nCol;
132912 aToOpen = (u8*)(aRegIdx+nIdx);
132913 memset(aToOpen, 1, nIdx+1);
132914 aToOpen[nIdx+1] = 0;
132915 for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
132916
132917 /* Initialize the name-context */
@@ -132986,11 +133250,11 @@
132986 /* There is one entry in the aRegIdx[] array for each index on the table
132987 ** being updated. Fill in aRegIdx[] with a register number that will hold
132988 ** the key for accessing each index.
132989 */
132990 if( onError==OE_Replace ) bReplace = 1;
132991 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
132992 int reg;
132993 if( chngKey || hasFK>1 || pIdx==pPk
132994 || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
132995 ){
132996 reg = ++pParse->nMem;
@@ -133006,13 +133270,14 @@
133006 }
133007 break;
133008 }
133009 }
133010 }
133011 if( reg==0 ) aToOpen[j+1] = 0;
133012 aRegIdx[j] = reg;
133013 }
 
133014 if( bReplace ){
133015 /* If REPLACE conflict resolution might be invoked, open cursors on all
133016 ** indexes in case they are needed to delete records. */
133017 memset(aToOpen, 1, nIdx+1);
133018 }
@@ -133023,11 +133288,17 @@
133023 if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
133024 sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
133025
133026 /* Allocate required registers. */
133027 if( !IsVirtual(pTab) ){
133028 regRowSet = ++pParse->nMem;
 
 
 
 
 
 
133029 regOldRowid = regNewRowid = ++pParse->nMem;
133030 if( chngPk || pTrigger || hasFK ){
133031 regOld = pParse->nMem + 1;
133032 pParse->nMem += pTab->nCol;
133033 }
@@ -133153,10 +133424,12 @@
133153 /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
133154 ** mode, write the rowid into the FIFO. In either of the one-pass modes,
133155 ** leave it in register regOldRowid. */
133156 sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
133157 if( eOnePass==ONEPASS_OFF ){
 
 
133158 sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
133159 }
133160 }else{
133161 /* Read the PK of the current row into an array of registers. In
133162 ** ONEPASS_OFF mode, serialize the array into a record and store it in
@@ -133984,10 +134257,11 @@
133984 */
133985 SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
133986 Vdbe *v = sqlite3GetVdbe(pParse);
133987 int iDb = 0;
133988 if( v==0 ) goto build_vacuum_end;
 
133989 if( pNm ){
133990 #ifndef SQLITE_BUG_COMPATIBLE_20160819
133991 /* Default behavior: Report an error if the argument to VACUUM is
133992 ** not recognized */
133993 iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
@@ -135136,18 +135410,20 @@
135136 }
135137 }
135138 p = vtabDisconnectAll(db, pTab);
135139 xDestroy = p->pMod->pModule->xDestroy;
135140 assert( xDestroy!=0 ); /* Checked before the virtual table is created */
 
135141 rc = xDestroy(p->pVtab);
135142 /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
135143 if( rc==SQLITE_OK ){
135144 assert( pTab->pVTable==p && p->pNext==0 );
135145 p->pVtab = 0;
135146 pTab->pVTable = 0;
135147 sqlite3VtabUnlock(p);
135148 }
 
135149 }
135150
135151 return rc;
135152 }
135153
@@ -135586,10 +135862,12 @@
135586 **
135587 ** This file contains structure and macro definitions for the query
135588 ** planner logic in "where.c". These definitions are broken out into
135589 ** a separate source file for easier editing.
135590 */
 
 
135591
135592 /*
135593 ** Trace output macros
135594 */
135595 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
@@ -136156,10 +136434,12 @@
136156 #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
136157 #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
136158 #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
136159 #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
136160 #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
 
 
136161
136162 /************** End of whereInt.h ********************************************/
136163 /************** Continuing where we left off in wherecode.c ******************/
136164
136165 #ifndef SQLITE_OMIT_EXPLAIN
@@ -137139,11 +137419,11 @@
137139 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
137140 if( sWalker.eCode ) continue;
137141 }
137142
137143 /* If we survive all prior tests, that means this term is worth hinting */
137144 pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
137145 }
137146 if( pExpr!=0 ){
137147 sWalker.xExprCallback = codeCursorHintFixExpr;
137148 sqlite3WalkExpr(&sWalker, pExpr);
137149 sqlite3VdbeAddOp4(v, OP_CursorHint,
@@ -138104,11 +138384,11 @@
138104 testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
138105 if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
138106 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
138107 testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
138108 pExpr = sqlite3ExprDup(db, pExpr, 0);
138109 pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
138110 }
138111 if( pAndExpr ){
138112 /* The extra 0x10000 bit on the opcode is masked off and does not
138113 ** become part of the new Expr.op. However, it does make the
138114 ** op==TK_AND comparison inside of sqlite3PExpr() false, and this
@@ -138255,11 +138535,11 @@
138255 }
138256 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
138257 sqlite3VdbeGoto(v, pLevel->addrBrk);
138258 sqlite3VdbeResolveLabel(v, iLoopBody);
138259
138260 if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
138261 if( !untestedTerms ) disableTerm(pLevel, pTerm);
138262 }else
138263 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
138264
138265 {
@@ -138688,26 +138968,28 @@
138688 for(iFrom=iTo=0; iFrom<cnt; iFrom++){
138689 if( zNew[iFrom]==wc[3] ) iFrom++;
138690 zNew[iTo++] = zNew[iFrom];
138691 }
138692 zNew[iTo] = 0;
 
138693
138694 /* If the RHS begins with a digit or a minus sign, then the LHS must be
138695 ** an ordinary column (not a virtual table column) with TEXT affinity.
138696 ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
138697 ** even though "lhs LIKE rhs" is true. But if the RHS does not start
138698 ** with a digit or '-', then "lhs LIKE rhs" will always be false if
138699 ** the LHS is numeric and so the optimization still works.
138700 **
138701 ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
138702 ** The RHS pattern must not be '/%' because the termination condition
138703 ** will then become "x<'0'" and if the affinity is numeric, will then
138704 ** be converted into "x<0", which is incorrect.
138705 */
138706 if( sqlite3Isdigit(zNew[0])
138707 || zNew[0]=='-'
138708 || (zNew[0]+1=='0' && iTo==1)
 
138709 ){
138710 if( pLeft->op!=TK_COLUMN
138711 || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
138712 || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
138713 ){
@@ -140770,11 +141052,11 @@
140770 || pLoop->prereq!=0 ); /* table of a LEFT JOIN */
140771 if( pLoop->prereq==0
140772 && (pTerm->wtFlags & TERM_VIRTUAL)==0
140773 && !ExprHasProperty(pExpr, EP_FromJoin)
140774 && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
140775 pPartial = sqlite3ExprAnd(pParse->db, pPartial,
140776 sqlite3ExprDup(pParse->db, pExpr, 0));
140777 }
140778 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
140779 int iCol = pTerm->u.leftColumn;
140780 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
@@ -146275,17 +146557,22 @@
146275 ** expression list pList. Return a pointer to the result list.
146276 */
146277 static ExprList *exprListAppendList(
146278 Parse *pParse, /* Parsing context */
146279 ExprList *pList, /* List to which to append. Might be NULL */
146280 ExprList *pAppend /* List of values to append. Might be NULL */
 
146281 ){
146282 if( pAppend ){
146283 int i;
146284 int nInit = pList ? pList->nExpr : 0;
146285 for(i=0; i<pAppend->nExpr; i++){
146286 Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
 
 
 
 
146287 pList = sqlite3ExprListAppend(pParse, pList, pDup);
146288 if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
146289 }
146290 }
146291 return pList;
@@ -146321,11 +146608,11 @@
146321
146322 /* Create the ORDER BY clause for the sub-select. This is the concatenation
146323 ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
146324 ** redundant, remove the ORDER BY from the parent SELECT. */
146325 pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
146326 pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
146327 if( pSort && p->pOrderBy ){
146328 if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
146329 sqlite3ExprListDelete(db, p->pOrderBy);
146330 p->pOrderBy = 0;
146331 }
@@ -146342,20 +146629,20 @@
146342 pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
146343
146344 /* Append the PARTITION BY and ORDER BY expressions to the to the
146345 ** sub-select expression list. They are required to figure out where
146346 ** boundaries for partitions and sets of peer rows lie. */
146347 pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
146348 pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
146349
146350 /* Append the arguments passed to each window function to the
146351 ** sub-select expression list. Also allocate two registers for each
146352 ** window function - one for the accumulator, another for interim
146353 ** results. */
146354 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
146355 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
146356 pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
146357 if( pWin->pFilter ){
146358 Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
146359 pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
146360 }
146361 pWin->regAccum = ++pParse->nMem;
@@ -152081,11 +152368,13 @@
152081 sqlite3ExprListDelete(pParse->db, pList);
152082 }
152083 }
152084 break;
152085 case 179: /* expr ::= expr AND expr */
152086 case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180);
 
 
152087 case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
152088 case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
152089 case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
152090 case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
152091 case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
@@ -158717,10 +159006,26 @@
158717 FILE *out = va_arg(ap, FILE*);
158718 if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
158719 break;
158720 }
158721 #endif /* defined(YYCOVERAGE) */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158722 }
158723 va_end(ap);
158724 #endif /* SQLITE_UNTESTABLE */
158725 return rc;
158726 }
@@ -174130,11 +174435,11 @@
174130 if( bFirst==0 ){
174131 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
174132 }
174133 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
174134
174135 if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
174136 return FTS_CORRUPT_VTAB;
174137 }
174138 blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
174139 if( rc==SQLITE_OK ){
174140 memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -174149,11 +174454,11 @@
174149 p->iOff += p->nDoclist;
174150 }
174151 }
174152 }
174153
174154 assert( p->iOff<=p->nNode );
174155 return rc;
174156 }
174157
174158 /*
174159 ** Release all dynamic resources held by node-reader object *p.
@@ -189790,11 +190095,12 @@
189790 assert( argc==1 || argc==2 );
189791
189792 zIn = (const char*)sqlite3_value_text(argv[0]);
189793 if( zIn ){
189794 if( rbuIsVacuum(p) ){
189795 if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
 
189796 sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
189797 }
189798 }else{
189799 if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
189800 int i;
@@ -190241,11 +190547,12 @@
190241 SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
190242 SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
190243 }
190244
190245 pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
190246 pIter->abTblPk[iOrder] = (iPk!=0);
 
190247 pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
190248 iOrder++;
190249 }
190250 }
190251
@@ -190275,10 +190582,217 @@
190275 zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
190276 zSep = ", ";
190277 }
190278 return zList;
190279 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190280
190281 /*
190282 ** This function is used to create a SELECT list (the list of SQL
190283 ** expressions that follows a SELECT keyword) for a SELECT statement
190284 ** used to read from an data_xxx or rbu_tmp_xxx table while updating the
@@ -190952,16 +191466,28 @@
190952
190953 /* Create the SELECT statement to read keys in sorted order */
190954 if( p->rc==SQLITE_OK ){
190955 char *zSql;
190956 if( rbuIsVacuum(p) ){
 
 
 
 
 
 
 
 
 
190957 zSql = sqlite3_mprintf(
190958 "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
190959 zCollist,
190960 pIter->zDataTbl,
190961 zPart, zCollist, zLimit
 
 
190962 );
 
190963 }else
190964
190965 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
190966 zSql = sqlite3_mprintf(
190967 "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
@@ -190980,11 +191506,15 @@
190980 zPart,
190981 (zPart ? "AND" : "WHERE"),
190982 zCollist, zLimit
190983 );
190984 }
190985 p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
 
 
 
 
190986 }
190987
190988 sqlite3_free(zImposterCols);
190989 sqlite3_free(zImposterPK);
190990 sqlite3_free(zWhere);
@@ -191080,22 +191610,46 @@
191080 }
191081
191082 /* Create the SELECT statement to read keys from data_xxx */
191083 if( p->rc==SQLITE_OK ){
191084 const char *zRbuRowid = "";
 
 
191085 if( bRbuRowid ){
191086 zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
191087 }
191088 p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
191089 sqlite3_mprintf(
191090 "SELECT %s,%s rbu_control%s FROM '%q'%s",
191091 zCollist,
191092 (rbuIsVacuum(p) ? "0 AS " : ""),
191093 zRbuRowid,
191094 pIter->zDataTbl, zLimit
191095 )
191096 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191097 }
191098
191099 sqlite3_free(zWhere);
191100 sqlite3_free(zOldlist);
191101 sqlite3_free(zNewlist);
@@ -193661,11 +194215,12 @@
193661 ** be intercepted (see the rbuVfsOpen() function) and the *-oal
193662 ** file opened instead.
193663 */
193664 if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
193665 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
193666 if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
 
193667 if( *pResOut ){
193668 rc = SQLITE_CANTOPEN;
193669 }else{
193670 sqlite3_int64 sz = 0;
193671 rc = rbuVfsFileSize(&pDb->base, &sz);
@@ -204285,11 +204840,15 @@
204285 return 1;
204286 }else{
204287 i64 iOff = *piOff;
204288 int iVal;
204289 fts5FastGetVarint32(a, i, iVal);
204290 if( iVal==1 ){
 
 
 
 
204291 fts5FastGetVarint32(a, i, iVal);
204292 iOff = ((i64)iVal) << 32;
204293 fts5FastGetVarint32(a, i, iVal);
204294 }
204295 *piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
@@ -218101,11 +218660,11 @@
218101 int nArg, /* Number of args */
218102 sqlite3_value **apUnused /* Function arguments */
218103 ){
218104 assert( nArg==0 );
218105 UNUSED_PARAM2(nArg, apUnused);
218106 sqlite3_result_text(pCtx, "fts5: 2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50", -1, SQLITE_TRANSIENT);
218107 }
218108
218109 /*
218110 ** Return true if zName is the extension on one of the shadow tables used
218111 ** by this module.
@@ -222865,12 +223424,12 @@
222865 }
222866 #endif /* SQLITE_CORE */
222867 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
222868
222869 /************** End of stmt.c ************************************************/
222870 #if __LINE__!=222870
222871 #undef SQLITE_SOURCE_ID
222872 #define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f8315alt2"
222873 #endif
222874 /* Return the source-id for this library */
222875 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
222876 /************************** End of sqlite3.c ******************************/
222877
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.29.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -886,10 +886,15 @@
886 #pragma warning(disable : 4306)
887 #pragma warning(disable : 4702)
888 #pragma warning(disable : 4706)
889 #endif /* defined(_MSC_VER) */
890
891 #if defined(_MSC_VER) && !defined(_WIN64)
892 #undef SQLITE_4_BYTE_ALIGNED_MALLOC
893 #define SQLITE_4_BYTE_ALIGNED_MALLOC
894 #endif /* defined(_MSC_VER) && !defined(_WIN64) */
895
896 #endif /* SQLITE_MSVC_H */
897
898 /************** End of msvc.h ************************************************/
899 /************** Continuing where we left off in sqliteInt.h ******************/
900
@@ -1160,13 +1165,13 @@
1165 **
1166 ** See also: [sqlite3_libversion()],
1167 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1168 ** [sqlite_version()] and [sqlite_source_id()].
1169 */
1170 #define SQLITE_VERSION "3.29.0"
1171 #define SQLITE_VERSION_NUMBER 3029000
1172 #define SQLITE_SOURCE_ID "2019-05-10 17:54:58 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000f2362"
1173
1174 /*
1175 ** CAPI3REF: Run-Time Library Version Numbers
1176 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1177 **
@@ -8356,11 +8361,12 @@
8361 #define SQLITE_TESTCTRL_BYTEORDER 22
8362 #define SQLITE_TESTCTRL_ISINIT 23
8363 #define SQLITE_TESTCTRL_SORTER_MMAP 24
8364 #define SQLITE_TESTCTRL_IMPOSTER 25
8365 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26
8366 #define SQLITE_TESTCTRL_RESULT_INTREAL 27
8367 #define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
8368
8369 /*
8370 ** CAPI3REF: SQL Keyword Checking
8371 **
8372 ** These routines provide access to the set of SQL language keywords
@@ -17451,10 +17457,12 @@
17457 #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
17458 #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
17459 #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
17460 #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
17461 #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
17462 #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
17463 #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
17464
17465 /*
17466 ** The EP_Propagate mask is a set of properties that automatically propagate
17467 ** upwards into parent nodes.
17468 */
@@ -17466,10 +17474,12 @@
17474 */
17475 #define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
17476 #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
17477 #define ExprSetProperty(E,P) (E)->flags|=(P)
17478 #define ExprClearProperty(E,P) (E)->flags&=~(P)
17479 #define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
17480 #define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
17481
17482 /* The ExprSetVVAProperty() macro is used for Verification, Validation,
17483 ** and Accreditation only. It works like ExprSetProperty() during VVA
17484 ** processes but is a no-op for delivery.
17485 */
@@ -18775,11 +18785,12 @@
18785 SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
18786 SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
18787 SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
18788 SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
18789 SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
18790 SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
18791 SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*);
18792 SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
18793 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
18794 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
18795 SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
18796 SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
@@ -19188,10 +19199,13 @@
19199 SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
19200 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
19201 void(*)(void*));
19202 SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
19203 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
19204 #ifndef SQLITE_UNTESTABLE
19205 SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*);
19206 #endif
19207 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
19208 #ifndef SQLITE_OMIT_UTF16
19209 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
19210 #endif
19211 SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
@@ -20178,16 +20192,16 @@
20192 #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
20193 #define MEM_Str 0x0002 /* Value is a string */
20194 #define MEM_Int 0x0004 /* Value is an integer */
20195 #define MEM_Real 0x0008 /* Value is a real number */
20196 #define MEM_Blob 0x0010 /* Value is a BLOB */
20197 #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
20198 #define MEM_AffMask 0x003f /* Mask of affinity bits */
20199 #define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
20200 #define MEM_Undefined 0x0080 /* Value is undefined */
20201 #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
20202 #define MEM_TypeMask 0xc1bf /* Mask of type bits */
20203
20204
20205 /* Whenever Mem contains a valid string or blob representation, one of
20206 ** the following flags must be set to determine the memory management
20207 ** policy for Mem.z. The MEM_Term flag tells us whether or not the
@@ -30210,13 +30224,11 @@
30224 ** strings, and stuff like that.
30225 **
30226 */
30227 /* #include "sqliteInt.h" */
30228 /* #include <stdarg.h> */
30229 #include <math.h>
 
 
30230
30231 /*
30232 ** Routine needed to support the testcase() macro.
30233 */
30234 #ifdef SQLITE_COVERAGE_TEST
@@ -30515,16 +30527,22 @@
30527 }
30528 return sqlite3StrICmp(zLeft, zRight);
30529 }
30530 SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
30531 unsigned char *a, *b;
30532 int c, x;
30533 a = (unsigned char *)zLeft;
30534 b = (unsigned char *)zRight;
30535 for(;;){
30536 c = *a;
30537 x = *b;
30538 if( c==x ){
30539 if( c==0 ) break;
30540 }else{
30541 c = (int)UpperToLower[c] - (int)UpperToLower[x];
30542 if( c ) break;
30543 }
30544 a++;
30545 b++;
30546 }
30547 return c;
30548 }
@@ -31105,36 +31123,26 @@
31123 ** Return the number of bytes read. The value is stored in *v.
31124 */
31125 SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
31126 u32 a,b,s;
31127
31128 if( ((signed char*)p)[0]>=0 ){
31129 *v = *p;
 
 
 
31130 return 1;
31131 }
31132 if( ((signed char*)p)[1]>=0 ){
31133 *v = ((u32)(p[0]&0x7f)<<7) | p[1];
 
 
 
 
 
 
 
 
31134 return 2;
31135 }
31136
31137 /* Verify that constants are precomputed correctly */
31138 assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
31139 assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
31140
31141 a = ((u32)p[0])<<14;
31142 b = p[1];
31143 p += 2;
31144 a |= *p;
31145 /* a: p0<<14 | p2 (unmasked) */
31146 if (!(a&0x80))
31147 {
31148 a &= SLOT_2_0;
@@ -61220,13 +61228,13 @@
61228 if( rc!=SQLITE_OK ){
61229 return rc;
61230 }
61231 nCollide = HASHTABLE_NSLOT;
61232 for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
61233 u32 iH = sLoc.aHash[iKey];
61234 u32 iFrame = iH + sLoc.iZero;
61235 if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
61236 assert( iFrame>iRead || CORRUPT_DB );
61237 iRead = iFrame;
61238 }
61239 if( (nCollide--)==0 ){
61240 return SQLITE_CORRUPT_BKPT;
@@ -64814,11 +64822,11 @@
64822 ** and the reserved space is zero (the usual value for reserved space)
64823 ** then the cell content offset of an empty page wants to be 65536.
64824 ** However, that integer is too large to be stored in a 2-byte unsigned
64825 ** integer, so a value of 0 is used in its place. */
64826 top = get2byte(&data[hdr+5]);
64827 assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
64828 if( gap>top ){
64829 if( top==0 && pPage->pBt->usableSize==65536 ){
64830 top = 65536;
64831 }else{
64832 return SQLITE_CORRUPT_PAGE(pPage);
@@ -65111,11 +65119,11 @@
65119 ** the cell-content area. If this is greater than the usable-size
65120 ** of the page, then the page must be corrupted. This check also
65121 ** serves to verify that the offset to the start of the cell-content
65122 ** area, according to the page header, lies within the page.
65123 */
65124 if( nFree>usableSize || nFree<iCellFirst ){
65125 return SQLITE_CORRUPT_PAGE(pPage);
65126 }
65127 pPage->nFree = (u16)(nFree - iCellFirst);
65128 return SQLITE_OK;
65129 }
@@ -67338,10 +67346,22 @@
67346 }
67347 sqlite3BtreeLeave(pBtree);
67348 }
67349 return rc;
67350 }
67351
67352 /*
67353 ** Set the pBt->nPage field correctly, according to the current
67354 ** state of the database. Assume pBt->pPage1 is valid.
67355 */
67356 static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
67357 int nPage = get4byte(&pPage1->aData[28]);
67358 testcase( nPage==0 );
67359 if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
67360 testcase( pBt->nPage!=nPage );
67361 pBt->nPage = nPage;
67362 }
67363
67364 /*
67365 ** Rollback the transaction in progress.
67366 **
67367 ** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
@@ -67384,15 +67404,11 @@
67404
67405 /* The rollback may have destroyed the pPage1->aData value. So
67406 ** call btreeGetPage() on page 1 again to make
67407 ** sure pPage1->aData is set correctly. */
67408 if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
67409 btreeSetNPage(pBt, pPage1);
 
 
 
 
67410 releasePageOne(pPage1);
67411 }
67412 assert( countValidCursors(pBt, 1)==0 );
67413 pBt->inTransaction = TRANS_READ;
67414 btreeClearHasContent(pBt);
@@ -67468,16 +67484,15 @@
67484 if( rc==SQLITE_OK ){
67485 if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
67486 pBt->nPage = 0;
67487 }
67488 rc = newDatabase(pBt);
67489 btreeSetNPage(pBt, pBt->pPage1);
67490
67491 /* pBt->nPage might be zero if the database was corrupt when
67492 ** the transaction was started. Otherwise, it must be at least 1. */
67493 assert( CORRUPT_DB || pBt->nPage>0 );
 
67494 }
67495 sqlite3BtreeLeave(p);
67496 }
67497 return rc;
67498 }
@@ -68481,10 +68496,11 @@
68496 assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
68497 }
68498 assert( pCur->ix==pCur->pPage->nCell-1 );
68499 assert( pCur->pPage->leaf );
68500 #endif
68501 *pRes = 0;
68502 return SQLITE_OK;
68503 }
68504
68505 rc = moveToRoot(pCur);
68506 if( rc==SQLITE_OK ){
@@ -70823,10 +70839,11 @@
70839 int limit = pOld->nCell;
70840 u8 *aData = pOld->aData;
70841 u16 maskPage = pOld->maskPage;
70842 u8 *piCell = aData + pOld->cellOffset;
70843 u8 *piEnd;
70844 VVA_ONLY( int nCellAtStart = b.nCell; )
70845
70846 /* Verify that all sibling pages are of the same "type" (table-leaf,
70847 ** table-interior, index-leaf, or index-interior).
70848 */
70849 if( pOld->aData[0]!=apOld[0]->aData[0] ){
@@ -70851,10 +70868,14 @@
70868 ** long be able to find the cells if a pointer to each cell is not saved
70869 ** first.
70870 */
70871 memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
70872 if( pOld->nOverflow>0 ){
70873 if( limit<pOld->aiOvfl[0] ){
70874 rc = SQLITE_CORRUPT_BKPT;
70875 goto balance_cleanup;
70876 }
70877 limit = pOld->aiOvfl[0];
70878 for(j=0; j<limit; j++){
70879 b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
70880 piCell += 2;
70881 b.nCell++;
@@ -70870,10 +70891,11 @@
70891 assert( b.nCell<nMaxCells );
70892 b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
70893 piCell += 2;
70894 b.nCell++;
70895 }
70896 assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) );
70897
70898 cntOld[i] = b.nCell;
70899 if( i<nOld-1 && !leafData){
70900 u16 sz = (u16)szNew[i];
70901 u8 *pTemp;
@@ -71170,10 +71192,11 @@
71192 for(i=0; i<b.nCell; i++){
71193 u8 *pCell = b.apCell[i];
71194 while( i==cntOldNext ){
71195 iOld++;
71196 assert( iOld<nNew || iOld<nOld );
71197 assert( iOld>=0 && iOld<NB );
71198 pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
71199 cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
71200 }
71201 if( i==cntNew[iNew] ){
71202 pNew = apNew[++iNew];
@@ -73890,11 +73913,11 @@
73913 ** then the backup cannot proceed.
73914 */
73915 if( nSrcReserve!=nDestReserve ){
73916 u32 newPgsz = nSrcPgsz;
73917 rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
73918 if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
73919 }
73920 #endif
73921
73922 /* This loop runs once for each destination page spanned by the source
73923 ** page. For each iteration, variable iOff is set to the byte offset
@@ -74437,10 +74460,15 @@
74460 ** name sqlite_value
74461 */
74462 /* #include "sqliteInt.h" */
74463 /* #include "vdbeInt.h" */
74464
74465 /* True if X is a power of two. 0 is considered a power of two here.
74466 ** In other words, return true if X has at most one bit set.
74467 */
74468 #define ISPOWEROF2(X) (((X)&((X)-1))==0)
74469
74470 #ifdef SQLITE_DEBUG
74471 /*
74472 ** Check invariants on a Mem object.
74473 **
74474 ** This routine is intended for use inside of assert() statements, like
@@ -74456,12 +74484,12 @@
74484 ** ensure that if Mem.szMalloc>0 then it is safe to do
74485 ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
74486 ** That saves a few cycles in inner loops. */
74487 assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
74488
74489 /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
74490 assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
74491
74492 if( p->flags & MEM_Null ){
74493 /* Cannot be both MEM_Null and some other type */
74494 assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
74495
@@ -74510,10 +74538,29 @@
74538 );
74539 }
74540 return 1;
74541 }
74542 #endif
74543
74544 /*
74545 ** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
74546 ** into a buffer.
74547 */
74548 static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
74549 StrAccum acc;
74550 assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
74551 sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
74552 if( p->flags & MEM_Int ){
74553 sqlite3_str_appendf(&acc, "%lld", p->u.i);
74554 }else if( p->flags & MEM_IntReal ){
74555 sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
74556 }else{
74557 sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
74558 }
74559 assert( acc.zText==zBuf && acc.mxAlloc<=0 );
74560 zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
74561 }
74562
74563 #ifdef SQLITE_DEBUG
74564 /*
74565 ** Check that string value of pMem agrees with its integer or real value.
74566 **
@@ -74536,16 +74583,12 @@
74583 SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
74584 char zBuf[100];
74585 char *z;
74586 int i, j, incr;
74587 if( (p->flags & MEM_Str)==0 ) return 1;
74588 if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
74589 vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
 
 
 
 
74590 z = p->z;
74591 i = j = 0;
74592 incr = 1;
74593 if( p->enc!=SQLITE_UTF8 ){
74594 incr = 2;
@@ -74653,12 +74696,12 @@
74696 ** If pMem->zMalloc already meets or exceeds the requested size, this
74697 ** routine is a no-op.
74698 **
74699 ** Any prior string or blob content in the pMem object may be discarded.
74700 ** The pMem->xDel destructor is called, if it exists. Though MEM_Str
74701 ** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
74702 ** and MEM_Null values are preserved.
74703 **
74704 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
74705 ** if unable to complete the resizing.
74706 */
74707 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
@@ -74667,24 +74710,30 @@
74710 if( pMem->szMalloc<szNew ){
74711 return sqlite3VdbeMemGrow(pMem, szNew, 0);
74712 }
74713 assert( (pMem->flags & MEM_Dyn)==0 );
74714 pMem->z = pMem->zMalloc;
74715 pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
74716 return SQLITE_OK;
74717 }
74718
74719 /*
74720 ** It is already known that pMem contains an unterminated string.
74721 ** Add the zero terminator.
74722 **
74723 ** Three bytes of zero are added. In this way, there is guaranteed
74724 ** to be a double-zero byte at an even byte boundary in order to
74725 ** terminate a UTF16 string, even if the initial size of the buffer
74726 ** is an odd number of bytes.
74727 */
74728 static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
74729 if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
74730 return SQLITE_NOMEM_BKPT;
74731 }
74732 pMem->z[pMem->n] = 0;
74733 pMem->z[pMem->n+1] = 0;
74734 pMem->z[pMem->n+2] = 0;
74735 pMem->flags |= MEM_Term;
74736 return SQLITE_OK;
74737 }
74738
74739 /*
@@ -74754,57 +74803,45 @@
74803 return vdbeMemAddTerminator(pMem);
74804 }
74805 }
74806
74807 /*
74808 ** Add MEM_Str to the set of representations for the given Mem. This
74809 ** routine is only called if pMem is a number of some kind, not a NULL
74810 ** or a BLOB.
74811 **
74812 ** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
74813 ** if bForce is true but are retained if bForce is false.
74814 **
74815 ** A MEM_Null value will never be passed to this function. This function is
74816 ** used for converting values to text for returning to the user (i.e. via
74817 ** sqlite3_value_text()), or for ensuring that values to be used as btree
74818 ** keys are strings. In the former case a NULL pointer is returned the
74819 ** user and the latter is an internal programming error.
74820 */
74821 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
 
74822 const int nByte = 32;
74823
74824 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
74825 assert( !(pMem->flags&MEM_Zero) );
74826 assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
74827 assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
74828 assert( !sqlite3VdbeMemIsRowSet(pMem) );
74829 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
74830
74831
74832 if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
74833 pMem->enc = 0;
74834 return SQLITE_NOMEM_BKPT;
74835 }
74836
74837 vdbeMemRenderNum(nByte, pMem->z, pMem);
 
 
 
 
 
 
 
 
 
 
 
74838 assert( pMem->z!=0 );
74839 pMem->n = sqlite3Strlen30NN(pMem->z);
74840 pMem->enc = SQLITE_UTF8;
74841 pMem->flags |= MEM_Str|MEM_Term;
74842 if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
74843 sqlite3VdbeChangeEncoding(pMem, enc);
74844 return SQLITE_OK;
74845 }
74846
74847 /*
@@ -74974,11 +75011,12 @@
75011 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
75012 int flags;
75013 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
75014 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
75015 flags = pMem->flags;
75016 if( flags & (MEM_Int|MEM_IntReal) ){
75017 testcase( flags & MEM_IntReal );
75018 return pMem->u.i;
75019 }else if( flags & MEM_Real ){
75020 return doubleToInt64(pMem->u.r);
75021 }else if( flags & (MEM_Str|MEM_Blob) ){
75022 assert( pMem->z || pMem->n==0 );
@@ -75003,11 +75041,12 @@
75041 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
75042 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
75043 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
75044 if( pMem->flags & MEM_Real ){
75045 return pMem->u.r;
75046 }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
75047 testcase( pMem->flags & MEM_IntReal );
75048 return (double)pMem->u.i;
75049 }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
75050 return memRealValue(pMem);
75051 }else{
75052 /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
@@ -75018,11 +75057,12 @@
75057 /*
75058 ** Return 1 if pMem represents true, and return 0 if pMem represents false.
75059 ** Return the value ifNull if pMem is NULL.
75060 */
75061 SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
75062 testcase( pMem->flags & MEM_IntReal );
75063 if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
75064 if( pMem->flags & MEM_Null ) return ifNull;
75065 return sqlite3VdbeRealValue(pMem)!=0.0;
75066 }
75067
75068 /*
@@ -75091,19 +75131,23 @@
75131 double r2 = (double)i;
75132 return memcmp(&r1, &r2, sizeof(r1))==0;
75133 }
75134
75135 /*
75136 ** Convert pMem so that it has type MEM_Real or MEM_Int.
75137 ** Invalidate any prior representations.
75138 **
75139 ** Every effort is made to force the conversion, even if the input
75140 ** is a string that does not look completely like a number. Convert
75141 ** as much of the string as we can and ignore the rest.
75142 */
75143 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
75144 testcase( pMem->flags & MEM_Int );
75145 testcase( pMem->flags & MEM_Real );
75146 testcase( pMem->flags & MEM_IntReal );
75147 testcase( pMem->flags & MEM_Null );
75148 if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
75149 int rc;
75150 assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
75151 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
75152 rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
75153 if( rc==0 ){
@@ -75117,11 +75161,11 @@
75161 }else{
75162 MemSetTypeFlag(pMem, MEM_Real);
75163 }
75164 }
75165 }
75166 assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
75167 pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
75168 return SQLITE_OK;
75169 }
75170
75171 /*
@@ -75160,11 +75204,11 @@
75204 assert( aff==SQLITE_AFF_TEXT );
75205 assert( MEM_Str==(MEM_Blob>>3) );
75206 pMem->flags |= (pMem->flags&MEM_Blob)>>3;
75207 sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
75208 assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
75209 pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
75210 break;
75211 }
75212 }
75213 }
75214
@@ -75344,11 +75388,11 @@
75388 ** A significant change would indicated a missed call to this
75389 ** function for pX. Minor changes, such as adding or removing a
75390 ** dual type, are allowed, as long as the underlying value is the
75391 ** same. */
75392 u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
75393 assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
75394 assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
75395 assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
75396 assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
75397
75398 /* pMem is the register that is changing. But also mark pX as
@@ -75907,11 +75951,16 @@
75951 if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
75952 sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
75953 }else{
75954 sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
75955 }
75956 assert( (pVal->flags & MEM_IntReal)==0 );
75957 if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
75958 testcase( pVal->flags & MEM_Int );
75959 testcase( pVal->flags & MEM_Real );
75960 pVal->flags &= ~MEM_Str;
75961 }
75962 if( enc!=SQLITE_UTF8 ){
75963 rc = sqlite3VdbeChangeEncoding(pVal, enc);
75964 }
75965 }else if( op==TK_UMINUS ) {
75966 /* This branch happens for multiple negative signs. Ex: -(-5) */
@@ -75930,11 +75979,11 @@
75979 sqlite3ValueApplyAffinity(pVal, affinity, enc);
75980 }
75981 }else if( op==TK_NULL ){
75982 pVal = valueNew(db, pCtx);
75983 if( pVal==0 ) goto no_mem;
75984 sqlite3VdbeMemSetNull(pVal);
75985 }
75986 #ifndef SQLITE_OMIT_BLOB_LITERAL
75987 else if( op==TK_BLOB ){
75988 int nVal;
75989 assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
@@ -77847,11 +77896,11 @@
77896 }
77897 case P4_MEM: {
77898 Mem *pMem = pOp->p4.pMem;
77899 if( pMem->flags & MEM_Str ){
77900 zP4 = pMem->z;
77901 }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
77902 sqlite3_str_appendf(&x, "%lld", pMem->u.i);
77903 }else if( pMem->flags & MEM_Real ){
77904 sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
77905 }else if( pMem->flags & MEM_Null ){
77906 zP4 = "NULL";
@@ -79209,11 +79258,11 @@
79258 }
79259 }
79260 }
79261
79262 /* Check for immediate foreign key violations. */
79263 if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
79264 sqlite3VdbeCheckFk(p, 0);
79265 }
79266
79267 /* If the auto-commit flag is set and this is the only active writer
79268 ** VM, then we do either a commit or rollback of the current transaction.
@@ -79735,10 +79784,12 @@
79784 ** of SQLite will not understand those serial types.
79785 */
79786
79787 /*
79788 ** Return the serial-type for the value stored in pMem.
79789 **
79790 ** This routine might convert a large MEM_IntReal value into MEM_Real.
79791 */
79792 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
79793 int flags = pMem->flags;
79794 u32 n;
79795
@@ -79745,15 +79796,17 @@
79796 assert( pLen!=0 );
79797 if( flags&MEM_Null ){
79798 *pLen = 0;
79799 return 0;
79800 }
79801 if( flags&(MEM_Int|MEM_IntReal) ){
79802 /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
79803 # define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
79804 i64 i = pMem->u.i;
79805 u64 u;
79806 testcase( flags & MEM_Int );
79807 testcase( flags & MEM_IntReal );
79808 if( i<0 ){
79809 u = ~i;
79810 }else{
79811 u = i;
79812 }
@@ -79769,10 +79822,19 @@
79822 if( u<=32767 ){ *pLen = 2; return 2; }
79823 if( u<=8388607 ){ *pLen = 3; return 3; }
79824 if( u<=2147483647 ){ *pLen = 4; return 4; }
79825 if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
79826 *pLen = 8;
79827 if( flags&MEM_IntReal ){
79828 /* If the value is IntReal and is going to take up 8 bytes to store
79829 ** as an integer, then we might as well make it an 8-byte floating
79830 ** point value */
79831 pMem->u.r = (double)pMem->u.i;
79832 pMem->flags &= ~MEM_IntReal;
79833 pMem->flags |= MEM_Real;
79834 return 7;
79835 }
79836 return 6;
79837 }
79838 if( flags&MEM_Real ){
79839 *pLen = 8;
79840 return 7;
@@ -80424,30 +80486,43 @@
80486 return (f2&MEM_Null) - (f1&MEM_Null);
80487 }
80488
80489 /* At least one of the two values is a number
80490 */
80491 if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
80492 testcase( combined_flags & MEM_Int );
80493 testcase( combined_flags & MEM_Real );
80494 testcase( combined_flags & MEM_IntReal );
80495 if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
80496 testcase( f1 & f2 & MEM_Int );
80497 testcase( f1 & f2 & MEM_IntReal );
80498 if( pMem1->u.i < pMem2->u.i ) return -1;
80499 if( pMem1->u.i > pMem2->u.i ) return +1;
80500 return 0;
80501 }
80502 if( (f1 & f2 & MEM_Real)!=0 ){
80503 if( pMem1->u.r < pMem2->u.r ) return -1;
80504 if( pMem1->u.r > pMem2->u.r ) return +1;
80505 return 0;
80506 }
80507 if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
80508 testcase( f1 & MEM_Int );
80509 testcase( f1 & MEM_IntReal );
80510 if( (f2&MEM_Real)!=0 ){
80511 return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
80512 }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
80513 if( pMem1->u.i < pMem2->u.i ) return -1;
80514 if( pMem1->u.i > pMem2->u.i ) return +1;
80515 return 0;
80516 }else{
80517 return -1;
80518 }
80519 }
80520 if( (f1&MEM_Real)!=0 ){
80521 if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
80522 testcase( f2 & MEM_Int );
80523 testcase( f2 & MEM_IntReal );
80524 return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
80525 }else{
80526 return -1;
80527 }
80528 }
@@ -80592,11 +80667,13 @@
80667 assert( idx1<=szHdr1 || CORRUPT_DB );
80668 do{
80669 u32 serial_type;
80670
80671 /* RHS is an integer */
80672 if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
80673 testcase( pRhs->flags & MEM_Int );
80674 testcase( pRhs->flags & MEM_IntReal );
80675 serial_type = aKey1[idx1];
80676 testcase( serial_type==12 );
80677 if( serial_type>=10 ){
80678 rc = +1;
80679 }else if( serial_type==0 ){
@@ -80937,11 +81014,13 @@
81014 return vdbeRecordCompareInt;
81015 }
81016 testcase( flags & MEM_Real );
81017 testcase( flags & MEM_Null );
81018 testcase( flags & MEM_Blob );
81019 if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
81020 && p->pKeyInfo->aColl[0]==0
81021 ){
81022 assert( flags & MEM_Str );
81023 return vdbeRecordCompareString;
81024 }
81025 }
81026
@@ -81527,43 +81606,90 @@
81606 ** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
81607 ** point number string BLOB NULL
81608 */
81609 SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
81610 static const u8 aType[] = {
81611 SQLITE_BLOB, /* 0x00 (not possible) */
81612 SQLITE_NULL, /* 0x01 NULL */
81613 SQLITE_TEXT, /* 0x02 TEXT */
81614 SQLITE_NULL, /* 0x03 (not possible) */
81615 SQLITE_INTEGER, /* 0x04 INTEGER */
81616 SQLITE_NULL, /* 0x05 (not possible) */
81617 SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */
81618 SQLITE_NULL, /* 0x07 (not possible) */
81619 SQLITE_FLOAT, /* 0x08 FLOAT */
81620 SQLITE_NULL, /* 0x09 (not possible) */
81621 SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */
81622 SQLITE_NULL, /* 0x0b (not possible) */
81623 SQLITE_INTEGER, /* 0x0c (not possible) */
81624 SQLITE_NULL, /* 0x0d (not possible) */
81625 SQLITE_INTEGER, /* 0x0e (not possible) */
81626 SQLITE_NULL, /* 0x0f (not possible) */
81627 SQLITE_BLOB, /* 0x10 BLOB */
81628 SQLITE_NULL, /* 0x11 (not possible) */
81629 SQLITE_TEXT, /* 0x12 (not possible) */
81630 SQLITE_NULL, /* 0x13 (not possible) */
81631 SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */
81632 SQLITE_NULL, /* 0x15 (not possible) */
81633 SQLITE_INTEGER, /* 0x16 (not possible) */
81634 SQLITE_NULL, /* 0x17 (not possible) */
81635 SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */
81636 SQLITE_NULL, /* 0x19 (not possible) */
81637 SQLITE_FLOAT, /* 0x1a (not possible) */
81638 SQLITE_NULL, /* 0x1b (not possible) */
81639 SQLITE_INTEGER, /* 0x1c (not possible) */
81640 SQLITE_NULL, /* 0x1d (not possible) */
81641 SQLITE_INTEGER, /* 0x1e (not possible) */
81642 SQLITE_NULL, /* 0x1f (not possible) */
81643 SQLITE_FLOAT, /* 0x20 INTREAL */
81644 SQLITE_NULL, /* 0x21 (not possible) */
81645 SQLITE_TEXT, /* 0x22 INTREAL + TEXT */
81646 SQLITE_NULL, /* 0x23 (not possible) */
81647 SQLITE_FLOAT, /* 0x24 (not possible) */
81648 SQLITE_NULL, /* 0x25 (not possible) */
81649 SQLITE_FLOAT, /* 0x26 (not possible) */
81650 SQLITE_NULL, /* 0x27 (not possible) */
81651 SQLITE_FLOAT, /* 0x28 (not possible) */
81652 SQLITE_NULL, /* 0x29 (not possible) */
81653 SQLITE_FLOAT, /* 0x2a (not possible) */
81654 SQLITE_NULL, /* 0x2b (not possible) */
81655 SQLITE_FLOAT, /* 0x2c (not possible) */
81656 SQLITE_NULL, /* 0x2d (not possible) */
81657 SQLITE_FLOAT, /* 0x2e (not possible) */
81658 SQLITE_NULL, /* 0x2f (not possible) */
81659 SQLITE_BLOB, /* 0x30 (not possible) */
81660 SQLITE_NULL, /* 0x31 (not possible) */
81661 SQLITE_TEXT, /* 0x32 (not possible) */
81662 SQLITE_NULL, /* 0x33 (not possible) */
81663 SQLITE_FLOAT, /* 0x34 (not possible) */
81664 SQLITE_NULL, /* 0x35 (not possible) */
81665 SQLITE_FLOAT, /* 0x36 (not possible) */
81666 SQLITE_NULL, /* 0x37 (not possible) */
81667 SQLITE_FLOAT, /* 0x38 (not possible) */
81668 SQLITE_NULL, /* 0x39 (not possible) */
81669 SQLITE_FLOAT, /* 0x3a (not possible) */
81670 SQLITE_NULL, /* 0x3b (not possible) */
81671 SQLITE_FLOAT, /* 0x3c (not possible) */
81672 SQLITE_NULL, /* 0x3d (not possible) */
81673 SQLITE_FLOAT, /* 0x3e (not possible) */
81674 SQLITE_NULL, /* 0x3f (not possible) */
81675 };
81676 #ifdef SQLITE_DEBUG
81677 {
81678 int eType = SQLITE_BLOB;
81679 if( pVal->flags & MEM_Null ){
81680 eType = SQLITE_NULL;
81681 }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
81682 eType = SQLITE_FLOAT;
81683 }else if( pVal->flags & MEM_Int ){
81684 eType = SQLITE_INTEGER;
81685 }else if( pVal->flags & MEM_Str ){
81686 eType = SQLITE_TEXT;
81687 }
81688 assert( eType == aType[pVal->flags&MEM_AffMask] );
81689 }
81690 #endif
81691 return aType[pVal->flags&MEM_AffMask];
81692 }
81693
81694 /* Return true if a parameter to xUpdate represents an unchanged column */
81695 SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
@@ -81808,10 +81934,25 @@
81934 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
81935 sqlite3VdbeMemSetNull(pCtx->pOut);
81936 pCtx->isError = SQLITE_NOMEM_BKPT;
81937 sqlite3OomFault(pCtx->pOut->db);
81938 }
81939
81940 #ifndef SQLITE_UNTESTABLE
81941 /* Force the INT64 value currently stored as the result to be
81942 ** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL
81943 ** test-control.
81944 */
81945 SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){
81946 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
81947 if( pCtx->pOut->flags & MEM_Int ){
81948 pCtx->pOut->flags &= ~MEM_Int;
81949 pCtx->pOut->flags |= MEM_IntReal;
81950 }
81951 }
81952 #endif
81953
81954
81955 /*
81956 ** This function is called after a transaction has been committed. It
81957 ** invokes callbacks registered with sqlite3_wal_hook() as required.
81958 */
@@ -83095,11 +83236,13 @@
83236 if( iIdx==p->pTab->iPKey ){
83237 sqlite3VdbeMemSetInt64(pMem, p->iKey1);
83238 }else if( iIdx>=p->pUnpacked->nField ){
83239 *ppValue = (sqlite3_value *)columnNullValue();
83240 }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
83241 if( pMem->flags & (MEM_Int|MEM_IntReal) ){
83242 testcase( pMem->flags & MEM_Int );
83243 testcase( pMem->flags & MEM_IntReal );
83244 sqlite3VdbeMemRealify(pMem);
83245 }
83246 }
83247
83248 preupdate_old_out:
@@ -83414,11 +83557,11 @@
83557 nextIndex = idx + 1;
83558 assert( idx>0 && idx<=p->nVar );
83559 pVar = &p->aVar[idx-1];
83560 if( pVar->flags & MEM_Null ){
83561 sqlite3_str_append(&out, "NULL", 4);
83562 }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
83563 sqlite3_str_appendf(&out, "%lld", pVar->u.i);
83564 }else if( pVar->flags & MEM_Real ){
83565 sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
83566 }else if( pVar->flags & MEM_Str ){
83567 int nOut; /* Number of bytes of the string text to include in output */
@@ -83676,18 +83819,10 @@
83819 sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
83820 iSrcLine&0xffffff, I, M);
83821 }
83822 #endif
83823
 
 
 
 
 
 
 
 
83824 /*
83825 ** An ephemeral string value (signified by the MEM_Ephem flag) contains
83826 ** a pointer to a dynamically allocated string where some other entity
83827 ** is responsible for deallocating that string. Because the register
83828 ** does not control the string, it might be deleted without the register
@@ -83745,11 +83880,11 @@
83880 if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
83881 /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
83882 ** is clear. Otherwise, if this is an ephemeral cursor created by
83883 ** OP_OpenDup, the cursor will not be closed and will still be part
83884 ** of a BtShared.pCursor list. */
83885 if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
83886 sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
83887 p->apCsr[iCur] = 0;
83888 }
83889 if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
83890 p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
@@ -83784,11 +83919,11 @@
83919 */
83920 static void applyNumericAffinity(Mem *pRec, int bTryForInt){
83921 double rValue;
83922 i64 iValue;
83923 u8 enc = pRec->enc;
83924 assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
83925 if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
83926 if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
83927 pRec->u.i = iValue;
83928 pRec->flags |= MEM_Int;
83929 }else{
@@ -83841,15 +83976,18 @@
83976 ** representation (blob and NULL do not get converted) but no string
83977 ** representation. It would be harmless to repeat the conversion if
83978 ** there is already a string rep, but it is pointless to waste those
83979 ** CPU cycles. */
83980 if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
83981 if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
83982 testcase( pRec->flags & MEM_Int );
83983 testcase( pRec->flags & MEM_Real );
83984 testcase( pRec->flags & MEM_IntReal );
83985 sqlite3VdbeMemStringify(pRec, enc, 1);
83986 }
83987 }
83988 pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
83989 }
83990 }
83991
83992 /*
83993 ** Try to convert the type of a function argument or a result column
@@ -83884,11 +84022,11 @@
84022 ** interpret as a string if we want to). Compute its corresponding
84023 ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields
84024 ** accordingly.
84025 */
84026 static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
84027 assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
84028 assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
84029 ExpandBlob(pMem);
84030 if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
84031 return 0;
84032 }
@@ -83904,14 +84042,19 @@
84042 **
84043 ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
84044 ** But it does set pMem->u.r and pMem->u.i appropriately.
84045 */
84046 static u16 numericType(Mem *pMem){
84047 if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
84048 testcase( pMem->flags & MEM_Int );
84049 testcase( pMem->flags & MEM_Real );
84050 testcase( pMem->flags & MEM_IntReal );
84051 return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
84052 }
84053 if( pMem->flags & (MEM_Str|MEM_Blob) ){
84054 testcase( pMem->flags & MEM_Str );
84055 testcase( pMem->flags & MEM_Blob );
84056 return computeNumericType(pMem);
84057 }
84058 return 0;
84059 }
84060
@@ -84003,10 +84146,12 @@
84146 printf(" undefined");
84147 }else if( p->flags & MEM_Null ){
84148 printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
84149 }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
84150 printf(" si:%lld", p->u.i);
84151 }else if( (p->flags & (MEM_IntReal))!=0 ){
84152 printf(" ir:%lld", p->u.i);
84153 }else if( p->flags & MEM_Int ){
84154 printf(" i:%lld", p->u.i);
84155 #ifndef SQLITE_OMIT_FLOATING_POINT
84156 }else if( p->flags & MEM_Real ){
84157 printf(" r:%g", p->u.r);
@@ -85033,23 +85178,42 @@
85178 ** It is illegal for P1 and P3 to be the same register. Sometimes,
85179 ** if P3 is the same register as P2, the implementation is able
85180 ** to avoid a memcpy().
85181 */
85182 case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
85183 i64 nByte; /* Total size of the output string or blob */
85184 u16 flags1; /* Initial flags for P1 */
85185 u16 flags2; /* Initial flags for P2 */
85186
85187 pIn1 = &aMem[pOp->p1];
85188 pIn2 = &aMem[pOp->p2];
85189 pOut = &aMem[pOp->p3];
85190 testcase( pIn1==pIn2 );
85191 testcase( pOut==pIn2 );
85192 assert( pIn1!=pOut );
85193 flags1 = pIn1->flags;
85194 testcase( flags1 & MEM_Null );
85195 testcase( pIn2->flags & MEM_Null );
85196 if( (flags1 | pIn2->flags) & MEM_Null ){
85197 sqlite3VdbeMemSetNull(pOut);
85198 break;
85199 }
85200 if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
85201 if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
85202 flags1 = pIn1->flags & ~MEM_Str;
85203 }else if( (flags1 & MEM_Zero)!=0 ){
85204 if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
85205 flags1 = pIn1->flags & ~MEM_Str;
85206 }
85207 flags2 = pIn2->flags;
85208 if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
85209 if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
85210 flags2 = pIn2->flags & ~MEM_Str;
85211 }else if( (flags2 & MEM_Zero)!=0 ){
85212 if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
85213 flags2 = pIn2->flags & ~MEM_Str;
85214 }
85215 nByte = pIn1->n + pIn2->n;
85216 if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
85217 goto too_big;
85218 }
85219 if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
@@ -85056,12 +85220,16 @@
85220 goto no_mem;
85221 }
85222 MemSetTypeFlag(pOut, MEM_Str);
85223 if( pOut!=pIn2 ){
85224 memcpy(pOut->z, pIn2->z, pIn2->n);
85225 assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
85226 pIn2->flags = flags2;
85227 }
85228 memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
85229 assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
85230 pIn1->flags = flags1;
85231 pOut->z[nByte]=0;
85232 pOut->z[nByte+1] = 0;
85233 pOut->flags |= MEM_Term;
85234 pOut->n = (int)nByte;
85235 pOut->enc = encoding;
@@ -85183,11 +85351,11 @@
85351 if( sqlite3IsNaN(rB) ){
85352 goto arithmetic_result_is_null;
85353 }
85354 pOut->u.r = rB;
85355 MemSetTypeFlag(pOut, MEM_Real);
85356 if( ((type1|type2)&(MEM_Real|MEM_IntReal))==0 && !bIntint ){
85357 sqlite3VdbeIntegerAffinity(pOut);
85358 }
85359 #endif
85360 }
85361 break;
@@ -85354,11 +85522,13 @@
85522 ** integers, for space efficiency, but after extraction we want them
85523 ** to have only a real value.
85524 */
85525 case OP_RealAffinity: { /* in1 */
85526 pIn1 = &aMem[pOp->p1];
85527 if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
85528 testcase( pIn1->flags & MEM_Int );
85529 testcase( pIn1->flags & MEM_IntReal );
85530 sqlite3VdbeMemRealify(pIn1);
85531 }
85532 break;
85533 }
85534 #endif
@@ -85546,21 +85716,21 @@
85716 }else{
85717 /* Neither operand is NULL. Do a comparison. */
85718 affinity = pOp->p5 & SQLITE_AFF_MASK;
85719 if( affinity>=SQLITE_AFF_NUMERIC ){
85720 if( (flags1 | flags3)&MEM_Str ){
85721 if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
85722 applyNumericAffinity(pIn1,0);
85723 assert( flags3==pIn3->flags );
85724 /* testcase( flags3!=pIn3->flags );
85725 ** this used to be possible with pIn1==pIn3, but not since
85726 ** the column cache was removed. The following assignment
85727 ** is essentially a no-op. But, it provides defense-in-depth
85728 ** in case our analysis is incorrect, so it is left in. */
85729 flags3 = pIn3->flags;
85730 }
85731 if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
85732 applyNumericAffinity(pIn3,0);
85733 }
85734 }
85735 /* Handle the common case of integer comparison here, as an
85736 ** optimization, to avoid a call to sqlite3MemCompare() */
@@ -85569,21 +85739,23 @@
85739 if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
85740 res = 0;
85741 goto compare_op;
85742 }
85743 }else if( affinity==SQLITE_AFF_TEXT ){
85744 if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
85745 testcase( pIn1->flags & MEM_Int );
85746 testcase( pIn1->flags & MEM_Real );
85747 testcase( pIn1->flags & MEM_IntReal );
85748 sqlite3VdbeMemStringify(pIn1, encoding, 1);
85749 testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
85750 flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
85751 assert( pIn1!=pIn3 );
85752 }
85753 if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
85754 testcase( pIn3->flags & MEM_Int );
85755 testcase( pIn3->flags & MEM_Real );
85756 testcase( pIn3->flags & MEM_IntReal );
85757 sqlite3VdbeMemStringify(pIn3, encoding, 1);
85758 testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
85759 flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
85760 }
85761 }
@@ -86335,16 +86507,25 @@
86507 zAffinity = pOp->p4.z;
86508 assert( zAffinity!=0 );
86509 assert( pOp->p2>0 );
86510 assert( zAffinity[pOp->p2]==0 );
86511 pIn1 = &aMem[pOp->p1];
86512 while( 1 /*edit-by-break*/ ){
86513 assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
86514 assert( memIsValid(pIn1) );
86515 applyAffinity(pIn1, zAffinity[0], encoding);
86516 if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
86517 /* When applying REAL affinity, if the result is still MEM_Int,
86518 ** indicate that REAL is actually desired */
86519 pIn1->flags |= MEM_IntReal;
86520 pIn1->flags &= ~MEM_Int;
86521 }
86522 REGISTER_TRACE((int)(pIn1-aMem), pIn1);
86523 zAffinity++;
86524 if( zAffinity[0]==0 ) break;
86525 pIn1++;
86526 }
86527 break;
86528 }
86529
86530 /* Opcode: MakeRecord P1 P2 P3 P4 *
86531 ** Synopsis: r[P3]=mkrec(r[P1@P2])
@@ -86361,11 +86542,10 @@
86542 ** macros defined in sqliteInt.h.
86543 **
86544 ** If P4 is NULL then all index fields have the affinity BLOB.
86545 */
86546 case OP_MakeRecord: {
 
86547 Mem *pRec; /* The new record */
86548 u64 nData; /* Number of bytes of data space */
86549 int nHdr; /* Number of bytes of header space */
86550 i64 nByte; /* Data space required for this record */
86551 i64 nZero; /* Number of zero bytes at the end of the record */
@@ -86374,13 +86554,13 @@
86554 Mem *pData0; /* First field to be combined into the record */
86555 Mem *pLast; /* Last field of the record */
86556 int nField; /* Number of fields in the record */
86557 char *zAffinity; /* The affinity string for the record */
86558 int file_format; /* File format to use for encoding */
 
 
86559 u32 len; /* Length of a field */
86560 u8 *zHdr; /* Where to write next byte of the header */
86561 u8 *zPayload; /* Where to write next byte of the payload */
86562
86563 /* Assuming the record contains N fields, the record format looks
86564 ** like this:
86565 **
86566 ** ------------------------------------------------------------------------
@@ -86415,11 +86595,14 @@
86595 */
86596 assert( pData0<=pLast );
86597 if( zAffinity ){
86598 pRec = pData0;
86599 do{
86600 applyAffinity(pRec, zAffinity[0], encoding);
86601 REGISTER_TRACE((int)(pRec-aMem), pRec);
86602 zAffinity++;
86603 pRec++;
86604 assert( zAffinity[0]==0 || pRec<=pLast );
86605 }while( zAffinity[0] );
86606 }
86607
86608 #ifdef SQLITE_ENABLE_NULL_TRIM
@@ -86503,38 +86686,38 @@
86686 }
86687 if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
86688 goto no_mem;
86689 }
86690 }
86691 pOut->n = (int)nByte;
86692 pOut->flags = MEM_Blob;
86693 if( nZero ){
86694 pOut->u.nZero = nZero;
86695 pOut->flags |= MEM_Zero;
86696 }
86697 UPDATE_MAX_BLOBSIZE(pOut);
86698 zHdr = (u8 *)pOut->z;
86699 zPayload = zHdr + nHdr;
86700
86701 /* Write the record */
86702 zHdr += putVarint32(zHdr, nHdr);
 
86703 assert( pData0<=pLast );
86704 pRec = pData0;
86705 do{
86706 serial_type = pRec->uTemp;
86707 /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
86708 ** additional varints, one per column. */
86709 zHdr += putVarint32(zHdr, serial_type); /* serial type */
86710 /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
86711 ** immediately follow the header. */
86712 zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
86713 }while( (++pRec)<=pLast );
86714 assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
86715 assert( nByte==(int)(zPayload - (u8*)pOut->z) );
86716
86717 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
 
 
 
 
 
 
86718 REGISTER_TRACE(pOp->p3, pOut);
 
86719 break;
86720 }
86721
86722 /* Opcode: Count P1 P2 * * *
86723 ** Synopsis: r[P2]=count()
@@ -86560,12 +86743,13 @@
86743 #endif
86744
86745 /* Opcode: Savepoint P1 * * P4 *
86746 **
86747 ** Open, release or rollback the savepoint named by parameter P4, depending
86748 ** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
86749 ** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
86750 ** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
86751 */
86752 case OP_Savepoint: {
86753 int p1; /* Value of P1 operand */
86754 char *zName; /* Name of savepoint */
86755 int nName;
@@ -86629,10 +86813,11 @@
86813 pNew->nDeferredCons = db->nDeferredCons;
86814 pNew->nDeferredImmCons = db->nDeferredImmCons;
86815 }
86816 }
86817 }else{
86818 assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
86819 iSavepoint = 0;
86820
86821 /* Find the named savepoint. If there is no such savepoint, then an
86822 ** an error is returned to the user. */
86823 for(
@@ -86682,10 +86867,11 @@
86867 SQLITE_ABORT_ROLLBACK,
86868 isSchemaChange==0);
86869 if( rc!=SQLITE_OK ) goto abort_due_to_error;
86870 }
86871 }else{
86872 assert( p1==SAVEPOINT_RELEASE );
86873 isSchemaChange = 0;
86874 }
86875 for(ii=0; ii<db->nDb; ii++){
86876 rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
86877 if( rc!=SQLITE_OK ){
@@ -86718,10 +86904,11 @@
86904 sqlite3DbFree(db, pSavepoint);
86905 if( !isTransaction ){
86906 db->nSavepoint--;
86907 }
86908 }else{
86909 assert( p1==SAVEPOINT_ROLLBACK );
86910 db->nDeferredCons = pSavepoint->nDeferredCons;
86911 db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
86912 }
86913
86914 if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
@@ -87256,11 +87443,14 @@
87443 assert( pOp->p2>=0 );
87444 pCx = p->apCsr[pOp->p1];
87445 if( pCx ){
87446 /* If the ephermeral table is already open, erase all existing content
87447 ** so that the table is empty again, rather than creating a new table. */
87448 assert( pCx->isEphemeral );
87449 if( pCx->pBtx ){
87450 rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
87451 }
87452 }else{
87453 pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
87454 if( pCx==0 ) goto no_mem;
87455 pCx->nullRow = 1;
87456 pCx->isEphemeral = 1;
@@ -87533,24 +87723,28 @@
87723
87724 /* The input value in P3 might be of any type: integer, real, string,
87725 ** blob, or NULL. But it needs to be an integer before we can do
87726 ** the seek, so convert it. */
87727 pIn3 = &aMem[pOp->p3];
87728 if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
87729 applyNumericAffinity(pIn3, 0);
87730 }
87731 iKey = sqlite3VdbeIntValue(pIn3);
87732
87733 /* If the P3 value could not be converted into an integer without
87734 ** loss of information, then special processing is required... */
87735 if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
87736 if( (pIn3->flags & MEM_Real)==0 ){
87737 if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
87738 VdbeBranchTaken(1,2); goto jump_to_p2;
87739 break;
87740 }else{
87741 rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
87742 if( rc!=SQLITE_OK ) goto abort_due_to_error;
87743 goto seek_not_found;
87744 }
87745 }else
87746
87747 /* If the approximation iKey is larger than the actual real search
87748 ** term, substitute >= for > and < for <=. e.g. if the search term
87749 ** is 4.9 and the integer approximation 5:
87750 **
@@ -87570,11 +87764,11 @@
87764 assert( OP_SeekLE==(OP_SeekLT+1) );
87765 assert( OP_SeekGT==(OP_SeekGE+1) );
87766 assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
87767 if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
87768 }
87769 }
87770 rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
87771 pC->movetoTarget = iKey; /* Used by OP_Delete */
87772 if( rc!=SQLITE_OK ){
87773 goto abort_due_to_error;
87774 }
@@ -87925,11 +88119,13 @@
88119 BtCursor *pCrsr;
88120 int res;
88121 u64 iKey;
88122
88123 pIn3 = &aMem[pOp->p3];
88124 testcase( pIn3->flags & MEM_Int );
88125 testcase( pIn3->flags & MEM_IntReal );
88126 if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
88127 /* Make sure pIn3->u.i contains a valid integer representation of
88128 ** the key value, but do not change the datatype of the register, as
88129 ** other parts of the perpared statement might be depending on the
88130 ** current datatype. */
88131 u16 origFlags = pIn3->flags;
@@ -95977,11 +96173,13 @@
96173 sqlite3WalkExprList(pWalker, pList);
96174 if( is_agg ){
96175 #ifndef SQLITE_OMIT_WINDOWFUNC
96176 if( pExpr->y.pWin ){
96177 Select *pSel = pNC->pWinSelect;
96178 if( IN_RENAME_OBJECT==0 ){
96179 sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
96180 }
96181 sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
96182 sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
96183 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
96184 if( 0==pSel->pWin
96185 || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
@@ -97660,11 +97858,11 @@
97858 memset(pNew, 0, sizeof(Expr));
97859 pNew->op = (u8)op;
97860 pNew->iAgg = -1;
97861 if( pToken ){
97862 if( nExtra==0 ){
97863 pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
97864 pNew->u.iValue = iValue;
97865 }else{
97866 pNew->u.zToken = (char*)&pNew[1];
97867 assert( pToken->z!=0 || pToken->n==0 );
97868 if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
@@ -97737,24 +97935,20 @@
97935 int op, /* Expression opcode */
97936 Expr *pLeft, /* Left operand */
97937 Expr *pRight /* Right operand */
97938 ){
97939 Expr *p;
97940 p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
97941 if( p ){
97942 memset(p, 0, sizeof(Expr));
97943 p->op = op & 0xff;
97944 p->iAgg = -1;
 
 
 
 
 
97945 sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
 
 
97946 sqlite3ExprCheckHeight(pParse, p->nHeight);
97947 }else{
97948 sqlite3ExprDelete(pParse->db, pLeft);
97949 sqlite3ExprDelete(pParse->db, pRight);
97950 }
97951 return p;
97952 }
97953
97954 /*
@@ -97771,58 +97965,32 @@
97965 sqlite3SelectDelete(pParse->db, pSelect);
97966 }
97967 }
97968
97969
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97970 /*
97971 ** Join two expressions using an AND operator. If either expression is
97972 ** NULL, then just return the other expression.
97973 **
97974 ** If one side or the other of the AND is known to be false, then instead
97975 ** of returning an AND expression, just return a constant expression with
97976 ** a value of false.
97977 */
97978 SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
97979 sqlite3 *db = pParse->db;
97980 if( pLeft==0 ){
97981 return pRight;
97982 }else if( pRight==0 ){
97983 return pLeft;
97984 }else if( pParse->nErr || IN_RENAME_OBJECT ){
97985 return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
97986 }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
97987 sqlite3ExprDelete(db, pLeft);
97988 sqlite3ExprDelete(db, pRight);
97989 return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
97990 }else{
97991 return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
 
 
97992 }
97993 }
97994
97995 /*
97996 ** Construct a new expression node for a function with multiple
@@ -98708,10 +98876,11 @@
98876 if( !ExprHasProperty(pExpr, EP_Quoted)
98877 && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
98878 || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
98879 ){
98880 pExpr->op = TK_TRUEFALSE;
98881 ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
98882 return 1;
98883 }
98884 return 0;
98885 }
98886
@@ -98723,10 +98892,37 @@
98892 assert( pExpr->op==TK_TRUEFALSE );
98893 assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
98894 || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
98895 return pExpr->u.zToken[4]==0;
98896 }
98897
98898 /*
98899 ** If pExpr is an AND or OR expression, try to simplify it by eliminating
98900 ** terms that are always true or false. Return the simplified expression.
98901 ** Or return the original expression if no simplification is possible.
98902 **
98903 ** Examples:
98904 **
98905 ** (x<10) AND true => (x<10)
98906 ** (x<10) AND false => false
98907 ** (x<10) AND (y=22 OR false) => (x<10) AND (y=22)
98908 ** (x<10) AND (y=22 OR true) => (x<10)
98909 ** (y=22) OR true => true
98910 */
98911 SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
98912 assert( pExpr!=0 );
98913 if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
98914 Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
98915 Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
98916 if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
98917 pExpr = pExpr->op==TK_AND ? pRight : pLeft;
98918 }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
98919 pExpr = pExpr->op==TK_AND ? pLeft : pRight;
98920 }
98921 }
98922 return pExpr;
98923 }
98924
98925
98926 /*
98927 ** These routines are Walker callbacks used to check expressions to
98928 ** see if they are "constant" for some definition of constant. The
@@ -98968,11 +99164,11 @@
99164 ** in *pValue. If the expression is not an integer or if it is too big
99165 ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
99166 */
99167 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
99168 int rc = 0;
99169 if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */
99170
99171 /* If an expression is an integer literal that fits in a signed 32-bit
99172 ** integer, then the EP_IntValue flag will have already been set */
99173 assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
99174 || sqlite3GetInt32(p->u.zToken, &rc)==0 );
@@ -101315,22 +101511,27 @@
101511 assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
101512 if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
101513 if( NEVER(pExpr==0) ) return; /* No way this can happen */
101514 op = pExpr->op;
101515 switch( op ){
101516 case TK_AND:
 
 
 
 
 
 
 
101517 case TK_OR: {
101518 Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
101519 if( pAlt!=pExpr ){
101520 sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
101521 }else if( op==TK_AND ){
101522 int d2 = sqlite3VdbeMakeLabel(pParse);
101523 testcase( jumpIfNull==0 );
101524 sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
101525 jumpIfNull^SQLITE_JUMPIFNULL);
101526 sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
101527 sqlite3VdbeResolveLabel(v, d2);
101528 }else{
101529 testcase( jumpIfNull==0 );
101530 sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
101531 sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
101532 }
101533 break;
101534 }
101535 case TK_NOT: {
101536 testcase( jumpIfNull==0 );
101537 sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -101412,13 +101613,13 @@
101613 break;
101614 }
101615 #endif
101616 default: {
101617 default_expr:
101618 if( ExprAlwaysTrue(pExpr) ){
101619 sqlite3VdbeGoto(v, dest);
101620 }else if( ExprAlwaysFalse(pExpr) ){
101621 /* No-op */
101622 }else{
101623 r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
101624 sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
101625 VdbeCoverage(v);
@@ -101482,22 +101683,27 @@
101683 assert( pExpr->op!=TK_LE || op==OP_Gt );
101684 assert( pExpr->op!=TK_GT || op==OP_Le );
101685 assert( pExpr->op!=TK_GE || op==OP_Lt );
101686
101687 switch( pExpr->op ){
101688 case TK_AND:
 
 
 
 
 
101689 case TK_OR: {
101690 Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
101691 if( pAlt!=pExpr ){
101692 sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
101693 }else if( pExpr->op==TK_AND ){
101694 testcase( jumpIfNull==0 );
101695 sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
101696 sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101697 }else{
101698 int d2 = sqlite3VdbeMakeLabel(pParse);
101699 testcase( jumpIfNull==0 );
101700 sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
101701 jumpIfNull^SQLITE_JUMPIFNULL);
101702 sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
101703 sqlite3VdbeResolveLabel(v, d2);
101704 }
101705 break;
101706 }
101707 case TK_NOT: {
101708 testcase( jumpIfNull==0 );
101709 sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
@@ -101582,13 +101788,13 @@
101788 break;
101789 }
101790 #endif
101791 default: {
101792 default_expr:
101793 if( ExprAlwaysFalse(pExpr) ){
101794 sqlite3VdbeGoto(v, dest);
101795 }else if( ExprAlwaysTrue(pExpr) ){
101796 /* no-op */
101797 }else{
101798 r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
101799 sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
101800 VdbeCoverage(v);
@@ -101822,11 +102028,15 @@
102028 && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
102029 || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
102030 ){
102031 return 1;
102032 }
102033 if( pE2->op==TK_NOTNULL
102034 && pE1->op!=TK_ISNULL
102035 && pE1->op!=TK_IS
102036 && pE1->op!=TK_OR
102037 ){
102038 Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
102039 testcase( pX!=pE1->pLeft );
102040 if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
102041 }
102042 return 0;
@@ -102399,11 +102609,11 @@
102609 */
102610 static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
102611 sqlite3NestedParse(pParse,
102612 "SELECT 1 "
102613 "FROM \"%w\".%s "
102614 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
102615 " AND sql NOT LIKE 'create virtual%%'"
102616 " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
102617 zDb, MASTER_NAME,
102618 zDb, bTemp
102619 );
@@ -102410,11 +102620,11 @@
102620
102621 if( bTemp==0 ){
102622 sqlite3NestedParse(pParse,
102623 "SELECT 1 "
102624 "FROM temp.%s "
102625 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
102626 " AND sql NOT LIKE 'create virtual%%'"
102627 " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
102628 MASTER_NAME, zDb
102629 );
102630 }
@@ -102531,11 +102741,11 @@
102741 ** the schema to use the new table name. */
102742 sqlite3NestedParse(pParse,
102743 "UPDATE \"%w\".%s SET "
102744 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
102745 "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
102746 "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
102747 , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
102748 );
102749
102750 /* Update the tbl_name and name columns of the sqlite_master table
102751 ** as required. */
@@ -102542,11 +102752,12 @@
102752 sqlite3NestedParse(pParse,
102753 "UPDATE %Q.%s SET "
102754 "tbl_name = %Q, "
102755 "name = CASE "
102756 "WHEN type='table' THEN %Q "
102757 "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
102758 " AND type='index' THEN "
102759 "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
102760 "ELSE name END "
102761 "WHERE tbl_name=%Q COLLATE nocase AND "
102762 "(type='table' OR type='index' OR type='trigger');",
102763 zDb, MASTER_NAME,
@@ -102916,11 +103127,12 @@
103127 assert( pNew->n>0 );
103128 bQuote = sqlite3Isquote(pNew->z[0]);
103129 sqlite3NestedParse(pParse,
103130 "UPDATE \"%w\".%s SET "
103131 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
103132 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
103133 " AND (type != 'index' OR tbl_name = %Q)"
103134 " AND sql NOT LIKE 'create virtual%%'",
103135 zDb, MASTER_NAME,
103136 zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
103137 pTab->zName
103138 );
@@ -108168,11 +108380,11 @@
108380 **
108381 ** This is goofy. But to preserve backwards compatibility we continue to
108382 ** accept it. This routine does the necessary conversion. It converts
108383 ** the expression given in its argument from a TK_STRING into a TK_ID
108384 ** if the expression is just a TK_STRING with an optional COLLATE clause.
108385 ** If the expression is anything other than TK_STRING, the expression is
108386 ** unchanged.
108387 */
108388 static void sqlite3StringToId(Expr *p){
108389 if( p->op==TK_STRING ){
108390 p->op = TK_ID;
@@ -108565,14 +108777,55 @@
108777 wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
108778 }
108779 pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
108780 }
108781
108782 /* Return true if column number x is any of the first nCol entries of aiCol[].
108783 ** This is used to determine if the column number x appears in any of the
108784 ** first nCol entries of an index.
108785 */
108786 static int hasColumn(const i16 *aiCol, int nCol, int x){
108787 while( nCol-- > 0 ){
108788 assert( aiCol[0]>=0 );
108789 if( x==*(aiCol++) ){
108790 return 1;
108791 }
108792 }
108793 return 0;
108794 }
108795
108796 /*
108797 ** Return true if any of the first nKey entries of index pIdx exactly
108798 ** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID
108799 ** PRIMARY KEY index. pIdx is an index on the same table. pIdx may
108800 ** or may not be the same index as pPk.
108801 **
108802 ** The first nKey entries of pIdx are guaranteed to be ordinary columns,
108803 ** not a rowid or expression.
108804 **
108805 ** This routine differs from hasColumn() in that both the column and the
108806 ** collating sequence must match for this routine, but for hasColumn() only
108807 ** the column name must match.
108808 */
108809 static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
108810 int i, j;
108811 assert( nKey<=pIdx->nColumn );
108812 assert( iCol<MAX(pPk->nColumn,pPk->nKeyCol) );
108813 assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
108814 assert( pPk->pTable->tabFlags & TF_WithoutRowid );
108815 assert( pPk->pTable==pIdx->pTable );
108816 testcase( pPk==pIdx );
108817 j = pPk->aiColumn[iCol];
108818 assert( j!=XN_ROWID && j!=XN_EXPR );
108819 for(i=0; i<nKey; i++){
108820 assert( pIdx->aiColumn[i]>=0 || j>=0 );
108821 if( pIdx->aiColumn[i]==j
108822 && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
108823 ){
108824 return 1;
108825 }
108826 }
108827 return 0;
108828 }
108829
108830 /* Recompute the colNotIdxed field of the Index.
108831 **
@@ -108657,17 +108910,20 @@
108910 Token ipkToken;
108911 sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
108912 pList = sqlite3ExprListAppend(pParse, 0,
108913 sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
108914 if( pList==0 ) return;
108915 if( IN_RENAME_OBJECT ){
108916 sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
108917 }
108918 pList->a[0].sortOrder = pParse->iPkSortOrder;
108919 assert( pParse->pNewTable==pTab );
108920 pTab->iPKey = -1;
108921 sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
108922 SQLITE_IDXTYPE_PRIMARYKEY);
108923 if( db->mallocFailed || pParse->nErr ) return;
108924 pPk = sqlite3PrimaryKeyIndex(pTab);
 
108925 }else{
108926 pPk = sqlite3PrimaryKeyIndex(pTab);
108927 assert( pPk!=0 );
108928
108929 /*
@@ -108674,13 +108930,14 @@
108930 ** Remove all redundant columns from the PRIMARY KEY. For example, change
108931 ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
108932 ** code assumes the PRIMARY KEY contains no repeated columns.
108933 */
108934 for(i=j=1; i<pPk->nKeyCol; i++){
108935 if( isDupColumn(pPk, j, pPk, i) ){
108936 pPk->nColumn--;
108937 }else{
108938 testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
108939 pPk->aiColumn[j++] = pPk->aiColumn[i];
108940 }
108941 }
108942 pPk->nKeyCol = j;
108943 }
@@ -108706,20 +108963,24 @@
108963 */
108964 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
108965 int n;
108966 if( IsPrimaryKeyIndex(pIdx) ) continue;
108967 for(i=n=0; i<nPk; i++){
108968 if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
108969 testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
108970 n++;
108971 }
108972 }
108973 if( n==0 ){
108974 /* This index is a superset of the primary key */
108975 pIdx->nColumn = pIdx->nKeyCol;
108976 continue;
108977 }
108978 if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
108979 for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
108980 if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
108981 testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
108982 pIdx->aiColumn[j] = pPk->aiColumn[i];
108983 pIdx->azColl[j] = pPk->azColl[i];
108984 j++;
108985 }
108986 }
@@ -110231,13 +110492,14 @@
110492 */
110493 if( pPk ){
110494 for(j=0; j<pPk->nKeyCol; j++){
110495 int x = pPk->aiColumn[j];
110496 assert( x>=0 );
110497 if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
110498 pIndex->nColumn--;
110499 }else{
110500 testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
110501 pIndex->aiColumn[i] = x;
110502 pIndex->azColl[i] = pPk->azColl[j];
110503 pIndex->aSortOrder[i] = pPk->aSortOrder[j];
110504 i++;
110505 }
@@ -113004,10 +113266,11 @@
113266 ** time functions, are implemented separately.)
113267 */
113268 /* #include "sqliteInt.h" */
113269 /* #include <stdlib.h> */
113270 /* #include <assert.h> */
113271 /* #include <math.h> */
113272 /* #include "vdbeInt.h" */
113273
113274 /*
113275 ** Return the collating function associated with a function.
113276 */
@@ -113384,11 +113647,14 @@
113647 zBuf = sqlite3_mprintf("%.*f",n,r);
113648 if( zBuf==0 ){
113649 sqlite3_result_error_nomem(context);
113650 return;
113651 }
113652 if( !sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8) ){
113653 assert( sqlite3_strglob("*Inf", zBuf)==0 );
113654 r = zBuf[0]=='-' ? -HUGE_VAL : +HUGE_VAL;
113655 }
113656 sqlite3_free(zBuf);
113657 }
113658 sqlite3_result_double(context, r);
113659 }
113660 #endif
@@ -113831,12 +114097,10 @@
114097 #endif
114098 sqlite3_result_int(context, 0);
114099 return;
114100 }
114101 #endif
 
 
114102
114103 /* Limit the length of the LIKE or GLOB pattern to avoid problems
114104 ** of deep recursion and N*N behavior in patternCompare().
114105 */
114106 nPat = sqlite3_value_bytes(argv[0]);
@@ -113844,12 +114108,10 @@
114108 testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
114109 if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
114110 sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
114111 return;
114112 }
 
 
114113 if( argc==3 ){
114114 /* The escape character string must consist of a single UTF-8 character.
114115 ** Otherwise, return an error.
114116 */
114117 const unsigned char *zEsc = sqlite3_value_text(argv[2]);
@@ -113861,10 +114123,12 @@
114123 }
114124 escape = sqlite3Utf8Read(&zEsc);
114125 }else{
114126 escape = pInfo->matchSet;
114127 }
114128 zB = sqlite3_value_text(argv[0]);
114129 zA = sqlite3_value_text(argv[1]);
114130 if( zA && zB ){
114131 #ifdef SQLITE_TEST
114132 sqlite3_like_count++;
114133 #endif
114134 sqlite3_result_int(context,
@@ -114786,43 +115050,28 @@
115050 sqlite3OomFault(db);
115051 }
115052 }
115053
115054 /*
115055 ** Re-register the built-in LIKE functions. The caseSensitive
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115056 ** parameter determines whether or not the LIKE operator is case
115057 ** sensitive.
115058 */
115059 SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
115060 struct compareInfo *pInfo;
115061 int flags;
115062 if( caseSensitive ){
115063 pInfo = (struct compareInfo*)&likeInfoAlt;
115064 flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
115065 }else{
115066 pInfo = (struct compareInfo*)&likeInfoNorm;
115067 flags = SQLITE_FUNC_LIKE;
115068 }
115069 sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
115070 sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
115071 sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
115072 sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
 
 
 
115073 }
115074
115075 /*
115076 ** pExpr points to an expression which implements a function. If
115077 ** it is appropriate to apply the LIKE optimization to that function
@@ -115608,11 +115857,11 @@
115857 iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
115858 assert( iCol>=0 );
115859 zCol = pFKey->pFrom->aCol[iCol].zName;
115860 pRight = sqlite3Expr(db, TK_ID, zCol);
115861 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
115862 pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
115863 }
115864
115865 /* If the child table is the same as the parent table, then add terms
115866 ** to the WHERE clause that prevent this entry from being scanned.
115867 ** The added WHERE clause terms are like this:
@@ -115642,15 +115891,15 @@
115891 i16 iCol = pIdx->aiColumn[i];
115892 assert( iCol>=0 );
115893 pLeft = exprTableRegister(pParse, pTab, regData, iCol);
115894 pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
115895 pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
115896 pAll = sqlite3ExprAnd(pParse, pAll, pEq);
115897 }
115898 pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
115899 }
115900 pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
115901 }
115902
115903 /* Resolve the references in the WHERE clause. */
115904 memset(&sNameContext, 0, sizeof(NameContext));
115905 sNameContext.pSrcList = pSrc;
@@ -116252,11 +116501,11 @@
116501 sqlite3PExpr(pParse, TK_DOT,
116502 sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
116503 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
116504 sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
116505 );
116506 pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
116507
116508 /* For ON UPDATE, construct the next term of the WHEN clause.
116509 ** The final WHEN clause will be like this:
116510 **
116511 ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
@@ -116268,11 +116517,11 @@
116517 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
116518 sqlite3PExpr(pParse, TK_DOT,
116519 sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
116520 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
116521 );
116522 pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
116523 }
116524
116525 if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
116526 Expr *pNew;
116527 if( action==OE_Cascade ){
@@ -117265,19 +117514,20 @@
117514 /* If this is not a view, open the table and and all indices */
117515 if( !isView ){
117516 int nIdx;
117517 nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
117518 &iDataCur, &iIdxCur);
117519 aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
117520 if( aRegIdx==0 ){
117521 goto insert_cleanup;
117522 }
117523 for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
117524 assert( pIdx );
117525 aRegIdx[i] = ++pParse->nMem;
117526 pParse->nMem += pIdx->nColumn;
117527 }
117528 aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
117529 }
117530 #ifndef SQLITE_OMIT_UPSERT
117531 if( pUpsert ){
117532 if( IsVirtual(pTab) ){
117533 sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
@@ -117676,10 +117926,18 @@
117926 ** The code generated by this routine will store new index entries into
117927 ** registers identified by aRegIdx[]. No index entry is created for
117928 ** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
117929 ** the same as the order of indices on the linked list of indices
117930 ** at pTab->pIndex.
117931 **
117932 ** (2019-05-07) The generated code also creates a new record for the
117933 ** main table, if pTab is a rowid table, and stores that record in the
117934 ** register identified by aRegIdx[nIdx] - in other words in the first
117935 ** entry of aRegIdx[] past the last index. It is important that the
117936 ** record be generated during constraint checks to avoid affinity changes
117937 ** to the register content that occur after constraint checks but before
117938 ** the new record is inserted.
117939 **
117940 ** The caller must have already opened writeable cursors on the main
117941 ** table and all applicable indices (that is to say, all indices for which
117942 ** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
117943 ** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
@@ -118295,10 +118553,20 @@
118553 if( ipkTop ){
118554 sqlite3VdbeGoto(v, ipkTop);
118555 VdbeComment((v, "Do IPK REPLACE"));
118556 sqlite3VdbeJumpHere(v, ipkBottom);
118557 }
118558
118559 /* Generate the table record */
118560 if( HasRowid(pTab) ){
118561 int regRec = aRegIdx[ix];
118562 sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec);
118563 sqlite3SetMakeRecordP5(v, pTab);
118564 if( !bAffinityDone ){
118565 sqlite3TableAffinity(v, pTab, 0);
118566 }
118567 }
118568
118569 *pbMayReplace = seenReplace;
118570 VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
118571 }
118572
@@ -118345,14 +118613,11 @@
118613 int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
118614 ){
118615 Vdbe *v; /* Prepared statements under construction */
118616 Index *pIdx; /* An index being inserted or updated */
118617 u8 pik_flags; /* flag values passed to the btree insert */
 
 
118618 int i; /* Loop counter */
 
118619
118620 assert( update_flags==0
118621 || update_flags==OPFLAG_ISUPDATE
118622 || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
118623 );
@@ -118360,11 +118625,10 @@
118625 v = sqlite3GetVdbe(pParse);
118626 assert( v!=0 );
118627 assert( pTab->pSelect==0 ); /* This table is not a VIEW */
118628 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
118629 if( aRegIdx[i]==0 ) continue;
 
118630 if( pIdx->pPartIdxWhere ){
118631 sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
118632 VdbeCoverage(v);
118633 }
118634 pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
@@ -118388,17 +118652,10 @@
118652 aRegIdx[i]+1,
118653 pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
118654 sqlite3VdbeChangeP5(v, pik_flags);
118655 }
118656 if( !HasRowid(pTab) ) return;
 
 
 
 
 
 
 
118657 if( pParse->nested ){
118658 pik_flags = 0;
118659 }else{
118660 pik_flags = OPFLAG_NCHANGE;
118661 pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
@@ -118407,11 +118664,11 @@
118664 pik_flags |= OPFLAG_APPEND;
118665 }
118666 if( useSeekResult ){
118667 pik_flags |= OPFLAG_USESEEKRESULT;
118668 }
118669 sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
118670 if( !pParse->nested ){
118671 sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
118672 }
118673 sqlite3VdbeChangeP5(v, pik_flags);
118674 }
@@ -120725,15 +120982,17 @@
120982 /* ePragTyp: */ PragTyp_CACHE_SPILL,
120983 /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
120984 /* ColNames: */ 0, 0,
120985 /* iArg: */ 0 },
120986 #endif
120987 #if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
120988 {/* zName: */ "case_sensitive_like",
120989 /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
120990 /* ePragFlg: */ PragFlg_NoColumns,
120991 /* ColNames: */ 0, 0,
120992 /* iArg: */ 0 },
120993 #endif
120994 {/* zName: */ "cell_size_check",
120995 /* ePragTyp: */ PragTyp_FLAG,
120996 /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
120997 /* ColNames: */ 0, 0,
120998 /* iArg: */ SQLITE_CellSizeCk },
@@ -122610,19 +122869,21 @@
122869 }
122870 break;
122871 #endif /* !defined(SQLITE_OMIT_TRIGGER) */
122872 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
122873
122874 #ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
122875 /* Reinstall the LIKE and GLOB functions. The variant of LIKE
122876 ** used will be case sensitive or not depending on the RHS.
122877 */
122878 case PragTyp_CASE_SENSITIVE_LIKE: {
122879 if( zRight ){
122880 sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
122881 }
122882 }
122883 break;
122884 #endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
122885
122886 #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
122887 # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
122888 #endif
122889
@@ -124974,11 +125235,11 @@
125235 ExprSetProperty(pEq, EP_FromJoin);
125236 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
125237 ExprSetVVAProperty(pEq, EP_NoReduce);
125238 pEq->iRightJoinTable = (i16)pE2->iTable;
125239 }
125240 *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
125241 }
125242
125243 /*
125244 ** Set the EP_FromJoin property on all terms of the given expression.
125245 ** And set the Expr.iRightJoinTable to iTable for every term in the
@@ -125108,11 +125369,11 @@
125369 /* Add the ON clause to the end of the WHERE clause, connected by
125370 ** an AND operator.
125371 */
125372 if( pRight->pOn ){
125373 if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
125374 p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
125375 pRight->pOn = 0;
125376 }
125377
125378 /* Create extra terms on the WHERE clause for each column named
125379 ** in the USING clause. Example: If the two tables to be joined are
@@ -128653,11 +128914,11 @@
128914 pWhere = pSub->pWhere;
128915 pSub->pWhere = 0;
128916 if( isLeftJoin>0 ){
128917 setJoinExpr(pWhere, iNewParent);
128918 }
128919 pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere);
128920 if( db->mallocFailed==0 ){
128921 SubstContext x;
128922 x.pParse = pParse;
128923 x.iTable = iParent;
128924 x.iNewTable = iNewParent;
@@ -128988,13 +129249,13 @@
129249 x.iNewTable = iCursor;
129250 x.isLeftJoin = 0;
129251 x.pEList = pSubq->pEList;
129252 pNew = substExpr(&x, pNew);
129253 if( pSubq->selFlags & SF_Aggregate ){
129254 pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
129255 }else{
129256 pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
129257 }
129258 pSubq = pSubq->pPrior;
129259 }
129260 }
129261 return nChng;
@@ -129416,11 +129677,11 @@
129677 sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
129678 pTab->iPKey = -1;
129679 pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
129680 pTab->tabFlags |= TF_Ephemeral;
129681
129682 return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
129683 }
129684
129685 /*
129686 ** This routine is a Walker callback for "expanding" a SELECT statement.
129687 ** "Expanding" means to do the following:
@@ -130037,11 +130298,11 @@
130298 sqlite3 *db = pWalker->pParse->db;
130299 Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
130300 if( pNew ){
130301 Expr *pWhere = pS->pWhere;
130302 SWAP(Expr, *pNew, *pExpr);
130303 pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
130304 pS->pWhere = pNew;
130305 pWalker->eCode = 1;
130306 }
130307 }
130308 return WRC_Prune;
@@ -130100,11 +130361,13 @@
130361 if( pThis->pSelect->selId!=pS1->selId ){
130362 /* The query flattener left two different CTE tables with identical
130363 ** names in the same FROM clause. */
130364 continue;
130365 }
130366 if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
130367 || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1)
130368 ){
130369 /* The view was modified by some other optimization such as
130370 ** pushDownWhereTerms() */
130371 continue;
130372 }
130373 return pItem;
@@ -132786,15 +133049,16 @@
133049 WhereInfo *pWInfo; /* Information about the WHERE clause */
133050 Vdbe *v; /* The virtual database engine */
133051 Index *pIdx; /* For looping over indices */
133052 Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
133053 int nIdx; /* Number of indices that need updating */
133054 int nAllIdx; /* Total number of indexes */
133055 int iBaseCur; /* Base cursor number */
133056 int iDataCur; /* Cursor for the canonical data btree */
133057 int iIdxCur; /* Cursor for the first index */
133058 sqlite3 *db; /* The database structure */
133059 int *aRegIdx = 0; /* Registers for to each index and the main table */
133060 int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
133061 ** an expression for the i-th column of the table.
133062 ** aXRef[i]==-1 if the i-th column is not changed. */
133063 u8 *aToOpen; /* 1 for tables and indices to be opened */
133064 u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */
@@ -132904,14 +133168,14 @@
133168 pTabList->a[0].iCursor = iDataCur;
133169
133170 /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
133171 ** Initialize aXRef[] and aToOpen[] to their default values.
133172 */
133173 aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
133174 if( aXRef==0 ) goto update_cleanup;
133175 aRegIdx = aXRef+pTab->nCol;
133176 aToOpen = (u8*)(aRegIdx+nIdx+1);
133177 memset(aToOpen, 1, nIdx+1);
133178 aToOpen[nIdx+1] = 0;
133179 for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
133180
133181 /* Initialize the name-context */
@@ -132986,11 +133250,11 @@
133250 /* There is one entry in the aRegIdx[] array for each index on the table
133251 ** being updated. Fill in aRegIdx[] with a register number that will hold
133252 ** the key for accessing each index.
133253 */
133254 if( onError==OE_Replace ) bReplace = 1;
133255 for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
133256 int reg;
133257 if( chngKey || hasFK>1 || pIdx==pPk
133258 || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
133259 ){
133260 reg = ++pParse->nMem;
@@ -133006,13 +133270,14 @@
133270 }
133271 break;
133272 }
133273 }
133274 }
133275 if( reg==0 ) aToOpen[nAllIdx+1] = 0;
133276 aRegIdx[nAllIdx] = reg;
133277 }
133278 aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */
133279 if( bReplace ){
133280 /* If REPLACE conflict resolution might be invoked, open cursors on all
133281 ** indexes in case they are needed to delete records. */
133282 memset(aToOpen, 1, nIdx+1);
133283 }
@@ -133023,11 +133288,17 @@
133288 if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
133289 sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
133290
133291 /* Allocate required registers. */
133292 if( !IsVirtual(pTab) ){
133293 /* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
133294 ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
133295 ** reallocated. aRegIdx[nAllIdx] is the register in which the main
133296 ** table record is written. regRowSet holds the RowSet for the
133297 ** two-pass update algorithm. */
133298 assert( aRegIdx[nAllIdx]==pParse->nMem );
133299 regRowSet = aRegIdx[nAllIdx];
133300 regOldRowid = regNewRowid = ++pParse->nMem;
133301 if( chngPk || pTrigger || hasFK ){
133302 regOld = pParse->nMem + 1;
133303 pParse->nMem += pTab->nCol;
133304 }
@@ -133153,10 +133424,12 @@
133424 /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
133425 ** mode, write the rowid into the FIFO. In either of the one-pass modes,
133426 ** leave it in register regOldRowid. */
133427 sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
133428 if( eOnePass==ONEPASS_OFF ){
133429 /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
133430 aRegIdx[nAllIdx] = ++pParse->nMem;
133431 sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
133432 }
133433 }else{
133434 /* Read the PK of the current row into an array of registers. In
133435 ** ONEPASS_OFF mode, serialize the array into a record and store it in
@@ -133984,10 +134257,11 @@
134257 */
134258 SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
134259 Vdbe *v = sqlite3GetVdbe(pParse);
134260 int iDb = 0;
134261 if( v==0 ) goto build_vacuum_end;
134262 if( pParse->nErr ) goto build_vacuum_end;
134263 if( pNm ){
134264 #ifndef SQLITE_BUG_COMPATIBLE_20160819
134265 /* Default behavior: Report an error if the argument to VACUUM is
134266 ** not recognized */
134267 iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
@@ -135136,18 +135410,20 @@
135410 }
135411 }
135412 p = vtabDisconnectAll(db, pTab);
135413 xDestroy = p->pMod->pModule->xDestroy;
135414 assert( xDestroy!=0 ); /* Checked before the virtual table is created */
135415 pTab->nTabRef++;
135416 rc = xDestroy(p->pVtab);
135417 /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
135418 if( rc==SQLITE_OK ){
135419 assert( pTab->pVTable==p && p->pNext==0 );
135420 p->pVtab = 0;
135421 pTab->pVTable = 0;
135422 sqlite3VtabUnlock(p);
135423 }
135424 sqlite3DeleteTable(db, pTab);
135425 }
135426
135427 return rc;
135428 }
135429
@@ -135586,10 +135862,12 @@
135862 **
135863 ** This file contains structure and macro definitions for the query
135864 ** planner logic in "where.c". These definitions are broken out into
135865 ** a separate source file for easier editing.
135866 */
135867 #ifndef SQLITE_WHEREINT_H
135868 #define SQLITE_WHEREINT_H
135869
135870 /*
135871 ** Trace output macros
135872 */
135873 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
@@ -136156,10 +136434,12 @@
136434 #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
136435 #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
136436 #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
136437 #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
136438 #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
136439
136440 #endif /* !defined(SQLITE_WHEREINT_H) */
136441
136442 /************** End of whereInt.h ********************************************/
136443 /************** Continuing where we left off in wherecode.c ******************/
136444
136445 #ifndef SQLITE_OMIT_EXPLAIN
@@ -137139,11 +137419,11 @@
137419 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
137420 if( sWalker.eCode ) continue;
137421 }
137422
137423 /* If we survive all prior tests, that means this term is worth hinting */
137424 pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
137425 }
137426 if( pExpr!=0 ){
137427 sWalker.xExprCallback = codeCursorHintFixExpr;
137428 sqlite3WalkExpr(&sWalker, pExpr);
137429 sqlite3VdbeAddOp4(v, OP_CursorHint,
@@ -138104,11 +138384,11 @@
138384 testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
138385 if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
138386 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
138387 testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
138388 pExpr = sqlite3ExprDup(db, pExpr, 0);
138389 pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
138390 }
138391 if( pAndExpr ){
138392 /* The extra 0x10000 bit on the opcode is masked off and does not
138393 ** become part of the new Expr.op. However, it does make the
138394 ** op==TK_AND comparison inside of sqlite3PExpr() false, and this
@@ -138255,11 +138535,11 @@
138535 }
138536 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
138537 sqlite3VdbeGoto(v, pLevel->addrBrk);
138538 sqlite3VdbeResolveLabel(v, iLoopBody);
138539
138540 if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
138541 if( !untestedTerms ) disableTerm(pLevel, pTerm);
138542 }else
138543 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
138544
138545 {
@@ -138688,26 +138968,28 @@
138968 for(iFrom=iTo=0; iFrom<cnt; iFrom++){
138969 if( zNew[iFrom]==wc[3] ) iFrom++;
138970 zNew[iTo++] = zNew[iFrom];
138971 }
138972 zNew[iTo] = 0;
138973 assert( iTo>0 );
138974
138975 /* If the RHS begins with a digit or a +/- sign, then the LHS must be
138976 ** an ordinary column (not a virtual table column) with TEXT affinity.
138977 ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
138978 ** even though "lhs LIKE rhs" is true. But if the RHS does not start
138979 ** with a digit or +/-, then "lhs LIKE rhs" will always be false if
138980 ** the LHS is numeric and so the optimization still works.
138981 **
138982 ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
138983 ** The RHS pattern must not be '/%' because the termination condition
138984 ** will then become "x<'0'" and if the affinity is numeric, will then
138985 ** be converted into "x<0", which is incorrect.
138986 */
138987 if( sqlite3Isdigit(zNew[0])
138988 || zNew[0]=='-'
138989 || zNew[0]=='+'
138990 || zNew[iTo-1]=='0'-1
138991 ){
138992 if( pLeft->op!=TK_COLUMN
138993 || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
138994 || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
138995 ){
@@ -140770,11 +141052,11 @@
141052 || pLoop->prereq!=0 ); /* table of a LEFT JOIN */
141053 if( pLoop->prereq==0
141054 && (pTerm->wtFlags & TERM_VIRTUAL)==0
141055 && !ExprHasProperty(pExpr, EP_FromJoin)
141056 && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
141057 pPartial = sqlite3ExprAnd(pParse, pPartial,
141058 sqlite3ExprDup(pParse->db, pExpr, 0));
141059 }
141060 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
141061 int iCol = pTerm->u.leftColumn;
141062 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
@@ -146275,17 +146557,22 @@
146557 ** expression list pList. Return a pointer to the result list.
146558 */
146559 static ExprList *exprListAppendList(
146560 Parse *pParse, /* Parsing context */
146561 ExprList *pList, /* List to which to append. Might be NULL */
146562 ExprList *pAppend, /* List of values to append. Might be NULL */
146563 int bIntToNull
146564 ){
146565 if( pAppend ){
146566 int i;
146567 int nInit = pList ? pList->nExpr : 0;
146568 for(i=0; i<pAppend->nExpr; i++){
146569 Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
146570 if( bIntToNull && pDup && pDup->op==TK_INTEGER ){
146571 pDup->op = TK_NULL;
146572 pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
146573 }
146574 pList = sqlite3ExprListAppend(pParse, pList, pDup);
146575 if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
146576 }
146577 }
146578 return pList;
@@ -146321,11 +146608,11 @@
146608
146609 /* Create the ORDER BY clause for the sub-select. This is the concatenation
146610 ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
146611 ** redundant, remove the ORDER BY from the parent SELECT. */
146612 pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
146613 pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
146614 if( pSort && p->pOrderBy ){
146615 if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
146616 sqlite3ExprListDelete(db, p->pOrderBy);
146617 p->pOrderBy = 0;
146618 }
@@ -146342,20 +146629,20 @@
146629 pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
146630
146631 /* Append the PARTITION BY and ORDER BY expressions to the to the
146632 ** sub-select expression list. They are required to figure out where
146633 ** boundaries for partitions and sets of peer rows lie. */
146634 pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
146635 pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
146636
146637 /* Append the arguments passed to each window function to the
146638 ** sub-select expression list. Also allocate two registers for each
146639 ** window function - one for the accumulator, another for interim
146640 ** results. */
146641 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
146642 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
146643 pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
146644 if( pWin->pFilter ){
146645 Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
146646 pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
146647 }
146648 pWin->regAccum = ++pParse->nMem;
@@ -152081,11 +152368,13 @@
152368 sqlite3ExprListDelete(pParse->db, pList);
152369 }
152370 }
152371 break;
152372 case 179: /* expr ::= expr AND expr */
152373 {yymsp[-2].minor.yy524=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy524,yymsp[0].minor.yy524);}
152374 break;
152375 case 180: /* expr ::= expr OR expr */
152376 case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
152377 case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
152378 case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
152379 case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
152380 case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
@@ -158717,10 +159006,26 @@
159006 FILE *out = va_arg(ap, FILE*);
159007 if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
159008 break;
159009 }
159010 #endif /* defined(YYCOVERAGE) */
159011
159012 /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
159013 **
159014 ** This test-control causes the most recent sqlite3_result_int64() value
159015 ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally,
159016 ** MEM_IntReal values only arise during an INSERT operation of integer
159017 ** values into a REAL column, so they can be challenging to test. This
159018 ** test-control enables us to write an intreal() SQL function that can
159019 ** inject an intreal() value at arbitrary places in an SQL statement,
159020 ** for testing purposes.
159021 */
159022 case SQLITE_TESTCTRL_RESULT_INTREAL: {
159023 sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
159024 sqlite3ResultIntReal(pCtx);
159025 break;
159026 }
159027 }
159028 va_end(ap);
159029 #endif /* SQLITE_UNTESTABLE */
159030 return rc;
159031 }
@@ -174130,11 +174435,11 @@
174435 if( bFirst==0 ){
174436 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
174437 }
174438 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
174439
174440 if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
174441 return FTS_CORRUPT_VTAB;
174442 }
174443 blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
174444 if( rc==SQLITE_OK ){
174445 memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -174149,11 +174454,11 @@
174454 p->iOff += p->nDoclist;
174455 }
174456 }
174457 }
174458
174459 assert_fts3_nc( p->iOff<=p->nNode );
174460 return rc;
174461 }
174462
174463 /*
174464 ** Release all dynamic resources held by node-reader object *p.
@@ -189790,11 +190095,12 @@
190095 assert( argc==1 || argc==2 );
190096
190097 zIn = (const char*)sqlite3_value_text(argv[0]);
190098 if( zIn ){
190099 if( rbuIsVacuum(p) ){
190100 assert( argc==2 );
190101 if( 0==sqlite3_value_int(argv[1]) ){
190102 sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
190103 }
190104 }else{
190105 if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
190106 int i;
@@ -190241,11 +190547,12 @@
190547 SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
190548 SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
190549 }
190550
190551 pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
190552 assert( iPk>=0 );
190553 pIter->abTblPk[iOrder] = (u8)iPk;
190554 pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
190555 iOrder++;
190556 }
190557 }
190558
@@ -190275,10 +190582,217 @@
190582 zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
190583 zSep = ", ";
190584 }
190585 return zList;
190586 }
190587
190588 /*
190589 ** Return a comma separated list of the quoted PRIMARY KEY column names,
190590 ** in order, for the current table. Before each column name, add the text
190591 ** zPre. After each column name, add the zPost text. Use zSeparator as
190592 ** the separator text (usually ", ").
190593 */
190594 static char *rbuObjIterGetPkList(
190595 sqlite3rbu *p, /* RBU object */
190596 RbuObjIter *pIter, /* Object iterator for column names */
190597 const char *zPre, /* Before each quoted column name */
190598 const char *zSeparator, /* Separator to use between columns */
190599 const char *zPost /* After each quoted column name */
190600 ){
190601 int iPk = 1;
190602 char *zRet = 0;
190603 const char *zSep = "";
190604 while( 1 ){
190605 int i;
190606 for(i=0; i<pIter->nTblCol; i++){
190607 if( (int)pIter->abTblPk[i]==iPk ){
190608 const char *zCol = pIter->azTblCol[i];
190609 zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
190610 zSep = zSeparator;
190611 break;
190612 }
190613 }
190614 if( i==pIter->nTblCol ) break;
190615 iPk++;
190616 }
190617 return zRet;
190618 }
190619
190620 /*
190621 ** This function is called as part of restarting an RBU vacuum within
190622 ** stage 1 of the process (while the *-oal file is being built) while
190623 ** updating a table (not an index). The table may be a rowid table or
190624 ** a WITHOUT ROWID table. It queries the target database to find the
190625 ** largest key that has already been written to the target table and
190626 ** constructs a WHERE clause that can be used to extract the remaining
190627 ** rows from the source table. For a rowid table, the WHERE clause
190628 ** is of the form:
190629 **
190630 ** "WHERE _rowid_ > ?"
190631 **
190632 ** and for WITHOUT ROWID tables:
190633 **
190634 ** "WHERE (key1, key2) > (?, ?)"
190635 **
190636 ** Instead of "?" placeholders, the actual WHERE clauses created by
190637 ** this function contain literal SQL values.
190638 */
190639 static char *rbuVacuumTableStart(
190640 sqlite3rbu *p, /* RBU handle */
190641 RbuObjIter *pIter, /* RBU iterator object */
190642 int bRowid, /* True for a rowid table */
190643 const char *zWrite /* Target table name prefix */
190644 ){
190645 sqlite3_stmt *pMax = 0;
190646 char *zRet = 0;
190647 if( bRowid ){
190648 p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
190649 sqlite3_mprintf(
190650 "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
190651 )
190652 );
190653 if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
190654 sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
190655 zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
190656 }
190657 rbuFinalize(p, pMax);
190658 }else{
190659 char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
190660 char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
190661 char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
190662
190663 if( p->rc==SQLITE_OK ){
190664 p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
190665 sqlite3_mprintf(
190666 "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1",
190667 zSelect, zWrite, pIter->zTbl, zOrder
190668 )
190669 );
190670 if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
190671 const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
190672 zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
190673 }
190674 rbuFinalize(p, pMax);
190675 }
190676
190677 sqlite3_free(zOrder);
190678 sqlite3_free(zSelect);
190679 sqlite3_free(zList);
190680 }
190681 return zRet;
190682 }
190683
190684 /*
190685 ** This function is called as part of restating an RBU vacuum when the
190686 ** current operation is writing content to an index. If possible, it
190687 ** queries the target index b-tree for the largest key already written to
190688 ** it, then composes and returns an expression that can be used in a WHERE
190689 ** clause to select the remaining required rows from the source table.
190690 ** It is only possible to return such an expression if:
190691 **
190692 ** * The index contains no DESC columns, and
190693 ** * The last key written to the index before the operation was
190694 ** suspended does not contain any NULL values.
190695 **
190696 ** The expression is of the form:
190697 **
190698 ** (index-field1, index-field2, ...) > (?, ?, ...)
190699 **
190700 ** except that the "?" placeholders are replaced with literal values.
190701 **
190702 ** If the expression cannot be created, NULL is returned. In this case,
190703 ** the caller has to use an OFFSET clause to extract only the required
190704 ** rows from the sourct table, just as it does for an RBU update operation.
190705 */
190706 char *rbuVacuumIndexStart(
190707 sqlite3rbu *p, /* RBU handle */
190708 RbuObjIter *pIter /* RBU iterator object */
190709 ){
190710 char *zOrder = 0;
190711 char *zLhs = 0;
190712 char *zSelect = 0;
190713 char *zVector = 0;
190714 char *zRet = 0;
190715 int bFailed = 0;
190716 const char *zSep = "";
190717 int iCol = 0;
190718 sqlite3_stmt *pXInfo = 0;
190719
190720 p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
190721 sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
190722 );
190723 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
190724 int iCid = sqlite3_column_int(pXInfo, 1);
190725 const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
190726 const char *zCol;
190727 if( sqlite3_column_int(pXInfo, 3) ){
190728 bFailed = 1;
190729 break;
190730 }
190731
190732 if( iCid<0 ){
190733 if( pIter->eType==RBU_PK_IPK ){
190734 int i;
190735 for(i=0; pIter->abTblPk[i]==0; i++);
190736 assert( i<pIter->nTblCol );
190737 zCol = pIter->azTblCol[i];
190738 }else{
190739 zCol = "_rowid_";
190740 }
190741 }else{
190742 zCol = pIter->azTblCol[iCid];
190743 }
190744
190745 zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
190746 zLhs, zSep, zCol, zCollate
190747 );
190748 zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
190749 zOrder, zSep, iCol, zCol, zCollate
190750 );
190751 zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
190752 zSelect, zSep, iCol, zCol
190753 );
190754 zSep = ", ";
190755 iCol++;
190756 }
190757 rbuFinalize(p, pXInfo);
190758 if( bFailed ) goto index_start_out;
190759
190760 if( p->rc==SQLITE_OK ){
190761 sqlite3_stmt *pSel = 0;
190762
190763 p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
190764 sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
190765 zSelect, pIter->zTbl, zOrder
190766 )
190767 );
190768 if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
190769 zSep = "";
190770 for(iCol=0; iCol<pIter->nCol; iCol++){
190771 const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
190772 if( zQuoted[0]=='N' ){
190773 bFailed = 1;
190774 break;
190775 }
190776 zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
190777 zSep = ", ";
190778 }
190779
190780 if( !bFailed ){
190781 zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
190782 }
190783 }
190784 rbuFinalize(p, pSel);
190785 }
190786
190787 index_start_out:
190788 sqlite3_free(zOrder);
190789 sqlite3_free(zSelect);
190790 sqlite3_free(zVector);
190791 sqlite3_free(zLhs);
190792 return zRet;
190793 }
190794
190795 /*
190796 ** This function is used to create a SELECT list (the list of SQL
190797 ** expressions that follows a SELECT keyword) for a SELECT statement
190798 ** used to read from an data_xxx or rbu_tmp_xxx table while updating the
@@ -190952,16 +191466,28 @@
191466
191467 /* Create the SELECT statement to read keys in sorted order */
191468 if( p->rc==SQLITE_OK ){
191469 char *zSql;
191470 if( rbuIsVacuum(p) ){
191471 char *zStart = 0;
191472 if( nOffset ){
191473 zStart = rbuVacuumIndexStart(p, pIter);
191474 if( zStart ){
191475 sqlite3_free(zLimit);
191476 zLimit = 0;
191477 }
191478 }
191479
191480 zSql = sqlite3_mprintf(
191481 "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
191482 zCollist,
191483 pIter->zDataTbl,
191484 zPart,
191485 (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
191486 zCollist, zLimit
191487 );
191488 sqlite3_free(zStart);
191489 }else
191490
191491 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
191492 zSql = sqlite3_mprintf(
191493 "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
@@ -190980,11 +191506,15 @@
191506 zPart,
191507 (zPart ? "AND" : "WHERE"),
191508 zCollist, zLimit
191509 );
191510 }
191511 if( p->rc==SQLITE_OK ){
191512 p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
191513 }else{
191514 sqlite3_free(zSql);
191515 }
191516 }
191517
191518 sqlite3_free(zImposterCols);
191519 sqlite3_free(zImposterPK);
191520 sqlite3_free(zWhere);
@@ -191080,22 +191610,46 @@
191610 }
191611
191612 /* Create the SELECT statement to read keys from data_xxx */
191613 if( p->rc==SQLITE_OK ){
191614 const char *zRbuRowid = "";
191615 char *zStart = 0;
191616 char *zOrder = 0;
191617 if( bRbuRowid ){
191618 zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
191619 }
191620
191621 if( rbuIsVacuum(p) ){
191622 if( nOffset ){
191623 zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
191624 if( zStart ){
191625 sqlite3_free(zLimit);
191626 zLimit = 0;
191627 }
191628 }
191629 if( bRbuRowid ){
191630 zOrder = rbuMPrintf(p, "_rowid_");
191631 }else{
191632 zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
191633 }
191634 }
191635
191636 if( p->rc==SQLITE_OK ){
191637 p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
191638 sqlite3_mprintf(
191639 "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
191640 zCollist,
191641 (rbuIsVacuum(p) ? "0 AS " : ""),
191642 zRbuRowid,
191643 pIter->zDataTbl, (zStart ? zStart : ""),
191644 (zOrder ? "ORDER BY" : ""), zOrder,
191645 zLimit
191646 )
191647 );
191648 }
191649 sqlite3_free(zStart);
191650 sqlite3_free(zOrder);
191651 }
191652
191653 sqlite3_free(zWhere);
191654 sqlite3_free(zOldlist);
191655 sqlite3_free(zNewlist);
@@ -193661,11 +194215,12 @@
194215 ** be intercepted (see the rbuVfsOpen() function) and the *-oal
194216 ** file opened instead.
194217 */
194218 if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
194219 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
194220 if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
194221 assert( pDb->pRbu );
194222 if( *pResOut ){
194223 rc = SQLITE_CANTOPEN;
194224 }else{
194225 sqlite3_int64 sz = 0;
194226 rc = rbuVfsFileSize(&pDb->base, &sz);
@@ -204285,11 +204840,15 @@
204840 return 1;
204841 }else{
204842 i64 iOff = *piOff;
204843 int iVal;
204844 fts5FastGetVarint32(a, i, iVal);
204845 if( iVal<=1 ){
204846 if( iVal==0 ){
204847 *pi = i;
204848 return 0;
204849 }
204850 fts5FastGetVarint32(a, i, iVal);
204851 iOff = ((i64)iVal) << 32;
204852 fts5FastGetVarint32(a, i, iVal);
204853 }
204854 *piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
@@ -218101,11 +218660,11 @@
218660 int nArg, /* Number of args */
218661 sqlite3_value **apUnused /* Function arguments */
218662 ){
218663 assert( nArg==0 );
218664 UNUSED_PARAM2(nArg, apUnused);
218665 sqlite3_result_text(pCtx, "fts5: 2019-05-10 17:50:33 2846bc0429c0956473bfe99dde135f2c206720f0be4c2800118b280e446ce325", -1, SQLITE_TRANSIENT);
218666 }
218667
218668 /*
218669 ** Return true if zName is the extension on one of the shadow tables used
218670 ** by this module.
@@ -222865,12 +223424,12 @@
223424 }
223425 #endif /* SQLITE_CORE */
223426 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
223427
223428 /************** End of stmt.c ************************************************/
223429 #if __LINE__!=223429
223430 #undef SQLITE_SOURCE_ID
223431 #define SQLITE_SOURCE_ID "2019-05-10 17:54:58 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000falt2"
223432 #endif
223433 /* Return the source-id for this library */
223434 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
223435 /************************** End of sqlite3.c ******************************/
223436
+5 -4
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -121,13 +121,13 @@
121121
**
122122
** See also: [sqlite3_libversion()],
123123
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124124
** [sqlite_version()] and [sqlite_source_id()].
125125
*/
126
-#define SQLITE_VERSION "3.28.0"
127
-#define SQLITE_VERSION_NUMBER 3028000
128
-#define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50"
126
+#define SQLITE_VERSION "3.29.0"
127
+#define SQLITE_VERSION_NUMBER 3029000
128
+#define SQLITE_SOURCE_ID "2019-05-10 17:54:58 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000f2362"
129129
130130
/*
131131
** CAPI3REF: Run-Time Library Version Numbers
132132
** KEYWORDS: sqlite3_version sqlite3_sourceid
133133
**
@@ -7317,11 +7317,12 @@
73177317
#define SQLITE_TESTCTRL_BYTEORDER 22
73187318
#define SQLITE_TESTCTRL_ISINIT 23
73197319
#define SQLITE_TESTCTRL_SORTER_MMAP 24
73207320
#define SQLITE_TESTCTRL_IMPOSTER 25
73217321
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
7322
-#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
7322
+#define SQLITE_TESTCTRL_RESULT_INTREAL 27
7323
+#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
73237324
73247325
/*
73257326
** CAPI3REF: SQL Keyword Checking
73267327
**
73277328
** These routines provide access to the set of SQL language keywords
73287329
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -121,13 +121,13 @@
121 **
122 ** See also: [sqlite3_libversion()],
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.28.0"
127 #define SQLITE_VERSION_NUMBER 3028000
128 #define SQLITE_SOURCE_ID "2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
@@ -7317,11 +7317,12 @@
7317 #define SQLITE_TESTCTRL_BYTEORDER 22
7318 #define SQLITE_TESTCTRL_ISINIT 23
7319 #define SQLITE_TESTCTRL_SORTER_MMAP 24
7320 #define SQLITE_TESTCTRL_IMPOSTER 25
7321 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26
7322 #define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
 
7323
7324 /*
7325 ** CAPI3REF: SQL Keyword Checking
7326 **
7327 ** These routines provide access to the set of SQL language keywords
7328
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -121,13 +121,13 @@
121 **
122 ** See also: [sqlite3_libversion()],
123 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
124 ** [sqlite_version()] and [sqlite_source_id()].
125 */
126 #define SQLITE_VERSION "3.29.0"
127 #define SQLITE_VERSION_NUMBER 3029000
128 #define SQLITE_SOURCE_ID "2019-05-10 17:54:58 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000f2362"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
@@ -7317,11 +7317,12 @@
7317 #define SQLITE_TESTCTRL_BYTEORDER 22
7318 #define SQLITE_TESTCTRL_ISINIT 23
7319 #define SQLITE_TESTCTRL_SORTER_MMAP 24
7320 #define SQLITE_TESTCTRL_IMPOSTER 25
7321 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26
7322 #define SQLITE_TESTCTRL_RESULT_INTREAL 27
7323 #define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
7324
7325 /*
7326 ** CAPI3REF: SQL Keyword Checking
7327 **
7328 ** These routines provide access to the set of SQL language keywords
7329
+2 -4
--- src/style.c
+++ src/style.c
@@ -573,14 +573,11 @@
573573
*/
574574
static void style_load_all_js_files(void){
575575
int i;
576576
if( needHrefJs ){
577577
int nDelay = db_get_int("auto-hyperlink-delay",0);
578
- int bMouseover;
579
- /* Load up the page data */
580
- bMouseover = (!g.isHuman || db_get_boolean("auto-hyperlink-ishuman",0))
581
- && db_get_boolean("auto-hyperlink-mouseover",0);
578
+ int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
582579
@ <script id='href-data' type='application/json'>\
583580
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
584581
}
585582
@ <script nonce="%h(style_nonce())">
586583
if( needHrefJs ){
@@ -631,10 +628,11 @@
631628
if( nSubmenu+nSubmenuCtrl>0 ){
632629
int i;
633630
if( nSubmenuCtrl ){
634631
@ <form id='f01' method='GET' action='%R/%s(g.zPath)'>
635632
@ <input type='hidden' name='udc' value='1'>
633
+ cgi_tag_query_parameter("udc");
636634
}
637635
@ <div class="submenu">
638636
if( nSubmenu>0 ){
639637
qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
640638
for(i=0; i<nSubmenu; i++){
641639
--- src/style.c
+++ src/style.c
@@ -573,14 +573,11 @@
573 */
574 static void style_load_all_js_files(void){
575 int i;
576 if( needHrefJs ){
577 int nDelay = db_get_int("auto-hyperlink-delay",0);
578 int bMouseover;
579 /* Load up the page data */
580 bMouseover = (!g.isHuman || db_get_boolean("auto-hyperlink-ishuman",0))
581 && db_get_boolean("auto-hyperlink-mouseover",0);
582 @ <script id='href-data' type='application/json'>\
583 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
584 }
585 @ <script nonce="%h(style_nonce())">
586 if( needHrefJs ){
@@ -631,10 +628,11 @@
631 if( nSubmenu+nSubmenuCtrl>0 ){
632 int i;
633 if( nSubmenuCtrl ){
634 @ <form id='f01' method='GET' action='%R/%s(g.zPath)'>
635 @ <input type='hidden' name='udc' value='1'>
 
636 }
637 @ <div class="submenu">
638 if( nSubmenu>0 ){
639 qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
640 for(i=0; i<nSubmenu; i++){
641
--- src/style.c
+++ src/style.c
@@ -573,14 +573,11 @@
573 */
574 static void style_load_all_js_files(void){
575 int i;
576 if( needHrefJs ){
577 int nDelay = db_get_int("auto-hyperlink-delay",0);
578 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
 
 
 
579 @ <script id='href-data' type='application/json'>\
580 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
581 }
582 @ <script nonce="%h(style_nonce())">
583 if( needHrefJs ){
@@ -631,10 +628,11 @@
628 if( nSubmenu+nSubmenuCtrl>0 ){
629 int i;
630 if( nSubmenuCtrl ){
631 @ <form id='f01' method='GET' action='%R/%s(g.zPath)'>
632 @ <input type='hidden' name='udc' value='1'>
633 cgi_tag_query_parameter("udc");
634 }
635 @ <div class="submenu">
636 if( nSubmenu>0 ){
637 qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
638 for(i=0; i<nSubmenu; i++){
639
+93 -5
--- src/timeline.c
+++ src/timeline.c
@@ -112,10 +112,11 @@
112112
#define TIMELINE_CLASSIC 0x010000 /* Use the "classic" view style */
113113
#define TIMELINE_VIEWS 0x01f000 /* Mask for all of the view styles */
114114
#define TIMELINE_NOSCROLL 0x100000 /* Don't scroll to the selection */
115115
#define TIMELINE_FILEDIFF 0x200000 /* Show File differences, not ckin diffs */
116116
#define TIMELINE_CHPICK 0x400000 /* Show cherrypick merges */
117
+#define TIMELINE_FILLGAPS 0x800000 /* Dotted lines for missing nodes */
117118
#endif
118119
119120
/*
120121
** Hash a string and use the hash to determine a background color.
121122
*/
@@ -757,16 +758,17 @@
757758
}
758759
if( pendingEndTr ){
759760
@ </td></tr>
760761
}
761762
if( pGraph ){
762
- graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
763
+ graph_finish(pGraph, tmFlags);
763764
if( pGraph->nErr ){
764765
graph_free(pGraph);
765766
pGraph = 0;
766767
}else{
767
- @ <tr class="timelineBottom"><td></td><td></td><td></td></tr>
768
+ @ <tr class="timelineBottom" id="btm-%d(iTableId)">\
769
+ @ <td></td><td></td><td></td></tr>
768770
}
769771
}
770772
@ </table>
771773
if( fchngQueryInit ) db_finalize(&fchngQuery);
772774
timeline_output_graph_javascript(pGraph, tmFlags, iTableId);
@@ -848,10 +850,11 @@
848850
@ "omitDescenders": %d(omitDescenders),
849851
@ "fileDiff": %d(fileDiff),
850852
@ "scrollToSelect": %d(scrollToSelect),
851853
@ "nrail": %d(pGraph->mxRail+1),
852854
@ "baseUrl": "%R",
855
+ @ "bottomRowId": "btm-%d(iTableId)",
853856
if( pGraph->nRow==0 ){
854857
@ "rowinfo": null
855858
}else{
856859
@ "rowinfo": [
857860
}
@@ -877,10 +880,14 @@
877880
** cu: Extend the mu merge arrow up to this row as a cherrypick
878881
** merge line, if this value exists.
879882
** u: Draw a thick child-line out of the top of this node and up to
880883
** the node with an id equal to this value. 0 if it is straight to
881884
** the top of the page, -1 if there is no thick-line riser.
885
+ ** sb: Draw a dotted child-line out of the top of this node up to the
886
+ ** node with the id equal to the value. This is like "u" except
887
+ ** that the line is dotted instead of solid and has no arrow.
888
+ ** Mnemonic: "Same Branch".
882889
** f: 0x01: a leaf node.
883890
** au: An array of integers that define thick-line risers for branches.
884891
** The integers are in pairs. For each pair, the first integer is
885892
** is the rail on which the riser should run and the second integer
886893
** is the id of the node upto which the riser should run. If there
@@ -909,11 +916,15 @@
909916
cgi_printf("\"mu\":%d,", pRow->mergeUpto);
910917
if( pRow->cherrypickUpto>0 && pRow->cherrypickUpto<pRow->mergeUpto ){
911918
cgi_printf("\"cu\":%d,", pRow->cherrypickUpto);
912919
}
913920
}
914
- cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]);
921
+ if( pRow->isStepParent ){
922
+ cgi_printf("\"sb\":%d,", pRow->aiRiser[pRow->iRail]);
923
+ }else{
924
+ cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]);
925
+ }
915926
k = 0;
916927
if( pRow->isLeaf ) k |= 1;
917928
cgi_printf("\"f\":%d,",k);
918929
for(i=k=0; i<GR_MAX_RAIL; i++){
919930
if( i==pRow->iRail ) continue;
@@ -1679,10 +1690,14 @@
16791690
if( zType[0]=='a' ){
16801691
tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH | TIMELINE_CHPICK;
16811692
}else{
16821693
tmFlags |= TIMELINE_GRAPH | TIMELINE_CHPICK;
16831694
}
1695
+ if( related ){
1696
+ tmFlags |= TIMELINE_FILLGAPS;
1697
+// tmFlags &= ~TIMELINE_DISJOINT;
1698
+ }
16841699
if( PB("ncp") ){
16851700
tmFlags &= ~TIMELINE_CHPICK;
16861701
}
16871702
if( PB("ng") || zSearch!=0 ){
16881703
tmFlags &= ~(TIMELINE_GRAPH|TIMELINE_CHPICK);
@@ -1741,19 +1756,19 @@
17411756
&& db_open_local(0)
17421757
){
17431758
int iCurrent = db_lget_int("checkout",0);
17441759
char *zPerm = bisect_permalink();
17451760
bisect_create_bilog_table(iCurrent, 0);
1746
- tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT;
1761
+ tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT | TIMELINE_FILLGAPS;
17471762
zType = "ci";
17481763
disableY = 1;
17491764
style_submenu_element("Permalink", "%R/timeline?bid=%z", zPerm);
17501765
}else{
17511766
bisectLocal = 0;
17521767
}
17531768
if( zBisect!=0 && bisect_create_bilog_table(0, zBisect) ){
1754
- tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT;
1769
+ tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT | TIMELINE_FILLGAPS;
17551770
zType = "ci";
17561771
disableY = 1;
17571772
}else{
17581773
zBisect = 0;
17591774
}
@@ -2783,10 +2798,83 @@
27832798
db_prepare_blob(&q, &sql);
27842799
blob_reset(&sql);
27852800
print_timeline(&q, n, width, verboseFlag);
27862801
db_finalize(&q);
27872802
}
2803
+
2804
+/*
2805
+** WEBPAGE: thisdayinhistory
2806
+**
2807
+** Generate a vanity page that shows project activity for the current
2808
+** day of the year for various years in the history of the project.
2809
+**
2810
+** Query parameters:
2811
+**
2812
+** today=DATE Use DATE as today's date
2813
+*/
2814
+void thisdayinhistory_page(void){
2815
+ static int aYearsAgo[] = { 1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50, 75, 100 };
2816
+ const char *zToday;
2817
+ char *zStartOfProject;
2818
+ int i;
2819
+ Stmt q;
2820
+ char *z;
2821
+
2822
+ login_check_credentials();
2823
+ if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
2824
+ login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
2825
+ return;
2826
+ }
2827
+ style_header("Today In History");
2828
+ zToday = (char*)P("today");
2829
+ if( zToday ){
2830
+ zToday = timeline_expand_datetime(zToday);
2831
+ if( !fossil_isdate(zToday) ) zToday = 0;
2832
+ }
2833
+ if( zToday==0 ){
2834
+ zToday = db_text(0, "SELECT date('now',toLocal())");
2835
+ }
2836
+ @ <h1>This Day In History For %h(zToday)</h1>
2837
+ z = db_text(0, "SELECT date(%Q,'-1 day')", zToday);
2838
+ style_submenu_element("Yesterday", "%R/thisdayinhistory?today=%t", z);
2839
+ z = db_text(0, "SELECT date(%Q,'+1 day')", zToday);
2840
+ style_submenu_element("Tomorrow", "%R/thisdayinhistory?today=%t", z);
2841
+ zStartOfProject = db_text(0,
2842
+ "SELECT datetime(min(mtime),toLocal()) FROM event;"
2843
+ );
2844
+ timeline_temp_table();
2845
+ db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
2846
+ for(i=0; i<sizeof(aYearsAgo)/sizeof(aYearsAgo[0]); i++){
2847
+ int iAgo = aYearsAgo[i];
2848
+ char *zThis = db_text(0, "SELECT date(%Q,'-%d years')", zToday, iAgo);
2849
+ Blob sql;
2850
+ char *zId;
2851
+ if( strcmp(zThis, zStartOfProject)<0 ) break;
2852
+ blob_init(&sql, 0, 0);
2853
+ blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
2854
+ blob_append(&sql, timeline_query_for_www(), -1);
2855
+ blob_append_sql(&sql,
2856
+ " AND %Q=date(event.mtime,toLocal()) "
2857
+ " AND event.mtime BETWEEN julianday(%Q,'-1 day')"
2858
+ " AND julianday(%Q,'+2 days')",
2859
+ zThis, zThis, zThis
2860
+ );
2861
+ db_multi_exec("DELETE FROM timeline; %s;", blob_sql_text(&sql));
2862
+ blob_reset(&sql);
2863
+ if( db_int(0, "SELECT count(*) FROM timeline")==0 ){
2864
+ continue;
2865
+ }
2866
+ zId = db_text(0, "SELECT timestamp FROM timeline"
2867
+ " ORDER BY sortby DESC LIMIT 1");
2868
+ @ <h2>%d(iAgo) Year%s(iAgo>1?"s":"") Ago
2869
+ @ <small>%z(href("%R/timeline?c=%t",zId))(more context)</a>\
2870
+ @ </small></h2>
2871
+ www_print_timeline(&q, TIMELINE_GRAPH, 0, 0, 0, 0);
2872
+ }
2873
+ db_finalize(&q);
2874
+ style_footer();
2875
+}
27882876
27892877
27902878
/*
27912879
** COMMAND: test-timewarp-list
27922880
**
27932881
--- src/timeline.c
+++ src/timeline.c
@@ -112,10 +112,11 @@
112 #define TIMELINE_CLASSIC 0x010000 /* Use the "classic" view style */
113 #define TIMELINE_VIEWS 0x01f000 /* Mask for all of the view styles */
114 #define TIMELINE_NOSCROLL 0x100000 /* Don't scroll to the selection */
115 #define TIMELINE_FILEDIFF 0x200000 /* Show File differences, not ckin diffs */
116 #define TIMELINE_CHPICK 0x400000 /* Show cherrypick merges */
 
117 #endif
118
119 /*
120 ** Hash a string and use the hash to determine a background color.
121 */
@@ -757,16 +758,17 @@
757 }
758 if( pendingEndTr ){
759 @ </td></tr>
760 }
761 if( pGraph ){
762 graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
763 if( pGraph->nErr ){
764 graph_free(pGraph);
765 pGraph = 0;
766 }else{
767 @ <tr class="timelineBottom"><td></td><td></td><td></td></tr>
 
768 }
769 }
770 @ </table>
771 if( fchngQueryInit ) db_finalize(&fchngQuery);
772 timeline_output_graph_javascript(pGraph, tmFlags, iTableId);
@@ -848,10 +850,11 @@
848 @ "omitDescenders": %d(omitDescenders),
849 @ "fileDiff": %d(fileDiff),
850 @ "scrollToSelect": %d(scrollToSelect),
851 @ "nrail": %d(pGraph->mxRail+1),
852 @ "baseUrl": "%R",
 
853 if( pGraph->nRow==0 ){
854 @ "rowinfo": null
855 }else{
856 @ "rowinfo": [
857 }
@@ -877,10 +880,14 @@
877 ** cu: Extend the mu merge arrow up to this row as a cherrypick
878 ** merge line, if this value exists.
879 ** u: Draw a thick child-line out of the top of this node and up to
880 ** the node with an id equal to this value. 0 if it is straight to
881 ** the top of the page, -1 if there is no thick-line riser.
 
 
 
 
882 ** f: 0x01: a leaf node.
883 ** au: An array of integers that define thick-line risers for branches.
884 ** The integers are in pairs. For each pair, the first integer is
885 ** is the rail on which the riser should run and the second integer
886 ** is the id of the node upto which the riser should run. If there
@@ -909,11 +916,15 @@
909 cgi_printf("\"mu\":%d,", pRow->mergeUpto);
910 if( pRow->cherrypickUpto>0 && pRow->cherrypickUpto<pRow->mergeUpto ){
911 cgi_printf("\"cu\":%d,", pRow->cherrypickUpto);
912 }
913 }
914 cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]);
 
 
 
 
915 k = 0;
916 if( pRow->isLeaf ) k |= 1;
917 cgi_printf("\"f\":%d,",k);
918 for(i=k=0; i<GR_MAX_RAIL; i++){
919 if( i==pRow->iRail ) continue;
@@ -1679,10 +1690,14 @@
1679 if( zType[0]=='a' ){
1680 tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH | TIMELINE_CHPICK;
1681 }else{
1682 tmFlags |= TIMELINE_GRAPH | TIMELINE_CHPICK;
1683 }
 
 
 
 
1684 if( PB("ncp") ){
1685 tmFlags &= ~TIMELINE_CHPICK;
1686 }
1687 if( PB("ng") || zSearch!=0 ){
1688 tmFlags &= ~(TIMELINE_GRAPH|TIMELINE_CHPICK);
@@ -1741,19 +1756,19 @@
1741 && db_open_local(0)
1742 ){
1743 int iCurrent = db_lget_int("checkout",0);
1744 char *zPerm = bisect_permalink();
1745 bisect_create_bilog_table(iCurrent, 0);
1746 tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT;
1747 zType = "ci";
1748 disableY = 1;
1749 style_submenu_element("Permalink", "%R/timeline?bid=%z", zPerm);
1750 }else{
1751 bisectLocal = 0;
1752 }
1753 if( zBisect!=0 && bisect_create_bilog_table(0, zBisect) ){
1754 tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT;
1755 zType = "ci";
1756 disableY = 1;
1757 }else{
1758 zBisect = 0;
1759 }
@@ -2783,10 +2798,83 @@
2783 db_prepare_blob(&q, &sql);
2784 blob_reset(&sql);
2785 print_timeline(&q, n, width, verboseFlag);
2786 db_finalize(&q);
2787 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2788
2789
2790 /*
2791 ** COMMAND: test-timewarp-list
2792 **
2793
--- src/timeline.c
+++ src/timeline.c
@@ -112,10 +112,11 @@
112 #define TIMELINE_CLASSIC 0x010000 /* Use the "classic" view style */
113 #define TIMELINE_VIEWS 0x01f000 /* Mask for all of the view styles */
114 #define TIMELINE_NOSCROLL 0x100000 /* Don't scroll to the selection */
115 #define TIMELINE_FILEDIFF 0x200000 /* Show File differences, not ckin diffs */
116 #define TIMELINE_CHPICK 0x400000 /* Show cherrypick merges */
117 #define TIMELINE_FILLGAPS 0x800000 /* Dotted lines for missing nodes */
118 #endif
119
120 /*
121 ** Hash a string and use the hash to determine a background color.
122 */
@@ -757,16 +758,17 @@
758 }
759 if( pendingEndTr ){
760 @ </td></tr>
761 }
762 if( pGraph ){
763 graph_finish(pGraph, tmFlags);
764 if( pGraph->nErr ){
765 graph_free(pGraph);
766 pGraph = 0;
767 }else{
768 @ <tr class="timelineBottom" id="btm-%d(iTableId)">\
769 @ <td></td><td></td><td></td></tr>
770 }
771 }
772 @ </table>
773 if( fchngQueryInit ) db_finalize(&fchngQuery);
774 timeline_output_graph_javascript(pGraph, tmFlags, iTableId);
@@ -848,10 +850,11 @@
850 @ "omitDescenders": %d(omitDescenders),
851 @ "fileDiff": %d(fileDiff),
852 @ "scrollToSelect": %d(scrollToSelect),
853 @ "nrail": %d(pGraph->mxRail+1),
854 @ "baseUrl": "%R",
855 @ "bottomRowId": "btm-%d(iTableId)",
856 if( pGraph->nRow==0 ){
857 @ "rowinfo": null
858 }else{
859 @ "rowinfo": [
860 }
@@ -877,10 +880,14 @@
880 ** cu: Extend the mu merge arrow up to this row as a cherrypick
881 ** merge line, if this value exists.
882 ** u: Draw a thick child-line out of the top of this node and up to
883 ** the node with an id equal to this value. 0 if it is straight to
884 ** the top of the page, -1 if there is no thick-line riser.
885 ** sb: Draw a dotted child-line out of the top of this node up to the
886 ** node with the id equal to the value. This is like "u" except
887 ** that the line is dotted instead of solid and has no arrow.
888 ** Mnemonic: "Same Branch".
889 ** f: 0x01: a leaf node.
890 ** au: An array of integers that define thick-line risers for branches.
891 ** The integers are in pairs. For each pair, the first integer is
892 ** is the rail on which the riser should run and the second integer
893 ** is the id of the node upto which the riser should run. If there
@@ -909,11 +916,15 @@
916 cgi_printf("\"mu\":%d,", pRow->mergeUpto);
917 if( pRow->cherrypickUpto>0 && pRow->cherrypickUpto<pRow->mergeUpto ){
918 cgi_printf("\"cu\":%d,", pRow->cherrypickUpto);
919 }
920 }
921 if( pRow->isStepParent ){
922 cgi_printf("\"sb\":%d,", pRow->aiRiser[pRow->iRail]);
923 }else{
924 cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]);
925 }
926 k = 0;
927 if( pRow->isLeaf ) k |= 1;
928 cgi_printf("\"f\":%d,",k);
929 for(i=k=0; i<GR_MAX_RAIL; i++){
930 if( i==pRow->iRail ) continue;
@@ -1679,10 +1690,14 @@
1690 if( zType[0]=='a' ){
1691 tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH | TIMELINE_CHPICK;
1692 }else{
1693 tmFlags |= TIMELINE_GRAPH | TIMELINE_CHPICK;
1694 }
1695 if( related ){
1696 tmFlags |= TIMELINE_FILLGAPS;
1697 // tmFlags &= ~TIMELINE_DISJOINT;
1698 }
1699 if( PB("ncp") ){
1700 tmFlags &= ~TIMELINE_CHPICK;
1701 }
1702 if( PB("ng") || zSearch!=0 ){
1703 tmFlags &= ~(TIMELINE_GRAPH|TIMELINE_CHPICK);
@@ -1741,19 +1756,19 @@
1756 && db_open_local(0)
1757 ){
1758 int iCurrent = db_lget_int("checkout",0);
1759 char *zPerm = bisect_permalink();
1760 bisect_create_bilog_table(iCurrent, 0);
1761 tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT | TIMELINE_FILLGAPS;
1762 zType = "ci";
1763 disableY = 1;
1764 style_submenu_element("Permalink", "%R/timeline?bid=%z", zPerm);
1765 }else{
1766 bisectLocal = 0;
1767 }
1768 if( zBisect!=0 && bisect_create_bilog_table(0, zBisect) ){
1769 tmFlags |= TIMELINE_UNHIDE | TIMELINE_BISECT | TIMELINE_FILLGAPS;
1770 zType = "ci";
1771 disableY = 1;
1772 }else{
1773 zBisect = 0;
1774 }
@@ -2783,10 +2798,83 @@
2798 db_prepare_blob(&q, &sql);
2799 blob_reset(&sql);
2800 print_timeline(&q, n, width, verboseFlag);
2801 db_finalize(&q);
2802 }
2803
2804 /*
2805 ** WEBPAGE: thisdayinhistory
2806 **
2807 ** Generate a vanity page that shows project activity for the current
2808 ** day of the year for various years in the history of the project.
2809 **
2810 ** Query parameters:
2811 **
2812 ** today=DATE Use DATE as today's date
2813 */
2814 void thisdayinhistory_page(void){
2815 static int aYearsAgo[] = { 1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50, 75, 100 };
2816 const char *zToday;
2817 char *zStartOfProject;
2818 int i;
2819 Stmt q;
2820 char *z;
2821
2822 login_check_credentials();
2823 if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
2824 login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
2825 return;
2826 }
2827 style_header("Today In History");
2828 zToday = (char*)P("today");
2829 if( zToday ){
2830 zToday = timeline_expand_datetime(zToday);
2831 if( !fossil_isdate(zToday) ) zToday = 0;
2832 }
2833 if( zToday==0 ){
2834 zToday = db_text(0, "SELECT date('now',toLocal())");
2835 }
2836 @ <h1>This Day In History For %h(zToday)</h1>
2837 z = db_text(0, "SELECT date(%Q,'-1 day')", zToday);
2838 style_submenu_element("Yesterday", "%R/thisdayinhistory?today=%t", z);
2839 z = db_text(0, "SELECT date(%Q,'+1 day')", zToday);
2840 style_submenu_element("Tomorrow", "%R/thisdayinhistory?today=%t", z);
2841 zStartOfProject = db_text(0,
2842 "SELECT datetime(min(mtime),toLocal()) FROM event;"
2843 );
2844 timeline_temp_table();
2845 db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
2846 for(i=0; i<sizeof(aYearsAgo)/sizeof(aYearsAgo[0]); i++){
2847 int iAgo = aYearsAgo[i];
2848 char *zThis = db_text(0, "SELECT date(%Q,'-%d years')", zToday, iAgo);
2849 Blob sql;
2850 char *zId;
2851 if( strcmp(zThis, zStartOfProject)<0 ) break;
2852 blob_init(&sql, 0, 0);
2853 blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
2854 blob_append(&sql, timeline_query_for_www(), -1);
2855 blob_append_sql(&sql,
2856 " AND %Q=date(event.mtime,toLocal()) "
2857 " AND event.mtime BETWEEN julianday(%Q,'-1 day')"
2858 " AND julianday(%Q,'+2 days')",
2859 zThis, zThis, zThis
2860 );
2861 db_multi_exec("DELETE FROM timeline; %s;", blob_sql_text(&sql));
2862 blob_reset(&sql);
2863 if( db_int(0, "SELECT count(*) FROM timeline")==0 ){
2864 continue;
2865 }
2866 zId = db_text(0, "SELECT timestamp FROM timeline"
2867 " ORDER BY sortby DESC LIMIT 1");
2868 @ <h2>%d(iAgo) Year%s(iAgo>1?"s":"") Ago
2869 @ <small>%z(href("%R/timeline?c=%t",zId))(more context)</a>\
2870 @ </small></h2>
2871 www_print_timeline(&q, TIMELINE_GRAPH, 0, 0, 0, 0);
2872 }
2873 db_finalize(&q);
2874 style_footer();
2875 }
2876
2877
2878 /*
2879 ** COMMAND: test-timewarp-list
2880 **
2881
--- src/unversioned.c
+++ src/unversioned.c
@@ -619,18 +619,16 @@
619619
sqlite3_int64 mtime = db_column_int(&q, 1);
620620
const char *zHash = db_column_text(&q, 2);
621621
int fullSize = db_column_int(&q, 3);
622622
const char *zLogin = db_column_text(&q, 4);
623623
if( zLogin==0 ) zLogin = "";
624
- blob_appendf(&json, "%s{\"name\":\"", zSep);
624
+ blob_appendf(&json, "%s{\"name\":\"%j\",\n", zSep, zName);
625625
zSep = ",\n ";
626
- blob_append_json_string(&json, zName);
627
- blob_appendf(&json, "\",\n \"mtime\":%lld,\n \"hash\":\"", mtime);
628
- blob_append_json_string(&json, zHash);
629
- blob_appendf(&json, "\",\n \"size\":%d,\n \"user\":\"", fullSize);
630
- blob_append_json_string(&json, zLogin);
631
- blob_appendf(&json, "\"}");
626
+ blob_appendf(&json, " \"mtime\":%lld,\n", mtime);
627
+ blob_appendf(&json, " \"hash\":\"%j\",\n", zHash);
628
+ blob_appendf(&json, " \"size\":%d,\n", fullSize);
629
+ blob_appendf(&json, " \"user\":\"%j\"}", zLogin);
632630
}
633631
db_finalize(&q);
634632
blob_appendf(&json,"]\n");
635633
cgi_set_content(&json);
636634
}
637635
--- src/unversioned.c
+++ src/unversioned.c
@@ -619,18 +619,16 @@
619 sqlite3_int64 mtime = db_column_int(&q, 1);
620 const char *zHash = db_column_text(&q, 2);
621 int fullSize = db_column_int(&q, 3);
622 const char *zLogin = db_column_text(&q, 4);
623 if( zLogin==0 ) zLogin = "";
624 blob_appendf(&json, "%s{\"name\":\"", zSep);
625 zSep = ",\n ";
626 blob_append_json_string(&json, zName);
627 blob_appendf(&json, "\",\n \"mtime\":%lld,\n \"hash\":\"", mtime);
628 blob_append_json_string(&json, zHash);
629 blob_appendf(&json, "\",\n \"size\":%d,\n \"user\":\"", fullSize);
630 blob_append_json_string(&json, zLogin);
631 blob_appendf(&json, "\"}");
632 }
633 db_finalize(&q);
634 blob_appendf(&json,"]\n");
635 cgi_set_content(&json);
636 }
637
--- src/unversioned.c
+++ src/unversioned.c
@@ -619,18 +619,16 @@
619 sqlite3_int64 mtime = db_column_int(&q, 1);
620 const char *zHash = db_column_text(&q, 2);
621 int fullSize = db_column_int(&q, 3);
622 const char *zLogin = db_column_text(&q, 4);
623 if( zLogin==0 ) zLogin = "";
624 blob_appendf(&json, "%s{\"name\":\"%j\",\n", zSep, zName);
625 zSep = ",\n ";
626 blob_appendf(&json, " \"mtime\":%lld,\n", mtime);
627 blob_appendf(&json, " \"hash\":\"%j\",\n", zHash);
628 blob_appendf(&json, " \"size\":%d,\n", fullSize);
629 blob_appendf(&json, " \"user\":\"%j\"}", zLogin);
 
 
630 }
631 db_finalize(&q);
632 blob_appendf(&json,"]\n");
633 cgi_set_content(&json);
634 }
635
+2
--- src/wiki.c
+++ src/wiki.c
@@ -219,10 +219,11 @@
219219
style_submenu_element("Formatted", "%R/md_rules");
220220
}else{
221221
style_submenu_element("Plain-Text", "%R/md_rules?txt=1");
222222
}
223223
blob_init(&x, builtin_text("markdown.md"), -1);
224
+ blob_materialize(&x);
224225
wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown");
225226
blob_reset(&x);
226227
style_footer();
227228
}
228229
@@ -239,10 +240,11 @@
239240
style_submenu_element("Formatted", "%R/wiki_rules");
240241
}else{
241242
style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
242243
}
243244
blob_init(&x, builtin_text("wiki.wiki"), -1);
245
+ blob_materialize(&x);
244246
wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki");
245247
blob_reset(&x);
246248
style_footer();
247249
}
248250
249251
--- src/wiki.c
+++ src/wiki.c
@@ -219,10 +219,11 @@
219 style_submenu_element("Formatted", "%R/md_rules");
220 }else{
221 style_submenu_element("Plain-Text", "%R/md_rules?txt=1");
222 }
223 blob_init(&x, builtin_text("markdown.md"), -1);
 
224 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown");
225 blob_reset(&x);
226 style_footer();
227 }
228
@@ -239,10 +240,11 @@
239 style_submenu_element("Formatted", "%R/wiki_rules");
240 }else{
241 style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
242 }
243 blob_init(&x, builtin_text("wiki.wiki"), -1);
 
244 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki");
245 blob_reset(&x);
246 style_footer();
247 }
248
249
--- src/wiki.c
+++ src/wiki.c
@@ -219,10 +219,11 @@
219 style_submenu_element("Formatted", "%R/md_rules");
220 }else{
221 style_submenu_element("Plain-Text", "%R/md_rules?txt=1");
222 }
223 blob_init(&x, builtin_text("markdown.md"), -1);
224 blob_materialize(&x);
225 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown");
226 blob_reset(&x);
227 style_footer();
228 }
229
@@ -239,10 +240,11 @@
240 style_submenu_element("Formatted", "%R/wiki_rules");
241 }else{
242 style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
243 }
244 blob_init(&x, builtin_text("wiki.wiki"), -1);
245 blob_materialize(&x);
246 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki");
247 blob_reset(&x);
248 style_footer();
249 }
250
251
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -158,13 +158,13 @@
158158
ZLIBCONFIG =
159159
ZLIBTARGETS =
160160
endif
161161
162162
#### Disable creation of the OpenSSL shared libraries. Also, disable support
163
-# for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
163
+# for SSLv3 (i.e. thereby forcing the use of TLS).
164164
#
165
-SSLCONFIG += no-ssl2 no-ssl3 no-weak-ssl-ciphers no-shared
165
+SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared
166166
167167
#### When using zlib, make sure that OpenSSL is configured to use the zlib
168168
# that Fossil knows about (i.e. the one within the source tree).
169169
#
170170
ifndef FOSSIL_ENABLE_MINIZ
@@ -174,11 +174,11 @@
174174
#### The directories where the OpenSSL include and library files are located.
175175
# The recommended usage here is to use the Sysinternals junction tool
176176
# to create a hard link between an "openssl-1.x" sub-directory of the
177177
# Fossil source code directory and the target OpenSSL source directory.
178178
#
179
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2r
179
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1b
180180
OPENSSLINCDIR = $(OPENSSLDIR)/include
181181
OPENSSLLIBDIR = $(OPENSSLDIR)
182182
183183
#### Either the directory where the Tcl library is installed or the Tcl
184184
# source code directory resides (depending on the value of the macro
@@ -1095,10 +1095,11 @@
10951095
BLDTARGETS = zlib
10961096
endif
10971097
10981098
openssl: $(BLDTARGETS)
10991099
cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
1100
+ sed -i -e 's/^PERL=C:\\.*$$/PERL=perl.exe/i' $(OPENSSLLIBDIR)/Makefile
11001101
$(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
11011102
11021103
clean-openssl:
11031104
$(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
11041105
11051106
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -158,13 +158,13 @@
158 ZLIBCONFIG =
159 ZLIBTARGETS =
160 endif
161
162 #### Disable creation of the OpenSSL shared libraries. Also, disable support
163 # for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
164 #
165 SSLCONFIG += no-ssl2 no-ssl3 no-weak-ssl-ciphers no-shared
166
167 #### When using zlib, make sure that OpenSSL is configured to use the zlib
168 # that Fossil knows about (i.e. the one within the source tree).
169 #
170 ifndef FOSSIL_ENABLE_MINIZ
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2r
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -1095,10 +1095,11 @@
1095 BLDTARGETS = zlib
1096 endif
1097
1098 openssl: $(BLDTARGETS)
1099 cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
 
1100 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
1101
1102 clean-openssl:
1103 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
1104
1105
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -158,13 +158,13 @@
158 ZLIBCONFIG =
159 ZLIBTARGETS =
160 endif
161
162 #### Disable creation of the OpenSSL shared libraries. Also, disable support
163 # for SSLv3 (i.e. thereby forcing the use of TLS).
164 #
165 SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared
166
167 #### When using zlib, make sure that OpenSSL is configured to use the zlib
168 # that Fossil knows about (i.e. the one within the source tree).
169 #
170 ifndef FOSSIL_ENABLE_MINIZ
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1b
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -1095,10 +1095,11 @@
1095 BLDTARGETS = zlib
1096 endif
1097
1098 openssl: $(BLDTARGETS)
1099 cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
1100 sed -i -e 's/^PERL=C:\\.*$$/PERL=perl.exe/i' $(OPENSSLLIBDIR)/Makefile
1101 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
1102
1103 clean-openssl:
1104 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
1105
1106
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -158,13 +158,13 @@
158158
ZLIBCONFIG =
159159
ZLIBTARGETS =
160160
endif
161161
162162
#### Disable creation of the OpenSSL shared libraries. Also, disable support
163
-# for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
163
+# for SSLv3 (i.e. thereby forcing the use of TLS).
164164
#
165
-SSLCONFIG += no-ssl2 no-ssl3 no-weak-ssl-ciphers no-shared
165
+SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared
166166
167167
#### When using zlib, make sure that OpenSSL is configured to use the zlib
168168
# that Fossil knows about (i.e. the one within the source tree).
169169
#
170170
ifndef FOSSIL_ENABLE_MINIZ
@@ -174,11 +174,11 @@
174174
#### The directories where the OpenSSL include and library files are located.
175175
# The recommended usage here is to use the Sysinternals junction tool
176176
# to create a hard link between an "openssl-1.x" sub-directory of the
177177
# Fossil source code directory and the target OpenSSL source directory.
178178
#
179
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2r
179
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1b
180180
OPENSSLINCDIR = $(OPENSSLDIR)/include
181181
OPENSSLLIBDIR = $(OPENSSLDIR)
182182
183183
#### Either the directory where the Tcl library is installed or the Tcl
184184
# source code directory resides (depending on the value of the macro
@@ -1095,10 +1095,11 @@
10951095
BLDTARGETS = zlib
10961096
endif
10971097
10981098
openssl: $(BLDTARGETS)
10991099
cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
1100
+ sed -i -e 's/^PERL=C:\\.*$$/PERL=perl.exe/i' $(OPENSSLLIBDIR)/Makefile
11001101
$(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
11011102
11021103
clean-openssl:
11031104
$(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
11041105
11051106
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -158,13 +158,13 @@
158 ZLIBCONFIG =
159 ZLIBTARGETS =
160 endif
161
162 #### Disable creation of the OpenSSL shared libraries. Also, disable support
163 # for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
164 #
165 SSLCONFIG += no-ssl2 no-ssl3 no-weak-ssl-ciphers no-shared
166
167 #### When using zlib, make sure that OpenSSL is configured to use the zlib
168 # that Fossil knows about (i.e. the one within the source tree).
169 #
170 ifndef FOSSIL_ENABLE_MINIZ
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2r
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -1095,10 +1095,11 @@
1095 BLDTARGETS = zlib
1096 endif
1097
1098 openssl: $(BLDTARGETS)
1099 cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
 
1100 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
1101
1102 clean-openssl:
1103 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
1104
1105
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -158,13 +158,13 @@
158 ZLIBCONFIG =
159 ZLIBTARGETS =
160 endif
161
162 #### Disable creation of the OpenSSL shared libraries. Also, disable support
163 # for SSLv3 (i.e. thereby forcing the use of TLS).
164 #
165 SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared
166
167 #### When using zlib, make sure that OpenSSL is configured to use the zlib
168 # that Fossil knows about (i.e. the one within the source tree).
169 #
170 ifndef FOSSIL_ENABLE_MINIZ
@@ -174,11 +174,11 @@
174 #### The directories where the OpenSSL include and library files are located.
175 # The recommended usage here is to use the Sysinternals junction tool
176 # to create a hard link between an "openssl-1.x" sub-directory of the
177 # Fossil source code directory and the target OpenSSL source directory.
178 #
179 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.1.1b
180 OPENSSLINCDIR = $(OPENSSLDIR)/include
181 OPENSSLLIBDIR = $(OPENSSLDIR)
182
183 #### Either the directory where the Tcl library is installed or the Tcl
184 # source code directory resides (depending on the value of the macro
@@ -1095,10 +1095,11 @@
1095 BLDTARGETS = zlib
1096 endif
1097
1098 openssl: $(BLDTARGETS)
1099 cd $(OPENSSLLIBDIR);./Configure --cross-compile-prefix=$(PREFIX) $(SSLCONFIG)
1100 sed -i -e 's/^PERL=C:\\.*$$/PERL=perl.exe/i' $(OPENSSLLIBDIR)/Makefile
1101 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) build_libs
1102
1103 clean-openssl:
1104 $(MAKE) -C $(OPENSSLLIBDIR) PREFIX=$(PREFIX) CC=$(PREFIX)$(TCCEXE) clean
1105
1106
+34 -71
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,78 +98,42 @@
9898
!ifndef USE_SEE
9999
USE_SEE = 0
100100
!endif
101101
102102
!if $(FOSSIL_ENABLE_SSL)!=0
103
-SSLDIR = $(B)\compat\openssl-1.0.2r
104
-SSLINCDIR = $(SSLDIR)\inc32
105
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
106
-SSLLIBDIR = $(SSLDIR)\out32dll
107
-!else
108
-SSLLIBDIR = $(SSLDIR)\out32
109
-!endif
110
-SSLLFLAGS = /nologo /opt:ref /debug
111
-SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib
112
-!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
113
-!message Using 'x64' platform for OpenSSL...
114
-# BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
115
-# SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
116
-SSLCONFIG = VC-WIN64A no-asm
117
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
118
-SSLCONFIG = $(SSLCONFIG) shared
119
-!else
120
-SSLCONFIG = $(SSLCONFIG) no-shared
121
-!endif
122
-SSLSETUP = ms\do_win64a.bat
123
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
124
-SSLNMAKE = ms\ntdll.mak all
125
-!else
126
-SSLNMAKE = ms\nt.mak all
127
-!endif
128
-# BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
129
-!if $(FOSSIL_DYNAMIC_BUILD)==0
130
-SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
131
-!endif
132
-!elseif "$(PLATFORM)"=="ia64"
133
-!message Using 'ia64' platform for OpenSSL...
134
-# BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
135
-# SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
136
-SSLCONFIG = VC-WIN64I no-asm
137
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
138
-SSLCONFIG = $(SSLCONFIG) shared
139
-!else
140
-SSLCONFIG = $(SSLCONFIG) no-shared
141
-!endif
142
-SSLSETUP = ms\do_win64i.bat
143
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
144
-SSLNMAKE = ms\ntdll.mak all
145
-!else
146
-SSLNMAKE = ms\nt.mak all
147
-!endif
148
-# BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
149
-!if $(FOSSIL_DYNAMIC_BUILD)==0
150
-SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
151
-!endif
152
-!else
153
-!message Assuming 'x86' platform for OpenSSL...
154
-# BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
155
-# SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
156
-SSLCONFIG = VC-WIN32 no-asm
157
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
158
-SSLCONFIG = $(SSLCONFIG) shared
159
-!else
160
-SSLCONFIG = $(SSLCONFIG) no-shared
161
-!endif
162
-SSLSETUP = ms\do_ms.bat
163
-!if $(FOSSIL_DYNAMIC_BUILD)!=0
164
-SSLNMAKE = ms\ntdll.mak all
165
-!else
166
-SSLNMAKE = ms\nt.mak all
167
-!endif
168
-# BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
169
-!if $(FOSSIL_DYNAMIC_BUILD)==0
170
-SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
103
+SSLDIR = $(B)\compat\openssl-1.1.1b
104
+SSLINCDIR = $(SSLDIR)\include
105
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
106
+SSLLIBDIR = $(SSLDIR)
107
+!else
108
+SSLLIBDIR = $(SSLDIR)
109
+!endif
110
+SSLLFLAGS = /nologo /opt:ref /debug
111
+SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
112
+!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
113
+!message Using 'x64' platform for OpenSSL...
114
+SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
115
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
116
+SSLCONFIG = $(SSLCONFIG) shared
117
+!else
118
+SSLCONFIG = $(SSLCONFIG) no-shared
119
+!endif
120
+!elseif "$(PLATFORM)"=="ia64"
121
+!message Using 'ia64' platform for OpenSSL...
122
+SSLCONFIG = VC-WIN64I no-asm no-ssl3 no-weak-ssl-ciphers
123
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
124
+SSLCONFIG = $(SSLCONFIG) shared
125
+!else
126
+SSLCONFIG = $(SSLCONFIG) no-shared
127
+!endif
128
+!else
129
+!message Assuming 'x86' platform for OpenSSL...
130
+SSLCONFIG = VC-WIN32 no-asm no-ssl3 no-weak-ssl-ciphers
131
+!if $(FOSSIL_DYNAMIC_BUILD)!=0
132
+SSLCONFIG = $(SSLCONFIG) shared
133
+!else
134
+SSLCONFIG = $(SSLCONFIG) no-shared
171135
!endif
172136
!endif
173137
!endif
174138
175139
!if $(FOSSIL_ENABLE_TCL)!=0
@@ -760,15 +724,14 @@
760724
@echo Building OpenSSL from "$(SSLDIR)"...
761725
!if "$(PERLDIR)" != ""
762726
@set PATH=$(PERLDIR);$(PATH)
763727
!endif
764728
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
765
- @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
766729
!if $(FOSSIL_ENABLE_WINXP)!=0
767
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
730
+ @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
768731
!else
769
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
732
+ @pushd "$(SSLDIR)" && $(MAKE) && popd
770733
!endif
771734
!endif
772735
773736
!if $(FOSSIL_ENABLE_MINIZ)==0
774737
!if $(FOSSIL_BUILD_ZLIB)!=0
775738
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,78 +98,42 @@
98 !ifndef USE_SEE
99 USE_SEE = 0
100 !endif
101
102 !if $(FOSSIL_ENABLE_SSL)!=0
103 SSLDIR = $(B)\compat\openssl-1.0.2r
104 SSLINCDIR = $(SSLDIR)\inc32
105 !if $(FOSSIL_DYNAMIC_BUILD)!=0
106 SSLLIBDIR = $(SSLDIR)\out32dll
107 !else
108 SSLLIBDIR = $(SSLDIR)\out32
109 !endif
110 SSLLFLAGS = /nologo /opt:ref /debug
111 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib
112 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
113 !message Using 'x64' platform for OpenSSL...
114 # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
115 # SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
116 SSLCONFIG = VC-WIN64A no-asm
117 !if $(FOSSIL_DYNAMIC_BUILD)!=0
118 SSLCONFIG = $(SSLCONFIG) shared
119 !else
120 SSLCONFIG = $(SSLCONFIG) no-shared
121 !endif
122 SSLSETUP = ms\do_win64a.bat
123 !if $(FOSSIL_DYNAMIC_BUILD)!=0
124 SSLNMAKE = ms\ntdll.mak all
125 !else
126 SSLNMAKE = ms\nt.mak all
127 !endif
128 # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
129 !if $(FOSSIL_DYNAMIC_BUILD)==0
130 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
131 !endif
132 !elseif "$(PLATFORM)"=="ia64"
133 !message Using 'ia64' platform for OpenSSL...
134 # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
135 # SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
136 SSLCONFIG = VC-WIN64I no-asm
137 !if $(FOSSIL_DYNAMIC_BUILD)!=0
138 SSLCONFIG = $(SSLCONFIG) shared
139 !else
140 SSLCONFIG = $(SSLCONFIG) no-shared
141 !endif
142 SSLSETUP = ms\do_win64i.bat
143 !if $(FOSSIL_DYNAMIC_BUILD)!=0
144 SSLNMAKE = ms\ntdll.mak all
145 !else
146 SSLNMAKE = ms\nt.mak all
147 !endif
148 # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
149 !if $(FOSSIL_DYNAMIC_BUILD)==0
150 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
151 !endif
152 !else
153 !message Assuming 'x86' platform for OpenSSL...
154 # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build.
155 # SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-weak-ssl-ciphers
156 SSLCONFIG = VC-WIN32 no-asm
157 !if $(FOSSIL_DYNAMIC_BUILD)!=0
158 SSLCONFIG = $(SSLCONFIG) shared
159 !else
160 SSLCONFIG = $(SSLCONFIG) no-shared
161 !endif
162 SSLSETUP = ms\do_ms.bat
163 !if $(FOSSIL_DYNAMIC_BUILD)!=0
164 SSLNMAKE = ms\ntdll.mak all
165 !else
166 SSLNMAKE = ms\nt.mak all
167 !endif
168 # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds.
169 !if $(FOSSIL_DYNAMIC_BUILD)==0
170 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS
171 !endif
172 !endif
173 !endif
174
175 !if $(FOSSIL_ENABLE_TCL)!=0
@@ -760,15 +724,14 @@
760 @echo Building OpenSSL from "$(SSLDIR)"...
761 !if "$(PERLDIR)" != ""
762 @set PATH=$(PERLDIR);$(PATH)
763 !endif
764 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
765 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
766 !if $(FOSSIL_ENABLE_WINXP)!=0
767 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
768 !else
769 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
770 !endif
771 !endif
772
773 !if $(FOSSIL_ENABLE_MINIZ)==0
774 !if $(FOSSIL_BUILD_ZLIB)!=0
775
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -98,78 +98,42 @@
98 !ifndef USE_SEE
99 USE_SEE = 0
100 !endif
101
102 !if $(FOSSIL_ENABLE_SSL)!=0
103 SSLDIR = $(B)\compat\openssl-1.1.1b
104 SSLINCDIR = $(SSLDIR)\include
105 !if $(FOSSIL_DYNAMIC_BUILD)!=0
106 SSLLIBDIR = $(SSLDIR)
107 !else
108 SSLLIBDIR = $(SSLDIR)
109 !endif
110 SSLLFLAGS = /nologo /opt:ref /debug
111 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
112 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
113 !message Using 'x64' platform for OpenSSL...
114 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
115 !if $(FOSSIL_DYNAMIC_BUILD)!=0
116 SSLCONFIG = $(SSLCONFIG) shared
117 !else
118 SSLCONFIG = $(SSLCONFIG) no-shared
119 !endif
120 !elseif "$(PLATFORM)"=="ia64"
121 !message Using 'ia64' platform for OpenSSL...
122 SSLCONFIG = VC-WIN64I no-asm no-ssl3 no-weak-ssl-ciphers
123 !if $(FOSSIL_DYNAMIC_BUILD)!=0
124 SSLCONFIG = $(SSLCONFIG) shared
125 !else
126 SSLCONFIG = $(SSLCONFIG) no-shared
127 !endif
128 !else
129 !message Assuming 'x86' platform for OpenSSL...
130 SSLCONFIG = VC-WIN32 no-asm no-ssl3 no-weak-ssl-ciphers
131 !if $(FOSSIL_DYNAMIC_BUILD)!=0
132 SSLCONFIG = $(SSLCONFIG) shared
133 !else
134 SSLCONFIG = $(SSLCONFIG) no-shared
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135 !endif
136 !endif
137 !endif
138
139 !if $(FOSSIL_ENABLE_TCL)!=0
@@ -760,15 +724,14 @@
724 @echo Building OpenSSL from "$(SSLDIR)"...
725 !if "$(PERLDIR)" != ""
726 @set PATH=$(PERLDIR);$(PATH)
727 !endif
728 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
 
729 !if $(FOSSIL_ENABLE_WINXP)!=0
730 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
731 !else
732 @pushd "$(SSLDIR)" && $(MAKE) && popd
733 !endif
734 !endif
735
736 !if $(FOSSIL_ENABLE_MINIZ)==0
737 !if $(FOSSIL_BUILD_ZLIB)!=0
738
+1 -1
--- www/build.wiki
+++ www/build.wiki
@@ -161,11 +161,11 @@
161161
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
162162
first <a href="https://www.openssl.org/source/">download the official
163163
source code for OpenSSL</a> and extract it to an appropriately named
164164
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
165165
[/tree?ci=trunk&name=compat | compat] directory (e.g.
166
-"<b>compat/openssl-1.0.2r</b>"), then make sure that some recent
166
+"<b>compat/openssl-1.1.1b</b>"), then make sure that some recent
167167
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
168168
and finally run one of the following commands:
169169
<blockquote><pre>
170170
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
171171
</pre></blockquote>
172172
--- www/build.wiki
+++ www/build.wiki
@@ -161,11 +161,11 @@
161 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
162 first <a href="https://www.openssl.org/source/">download the official
163 source code for OpenSSL</a> and extract it to an appropriately named
164 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
165 [/tree?ci=trunk&name=compat | compat] directory (e.g.
166 "<b>compat/openssl-1.0.2r</b>"), then make sure that some recent
167 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
168 and finally run one of the following commands:
169 <blockquote><pre>
170 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
171 </pre></blockquote>
172
--- www/build.wiki
+++ www/build.wiki
@@ -161,11 +161,11 @@
161 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
162 first <a href="https://www.openssl.org/source/">download the official
163 source code for OpenSSL</a> and extract it to an appropriately named
164 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
165 [/tree?ci=trunk&name=compat | compat] directory (e.g.
166 "<b>compat/openssl-1.1.1b</b>"), then make sure that some recent
167 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
168 and finally run one of the following commands:
169 <blockquote><pre>
170 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
171 </pre></blockquote>
172
+25 -1
--- www/changes.wiki
+++ www/changes.wiki
@@ -8,23 +8,47 @@
88
* Improved handling of relative hyperlinks on the
99
[/help?cmd=/artifact|/artifact] pages for wiki. For example,
1010
hyperlinks and the lizard &lt;img&gt; now work correctly
1111
for both [/artifact/2ff24ab0887cf522] and
1212
[/doc/0d7ac90d575004c2415/www/index.wiki].
13
+ * Many documentation enhancements.
1314
* For the "[/help?cmd=update|fossil update]" and
1415
"[/help?cmd=checkout|fossil checkout]" commands, if a
1516
managed file is removed because it is no longer part of the target
1617
check-in and the directory containing the file is empty after the
1718
file is removed and the directory is not the current working
1819
directory and is not on the [/help?cmd=empty-dirs|empty-dirs]
1920
list, then also remove the directory.
2021
* Update internal Unicode character tables, used in regular expression
21
- handling, from version 11.0 to 12.0.
22
+ handling, from version 11.0 to 12.1.
2223
* In "[/help?cmd=regexp|fossil regexp]", "[/help?cmd=grep|fossil grep]"
2324
and the TH1 "regexp" command, the -nocase option now removes multiple
2425
diacritics from the same character (derived from SQLite's
2526
remove_diacritics=2)
27
+ * Added the [/help?cmd=/secureraw|/secureraw] page that requires the
28
+ complete SHA1 or SHA3 hash, not just a prefix, before it will deliver
29
+ content.
30
+ * Accept purely numeric ISO8601 date/time strings as long as they
31
+ do not conflict with a hash. Example: "20190510134217" instead of
32
+ "2019-05-10 13:42:17". This is very useful for query parameters.
33
+ * Support both "1)" and "1." for numbered lists in markdown, as
34
+ commonmark does.
35
+ * The sync and clone HTTP requests omit the extra /xfer path element
36
+ from the end of the request URI. All servers since 2010 know that
37
+ the HTTP request is for a sync or clone from the mimetype so the
38
+ extra path element is not needed.
39
+ * If an automatic sync gets a 301 or 302 redirect request, then update
40
+ the saved remote URL to the new address.
41
+ * Temporary filenames (for example used for external "diff" commands)
42
+ try to preserve the suffix of the original file.
43
+ * Added the [/help?cmd=/thisdayinhistory|/thisdayinhistory] web page.
44
+ * Enhanced parsing of [/help?cmd=/timeline|/timeline] query parameters
45
+ "ymd=", "ym=", and "yw=". All arguments are option (in which case they
46
+ default to the current time) and all accept ISO8601 date/times without
47
+ punctuation.
48
+ * Improvements to the "Capability Summary" section in the
49
+ [/help?cmd=/secaudit0|Security Audit] web-page.
2650
2751
<a name='v2_8'></a>
2852
<h2>Changes for Version 2.8 (2019-02-20)</h2>
2953
3054
* Show cherry-pick merges as dotted lines on the timeline graph.
3155
--- www/changes.wiki
+++ www/changes.wiki
@@ -8,23 +8,47 @@
8 * Improved handling of relative hyperlinks on the
9 [/help?cmd=/artifact|/artifact] pages for wiki. For example,
10 hyperlinks and the lizard &lt;img&gt; now work correctly
11 for both [/artifact/2ff24ab0887cf522] and
12 [/doc/0d7ac90d575004c2415/www/index.wiki].
 
13 * For the "[/help?cmd=update|fossil update]" and
14 "[/help?cmd=checkout|fossil checkout]" commands, if a
15 managed file is removed because it is no longer part of the target
16 check-in and the directory containing the file is empty after the
17 file is removed and the directory is not the current working
18 directory and is not on the [/help?cmd=empty-dirs|empty-dirs]
19 list, then also remove the directory.
20 * Update internal Unicode character tables, used in regular expression
21 handling, from version 11.0 to 12.0.
22 * In "[/help?cmd=regexp|fossil regexp]", "[/help?cmd=grep|fossil grep]"
23 and the TH1 "regexp" command, the -nocase option now removes multiple
24 diacritics from the same character (derived from SQLite's
25 remove_diacritics=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
27 <a name='v2_8'></a>
28 <h2>Changes for Version 2.8 (2019-02-20)</h2>
29
30 * Show cherry-pick merges as dotted lines on the timeline graph.
31
--- www/changes.wiki
+++ www/changes.wiki
@@ -8,23 +8,47 @@
8 * Improved handling of relative hyperlinks on the
9 [/help?cmd=/artifact|/artifact] pages for wiki. For example,
10 hyperlinks and the lizard &lt;img&gt; now work correctly
11 for both [/artifact/2ff24ab0887cf522] and
12 [/doc/0d7ac90d575004c2415/www/index.wiki].
13 * Many documentation enhancements.
14 * For the "[/help?cmd=update|fossil update]" and
15 "[/help?cmd=checkout|fossil checkout]" commands, if a
16 managed file is removed because it is no longer part of the target
17 check-in and the directory containing the file is empty after the
18 file is removed and the directory is not the current working
19 directory and is not on the [/help?cmd=empty-dirs|empty-dirs]
20 list, then also remove the directory.
21 * Update internal Unicode character tables, used in regular expression
22 handling, from version 11.0 to 12.1.
23 * In "[/help?cmd=regexp|fossil regexp]", "[/help?cmd=grep|fossil grep]"
24 and the TH1 "regexp" command, the -nocase option now removes multiple
25 diacritics from the same character (derived from SQLite's
26 remove_diacritics=2)
27 * Added the [/help?cmd=/secureraw|/secureraw] page that requires the
28 complete SHA1 or SHA3 hash, not just a prefix, before it will deliver
29 content.
30 * Accept purely numeric ISO8601 date/time strings as long as they
31 do not conflict with a hash. Example: "20190510134217" instead of
32 "2019-05-10 13:42:17". This is very useful for query parameters.
33 * Support both "1)" and "1." for numbered lists in markdown, as
34 commonmark does.
35 * The sync and clone HTTP requests omit the extra /xfer path element
36 from the end of the request URI. All servers since 2010 know that
37 the HTTP request is for a sync or clone from the mimetype so the
38 extra path element is not needed.
39 * If an automatic sync gets a 301 or 302 redirect request, then update
40 the saved remote URL to the new address.
41 * Temporary filenames (for example used for external "diff" commands)
42 try to preserve the suffix of the original file.
43 * Added the [/help?cmd=/thisdayinhistory|/thisdayinhistory] web page.
44 * Enhanced parsing of [/help?cmd=/timeline|/timeline] query parameters
45 "ymd=", "ym=", and "yw=". All arguments are option (in which case they
46 default to the current time) and all accept ISO8601 date/times without
47 punctuation.
48 * Improvements to the "Capability Summary" section in the
49 [/help?cmd=/secaudit0|Security Audit] web-page.
50
51 <a name='v2_8'></a>
52 <h2>Changes for Version 2.8 (2019-02-20)</h2>
53
54 * Show cherry-pick merges as dotted lines on the timeline graph.
55
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -142,21 +142,27 @@
142142
<h2>Timestamps</h2>
143143
144144
A timestamp in one of the formats shown below means the most recent
145145
check-in that occurs no later than the timestamp given:
146146
147
- * <i>YYYY-MM-DD</i>
148
- * <i>YYYY-MM-DD HH:MM</i>
149
- * <i>YYYY-MM-DD HH:MM:SS</i>
150
- * <i>YYYY-MM-DD HH:MM:SS.SSS</i>
147
+ 1. <i>YYYY-MM-DD</i>
148
+ 2. <i>YYYY-MM-DD HH:MM</i>
149
+ 3. <i>YYYY-MM-DD HH:MM:SS</i>
150
+ 4. <i>YYYY-MM-DD HH:MM:SS.SSS</i>
151
+ 5. <i>YYYYMMDD</i>
152
+ 6. <i>YYYYMMDDHHMM</i>
153
+ 7. <i>YYYYMMDDHHMMSS</i>
151154
152
-The space between the day and the year can optionally be
155
+In the second through the fourth forms,
156
+the space between the day and the year can optionally be
153157
replaced by an uppercase <b>T</b> and the entire timestamp can
154158
optionally be followed by "<b>z</b>" or "<b>Z</b>". In the fourth
155159
form with fractional seconds, any number of digits may follow the
156160
decimal point, though due to precision limits only the first three
157
-digits will be significant.
161
+digits will be significant. The final three pure-digit forms
162
+without punctuation are only valid if the number they encode is
163
+not also the prefix of an artifact hash.
158164
159165
In its default configuration, Fossil interprets and displays all dates
160166
in Universal Coordinated Time (UTC). This tends to work the best for
161167
distributed projects where participants are scattered around the globe.
162168
But there is an option on the Admin/Timeline page of the web-interface to
163169
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -142,21 +142,27 @@
142 <h2>Timestamps</h2>
143
144 A timestamp in one of the formats shown below means the most recent
145 check-in that occurs no later than the timestamp given:
146
147 * <i>YYYY-MM-DD</i>
148 * <i>YYYY-MM-DD HH:MM</i>
149 * <i>YYYY-MM-DD HH:MM:SS</i>
150 * <i>YYYY-MM-DD HH:MM:SS.SSS</i>
 
 
 
151
152 The space between the day and the year can optionally be
 
153 replaced by an uppercase <b>T</b> and the entire timestamp can
154 optionally be followed by "<b>z</b>" or "<b>Z</b>". In the fourth
155 form with fractional seconds, any number of digits may follow the
156 decimal point, though due to precision limits only the first three
157 digits will be significant.
 
 
158
159 In its default configuration, Fossil interprets and displays all dates
160 in Universal Coordinated Time (UTC). This tends to work the best for
161 distributed projects where participants are scattered around the globe.
162 But there is an option on the Admin/Timeline page of the web-interface to
163
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -142,21 +142,27 @@
142 <h2>Timestamps</h2>
143
144 A timestamp in one of the formats shown below means the most recent
145 check-in that occurs no later than the timestamp given:
146
147 1. <i>YYYY-MM-DD</i>
148 2. <i>YYYY-MM-DD HH:MM</i>
149 3. <i>YYYY-MM-DD HH:MM:SS</i>
150 4. <i>YYYY-MM-DD HH:MM:SS.SSS</i>
151 5. <i>YYYYMMDD</i>
152 6. <i>YYYYMMDDHHMM</i>
153 7. <i>YYYYMMDDHHMMSS</i>
154
155 In the second through the fourth forms,
156 the space between the day and the year can optionally be
157 replaced by an uppercase <b>T</b> and the entire timestamp can
158 optionally be followed by "<b>z</b>" or "<b>Z</b>". In the fourth
159 form with fractional seconds, any number of digits may follow the
160 decimal point, though due to precision limits only the first three
161 digits will be significant. The final three pure-digit forms
162 without punctuation are only valid if the number they encode is
163 not also the prefix of an artifact hash.
164
165 In its default configuration, Fossil interprets and displays all dates
166 in Universal Coordinated Time (UTC). This tends to work the best for
167 distributed projects where participants are scattered around the globe.
168 But there is an option on the Admin/Timeline page of the web-interface to
169
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -25,16 +25,18 @@
2525
with further description in the text that follows.
2626
2727
<blockquote><table border=1 cellpadding=5 align=center>
2828
<tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
2929
<tr><td>File versioning only</td>
30
- <td>Versioning, Tickets, Wiki, and Technotes</td></tr>
30
+ <td>Versioning, Tickets, Wiki, Technotes, Forum</td></tr>
3131
<tr><td>Ad-hoc, pile-of-files key/value database</td>
3232
<td>Relational SQL database</td></tr>
3333
<tr><td>Bazaar-style development</td><td>Cathedral-style development</td></tr>
3434
<tr><td>Designed for Linux development</td>
3535
<td>Designed for SQLite development</td></tr>
36
+<tr><td>Focus on individual branches</td>
37
+ <td>Focus on the entire tree of changes</td></tr>
3638
<tr><td>Lots of little tools</td><td>Stand-alone executable</td></tr>
3739
<tr><td>One check-out per repository</td>
3840
<td>Many check-outs per repository</td></tr>
3941
<tr><td>Remembers what you should have done</td>
4042
<td>Remembers what you actually did</td></tr>
@@ -44,12 +46,12 @@
4446
<h3>2.1 Feature Set</h3>
4547
4648
Git provides file versioning services only, whereas Fossil adds
4749
integrated [./wikitheory.wiki | wiki],
4850
[./bugtheory.wiki | ticketing &amp; bug tracking],
49
-[./embeddeddoc.wiki | embedded documentation], and
50
-[./event.wiki | Technical notes].
51
+[./embeddeddoc.wiki | embedded documentation],
52
+[./event.wiki | Technical notes], and a [./forum.wiki | forum].
5153
These additional capabilities are available for Git as 3rd-party and/or
5254
user-installed add-ons, but with Fossil they are integrated into
5355
the design. One way to describe Fossil is that it is
5456
"[https://github.com/ | github]-in-a-box".
5557
@@ -159,11 +161,39 @@
159161
SQLite uses cathedral-style development. 95% of the code in SQLite
160162
comes from just three programmers, 64% from just the lead developer.
161163
And all SQLite developers know each other well and interact daily.
162164
Fossil is designed for this development model.
163165
164
-<h3>2.5 Lots of little tools vs. Self-contained system</h3>
166
+<h3>2.5 Individual Branches vs. The Entire Change History</h3>
167
+
168
+Both Fossil and Git store history as a directed acyclic graph (DAG)
169
+of changes. But Git tends to focus more on individual branches of
170
+the DAG, whereas Fossil puts more emphasis on the entire DAG.
171
+
172
+For example, the default "sync" behavior in Git is to only sync
173
+a single branch, whereas with Fossil the only sync option it to
174
+sync the entire DAG. Git commands, and Git web interfaces such as
175
+GitHub and/or GitLab, tend to show only a single branch at
176
+a time, whereas Fossil usually shows all parallel branches all at
177
+once. Git has commands like "rebase" that help keep all relevant
178
+changes on a single branch, whereas Fossil encourages a style of
179
+many concurrent branches constantly springing into existance,
180
+undergoing active development in parallel for a few days or weeks, then
181
+merging back into the main line and disappearing.
182
+
183
+This difference in emphasis arises from the different purposes of
184
+the two systems. Git focuses on individual branches, because that
185
+is exactly what you want for a highly-distributed bazaar-style project
186
+such as Linux. Linus Torvalds does not want to see every check-in
187
+by every contributor to Linux, as such extreme visibility does not scale
188
+well. But Fossil was written for the cathedral-style SQLite project
189
+with just a handful of active committers. Seeing all
190
+changes on all branches all at once helps keep the whole team
191
+up-to-date with what everybody else is doing, resulting in a more
192
+tightly focused and cohesive implementation.
193
+
194
+<h3>2.6 Lots of little tools vs. Self-contained system</h3>
165195
166196
Git consists of many small tools, each doing one small part of the job,
167197
which can be recombined (by experts) to perform powerful operations.
168198
Git has a lot of complexity and many dependencies and requires an "installer"
169199
script or program to get it running.
@@ -177,11 +207,11 @@
177207
small tools that collaborate to get the job done. The designer of
178208
Fossil says that the unix philosophy is "it just works". Both
179209
individuals have written their DVCSes to reflect their own view
180210
of the "unix philosophy".
181211
182
-<h3>2.6 One vs. Many Check-outs per Repository</h3>
212
+<h3>2.7 One vs. Many Check-outs per Repository</h3>
183213
184214
A "repository" in Git is a pile-of-files in the ".git" subdirectory
185215
of a single check-out. The check-out and the repository are located
186216
together in the filesystem.
187217
@@ -198,11 +228,11 @@
198228
"[https://git-scm.com/docs/git-worktree|worktree]" command that
199229
allows a single repository to host multiple check-outs. However,
200230
the interface is sufficiently difficult to use that most people
201231
find it easier to create a separate clone for each check-out.
202232
203
-<h3>2.7 What you should have done vs. What you actually did</h3>
233
+<h3>2.8 What you should have done vs. What you actually did</h3>
204234
205235
Git puts a lot of emphasis on maintaining
206236
a "clean" check-in history. Extraneous and experimental branches by
207237
individual developers often never make it into the main repository. And
208238
branches are often rebased before being pushed, to make
@@ -219,11 +249,11 @@
219249
is not a factor.
220250
221251
One commentator has mused that Git records history according to
222252
the victors, whereas Fossil records history as it actually happened.
223253
224
-<h3>2.8 GPL vs. BSD</h3>
254
+<h3>2.9 GPL vs. BSD</h3>
225255
226256
Git is covered by the GPL license whereas Fossil is covered by
227257
a two-clause BSD license.
228258
229259
Consider the difference between GPL and BSD licenses: GPL is designed
@@ -275,14 +305,14 @@
275305
Both Git and Fossil can easily find the ancestors of a check-in. But
276306
only Fossil shows the descendents. (It is possible to find the
277307
descendents of a check-in in Git using the log, but that is sufficiently
278308
difficult that nobody ever actually does it.)
279309
280
- * <b>Wiki, Embedded documentation, Trouble-tickets, and Tech-Notes</b>
310
+ * <b>Wiki, Embedded documentation, Trouble-tickets, Tech-Notes, and Forum</b>
281311
282312
Git only provides versioning of source code. Fossil strives to provide
283
- other related configuration management services as well.
313
+ other related project management services as well.
284314
285315
* <b>Named branches</b>
286316
287317
Branches in Fossil have persistent names that are propagated
288318
to collaborators via [/help?cmd=push|push] and [/help?cmd=pull|pull].
289319
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -25,16 +25,18 @@
25 with further description in the text that follows.
26
27 <blockquote><table border=1 cellpadding=5 align=center>
28 <tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
29 <tr><td>File versioning only</td>
30 <td>Versioning, Tickets, Wiki, and Technotes</td></tr>
31 <tr><td>Ad-hoc, pile-of-files key/value database</td>
32 <td>Relational SQL database</td></tr>
33 <tr><td>Bazaar-style development</td><td>Cathedral-style development</td></tr>
34 <tr><td>Designed for Linux development</td>
35 <td>Designed for SQLite development</td></tr>
 
 
36 <tr><td>Lots of little tools</td><td>Stand-alone executable</td></tr>
37 <tr><td>One check-out per repository</td>
38 <td>Many check-outs per repository</td></tr>
39 <tr><td>Remembers what you should have done</td>
40 <td>Remembers what you actually did</td></tr>
@@ -44,12 +46,12 @@
44 <h3>2.1 Feature Set</h3>
45
46 Git provides file versioning services only, whereas Fossil adds
47 integrated [./wikitheory.wiki | wiki],
48 [./bugtheory.wiki | ticketing &amp; bug tracking],
49 [./embeddeddoc.wiki | embedded documentation], and
50 [./event.wiki | Technical notes].
51 These additional capabilities are available for Git as 3rd-party and/or
52 user-installed add-ons, but with Fossil they are integrated into
53 the design. One way to describe Fossil is that it is
54 "[https://github.com/ | github]-in-a-box".
55
@@ -159,11 +161,39 @@
159 SQLite uses cathedral-style development. 95% of the code in SQLite
160 comes from just three programmers, 64% from just the lead developer.
161 And all SQLite developers know each other well and interact daily.
162 Fossil is designed for this development model.
163
164 <h3>2.5 Lots of little tools vs. Self-contained system</h3>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
166 Git consists of many small tools, each doing one small part of the job,
167 which can be recombined (by experts) to perform powerful operations.
168 Git has a lot of complexity and many dependencies and requires an "installer"
169 script or program to get it running.
@@ -177,11 +207,11 @@
177 small tools that collaborate to get the job done. The designer of
178 Fossil says that the unix philosophy is "it just works". Both
179 individuals have written their DVCSes to reflect their own view
180 of the "unix philosophy".
181
182 <h3>2.6 One vs. Many Check-outs per Repository</h3>
183
184 A "repository" in Git is a pile-of-files in the ".git" subdirectory
185 of a single check-out. The check-out and the repository are located
186 together in the filesystem.
187
@@ -198,11 +228,11 @@
198 "[https://git-scm.com/docs/git-worktree|worktree]" command that
199 allows a single repository to host multiple check-outs. However,
200 the interface is sufficiently difficult to use that most people
201 find it easier to create a separate clone for each check-out.
202
203 <h3>2.7 What you should have done vs. What you actually did</h3>
204
205 Git puts a lot of emphasis on maintaining
206 a "clean" check-in history. Extraneous and experimental branches by
207 individual developers often never make it into the main repository. And
208 branches are often rebased before being pushed, to make
@@ -219,11 +249,11 @@
219 is not a factor.
220
221 One commentator has mused that Git records history according to
222 the victors, whereas Fossil records history as it actually happened.
223
224 <h3>2.8 GPL vs. BSD</h3>
225
226 Git is covered by the GPL license whereas Fossil is covered by
227 a two-clause BSD license.
228
229 Consider the difference between GPL and BSD licenses: GPL is designed
@@ -275,14 +305,14 @@
275 Both Git and Fossil can easily find the ancestors of a check-in. But
276 only Fossil shows the descendents. (It is possible to find the
277 descendents of a check-in in Git using the log, but that is sufficiently
278 difficult that nobody ever actually does it.)
279
280 * <b>Wiki, Embedded documentation, Trouble-tickets, and Tech-Notes</b>
281
282 Git only provides versioning of source code. Fossil strives to provide
283 other related configuration management services as well.
284
285 * <b>Named branches</b>
286
287 Branches in Fossil have persistent names that are propagated
288 to collaborators via [/help?cmd=push|push] and [/help?cmd=pull|pull].
289
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -25,16 +25,18 @@
25 with further description in the text that follows.
26
27 <blockquote><table border=1 cellpadding=5 align=center>
28 <tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
29 <tr><td>File versioning only</td>
30 <td>Versioning, Tickets, Wiki, Technotes, Forum</td></tr>
31 <tr><td>Ad-hoc, pile-of-files key/value database</td>
32 <td>Relational SQL database</td></tr>
33 <tr><td>Bazaar-style development</td><td>Cathedral-style development</td></tr>
34 <tr><td>Designed for Linux development</td>
35 <td>Designed for SQLite development</td></tr>
36 <tr><td>Focus on individual branches</td>
37 <td>Focus on the entire tree of changes</td></tr>
38 <tr><td>Lots of little tools</td><td>Stand-alone executable</td></tr>
39 <tr><td>One check-out per repository</td>
40 <td>Many check-outs per repository</td></tr>
41 <tr><td>Remembers what you should have done</td>
42 <td>Remembers what you actually did</td></tr>
@@ -44,12 +46,12 @@
46 <h3>2.1 Feature Set</h3>
47
48 Git provides file versioning services only, whereas Fossil adds
49 integrated [./wikitheory.wiki | wiki],
50 [./bugtheory.wiki | ticketing &amp; bug tracking],
51 [./embeddeddoc.wiki | embedded documentation],
52 [./event.wiki | Technical notes], and a [./forum.wiki | forum].
53 These additional capabilities are available for Git as 3rd-party and/or
54 user-installed add-ons, but with Fossil they are integrated into
55 the design. One way to describe Fossil is that it is
56 "[https://github.com/ | github]-in-a-box".
57
@@ -159,11 +161,39 @@
161 SQLite uses cathedral-style development. 95% of the code in SQLite
162 comes from just three programmers, 64% from just the lead developer.
163 And all SQLite developers know each other well and interact daily.
164 Fossil is designed for this development model.
165
166 <h3>2.5 Individual Branches vs. The Entire Change History</h3>
167
168 Both Fossil and Git store history as a directed acyclic graph (DAG)
169 of changes. But Git tends to focus more on individual branches of
170 the DAG, whereas Fossil puts more emphasis on the entire DAG.
171
172 For example, the default "sync" behavior in Git is to only sync
173 a single branch, whereas with Fossil the only sync option it to
174 sync the entire DAG. Git commands, and Git web interfaces such as
175 GitHub and/or GitLab, tend to show only a single branch at
176 a time, whereas Fossil usually shows all parallel branches all at
177 once. Git has commands like "rebase" that help keep all relevant
178 changes on a single branch, whereas Fossil encourages a style of
179 many concurrent branches constantly springing into existance,
180 undergoing active development in parallel for a few days or weeks, then
181 merging back into the main line and disappearing.
182
183 This difference in emphasis arises from the different purposes of
184 the two systems. Git focuses on individual branches, because that
185 is exactly what you want for a highly-distributed bazaar-style project
186 such as Linux. Linus Torvalds does not want to see every check-in
187 by every contributor to Linux, as such extreme visibility does not scale
188 well. But Fossil was written for the cathedral-style SQLite project
189 with just a handful of active committers. Seeing all
190 changes on all branches all at once helps keep the whole team
191 up-to-date with what everybody else is doing, resulting in a more
192 tightly focused and cohesive implementation.
193
194 <h3>2.6 Lots of little tools vs. Self-contained system</h3>
195
196 Git consists of many small tools, each doing one small part of the job,
197 which can be recombined (by experts) to perform powerful operations.
198 Git has a lot of complexity and many dependencies and requires an "installer"
199 script or program to get it running.
@@ -177,11 +207,11 @@
207 small tools that collaborate to get the job done. The designer of
208 Fossil says that the unix philosophy is "it just works". Both
209 individuals have written their DVCSes to reflect their own view
210 of the "unix philosophy".
211
212 <h3>2.7 One vs. Many Check-outs per Repository</h3>
213
214 A "repository" in Git is a pile-of-files in the ".git" subdirectory
215 of a single check-out. The check-out and the repository are located
216 together in the filesystem.
217
@@ -198,11 +228,11 @@
228 "[https://git-scm.com/docs/git-worktree|worktree]" command that
229 allows a single repository to host multiple check-outs. However,
230 the interface is sufficiently difficult to use that most people
231 find it easier to create a separate clone for each check-out.
232
233 <h3>2.8 What you should have done vs. What you actually did</h3>
234
235 Git puts a lot of emphasis on maintaining
236 a "clean" check-in history. Extraneous and experimental branches by
237 individual developers often never make it into the main repository. And
238 branches are often rebased before being pushed, to make
@@ -219,11 +249,11 @@
249 is not a factor.
250
251 One commentator has mused that Git records history according to
252 the victors, whereas Fossil records history as it actually happened.
253
254 <h3>2.9 GPL vs. BSD</h3>
255
256 Git is covered by the GPL license whereas Fossil is covered by
257 a two-clause BSD license.
258
259 Consider the difference between GPL and BSD licenses: GPL is designed
@@ -275,14 +305,14 @@
305 Both Git and Fossil can easily find the ancestors of a check-in. But
306 only Fossil shows the descendents. (It is possible to find the
307 descendents of a check-in in Git using the log, but that is sufficiently
308 difficult that nobody ever actually does it.)
309
310 * <b>Wiki, Embedded documentation, Trouble-tickets, Tech-Notes, and Forum</b>
311
312 Git only provides versioning of source code. Fossil strives to provide
313 other related project management services as well.
314
315 * <b>Named branches</b>
316
317 Branches in Fossil have persistent names that are propagated
318 to collaborators via [/help?cmd=push|push] and [/help?cmd=pull|pull].
319
+3 -2
--- www/index.wiki
+++ www/index.wiki
@@ -62,12 +62,13 @@
6262
[./stats.wiki | bandwidth efficient] to the point that Fossil can be
6363
used comfortably over dial-up or over the exceedingly slow Wifi on
6464
airliners.
6565
6666
5. <b>CGI/SCGI Enabled</b> - No server is required, but if you want to
67
- set one up, Fossil supports four easy
68
- [./server.wiki | server configurations].
67
+ set one up, Fossil supports four easy [./server.wiki | server configurations].
68
+ You can also easily set up your server to automatically
69
+ [./mirrortogithub.md | mirror content on GitHub].
6970
7071
6. <b>Autosync</b> -
7172
Fossil supports [./concepts.wiki#workflow | "autosync" mode]
7273
which helps to keep projects moving
7374
forward by reducing the amount of needless
7475
--- www/index.wiki
+++ www/index.wiki
@@ -62,12 +62,13 @@
62 [./stats.wiki | bandwidth efficient] to the point that Fossil can be
63 used comfortably over dial-up or over the exceedingly slow Wifi on
64 airliners.
65
66 5. <b>CGI/SCGI Enabled</b> - No server is required, but if you want to
67 set one up, Fossil supports four easy
68 [./server.wiki | server configurations].
 
69
70 6. <b>Autosync</b> -
71 Fossil supports [./concepts.wiki#workflow | "autosync" mode]
72 which helps to keep projects moving
73 forward by reducing the amount of needless
74
--- www/index.wiki
+++ www/index.wiki
@@ -62,12 +62,13 @@
62 [./stats.wiki | bandwidth efficient] to the point that Fossil can be
63 used comfortably over dial-up or over the exceedingly slow Wifi on
64 airliners.
65
66 5. <b>CGI/SCGI Enabled</b> - No server is required, but if you want to
67 set one up, Fossil supports four easy [./server.wiki | server configurations].
68 You can also easily set up your server to automatically
69 [./mirrortogithub.md | mirror content on GitHub].
70
71 6. <b>Autosync</b> -
72 Fossil supports [./concepts.wiki#workflow | "autosync" mode]
73 which helps to keep projects moving
74 forward by reducing the amount of needless
75
--- www/inout.wiki
+++ www/inout.wiki
@@ -48,10 +48,19 @@
4848
since the git-fast-export file format is currently the only VCS interchange
4949
format that Fossil will generate. However,
5050
future versions of Fossil might add the ability to generate other
5151
VCS interchange formats, and so for compatibility, the use of the --git
5252
option recommended.
53
+
54
+<h2>Mirror A Fossil Repository In Git</h2>
55
+
56
+Fossil version 2.9 and later supports a simple mechanism for
57
+doing a Git or
58
+[./mirrortogithub.md|GitHub mirror of a Fossil repository].
59
+See that separate document for details. Fossil is self-hosting,
60
+but a [https://github.com/drhsqlite/fossil-mirror|GitHub mirror of Fossil]
61
+is available as a proof-of-concept.
5362
5463
<h2>Bidirectional Synchronization</h2>
5564
Fossil also has the ability to synchronize with a Git repository via repeated
5665
imports and/or exports. To do this, it uses marks files to store a record of
5766
artifacts which are known by both Git and Fossil to exist at a given point in
5867
--- www/inout.wiki
+++ www/inout.wiki
@@ -48,10 +48,19 @@
48 since the git-fast-export file format is currently the only VCS interchange
49 format that Fossil will generate. However,
50 future versions of Fossil might add the ability to generate other
51 VCS interchange formats, and so for compatibility, the use of the --git
52 option recommended.
 
 
 
 
 
 
 
 
 
53
54 <h2>Bidirectional Synchronization</h2>
55 Fossil also has the ability to synchronize with a Git repository via repeated
56 imports and/or exports. To do this, it uses marks files to store a record of
57 artifacts which are known by both Git and Fossil to exist at a given point in
58
--- www/inout.wiki
+++ www/inout.wiki
@@ -48,10 +48,19 @@
48 since the git-fast-export file format is currently the only VCS interchange
49 format that Fossil will generate. However,
50 future versions of Fossil might add the ability to generate other
51 VCS interchange formats, and so for compatibility, the use of the --git
52 option recommended.
53
54 <h2>Mirror A Fossil Repository In Git</h2>
55
56 Fossil version 2.9 and later supports a simple mechanism for
57 doing a Git or
58 [./mirrortogithub.md|GitHub mirror of a Fossil repository].
59 See that separate document for details. Fossil is self-hosting,
60 but a [https://github.com/drhsqlite/fossil-mirror|GitHub mirror of Fossil]
61 is available as a proof-of-concept.
62
63 <h2>Bidirectional Synchronization</h2>
64 Fossil also has the ability to synchronize with a Git repository via repeated
65 imports and/or exports. To do this, it uses marks files to store a record of
66 artifacts which are known by both Git and Fossil to exist at a given point in
67
--- www/mirrortogithub.md
+++ www/mirrortogithub.md
@@ -49,11 +49,12 @@
4949
<p> You can also run the command above outside of any open checkout of
5050
your project by supplying the “<code>-R&nbsp;repository</code>”
5151
option.
5252
5353
<li><p>Get some coffee. Depending on the size of your project, the
54
- command above can run for several minutes.
54
+ initial "<code>fossil git export</code>" command in the previous
55
+ step might run for several minutes.
5556
5657
<li><p>And you are done! Assuming everything worked, your project is now
5758
mirrored on GitHub.
5859
5960
<li><p>Whenever you update your project, simply run this command to update
@@ -64,11 +65,18 @@
6465
</blockquote>
6566
6667
6768
<p> Unlike with the first time you ran that command, you don’t need
6869
the remaining arguments, because Fossil remembers those things.
69
- Subsequent mirror updates should happen in a second or less.
70
+ Subsequent mirror updates should usually happen in a fraction of
71
+ a second.
72
+
73
+<li><p>To see the status of your mirror, run:
74
+
75
+<blockquote>
76
+<pre>$ fossil git status</pre>
77
+</blockquote>
7078
</ol>
7179
7280
## Notes:
7381
7482
* The mirroring is one-way. If you check in changes on GitHub, those
@@ -87,10 +95,13 @@
8795
subsequent invocations of "`fossil git export`" will know where you
8896
left off the last time and what new content needs to be moved over into
8997
Git. Be careful not to mess with the `.mirror_state` directory or
9098
any of its contents. Do not put those files under Git management. Do
9199
not edit or delete them.
100
+
101
+ * The name of the "trunk" branch is automatically translated into "master"
102
+ in the Git mirror.
92103
93104
* Only check-ins and simple tags are translated to Git. Git does not
94105
support wiki or tickets or unversioned content or any of the other
95106
features of Fossil that make it so convenient to use, so those other
96107
elements cannot be mirrored in Git.
@@ -97,32 +108,41 @@
97108
98109
* In Git, all tags must be unique. If your Fossil repository has the
99110
same tag on two or more check-ins, the tag will only be preserved on
100111
the chronologically newest check-in.
101112
113
+ * There is a
114
+ [long list of restrictions](https://git-scm.com/docs/git-check-ref-format)
115
+ on tag and branch names in Git. If any of your Fossil tag or branch names
116
+ violate these rules, then the names are translated prior to being exported
117
+ to Git. The translation usually involves converting the offending characters
118
+ into underscores.
119
+
102120
## Example GitHub Mirrors
103121
104122
As of this writing (2019-03-16) Fossil’s own repository is mirrored
105123
on GitHub at:
106124
107125
>
108126
<https://github.com/drhsqlite/fossil-mirror>
109127
110
-In addition, an experimental SQLite mirror is available:
128
+In addition, an official Git mirror of SQLite is available:
111129
112130
>
113
-<https://github.com/drhsqlite/sqlite-mirror>
131
+<https://github.com/sqlite/sqlite>
114132
115
-The Fossil source repositories for both of these mirrors are at
133
+The Fossil source repositories for these mirrors are at
116134
<https://www2.fossil-scm.org/fossil> and <https://www2.sqlite.org/src>,
117
-respectively. On that machine, there is a cron job that runs at
118
-17 minutes after the hour, every hour that does:
135
+respectively. Both repositories are hosted on the same VM at
136
+[Linode](https://www.linode.com). On that machine, there is a
137
+[cron job](https://linux.die.net/man/8/cron)
138
+that runs at 17 minutes after the hour, every hour that does:
119139
120140
>
121141
/usr/bin/fossil sync -u -R /home/www/fossil/fossil.fossil
122142
/usr/bin/fossil sync -R /home/www/fossil/sqlite.fossil
123143
/usr/bin/fossil git export -R /home/www/fossil/fossil.fossil
124144
/usr/bin/fossil git export -R /home/www/fossil/sqlite.fossil
125145
126146
The initial two "sync" commands pull in changes from the primary
127
-Fossil repositores for Fossil and SQLite. The last two lines
147
+Fossil repositories for Fossil and SQLite. The last two lines
128148
export the changes to Git and push the results up to GitHub.
129149
--- www/mirrortogithub.md
+++ www/mirrortogithub.md
@@ -49,11 +49,12 @@
49 <p> You can also run the command above outside of any open checkout of
50 your project by supplying the “<code>-R&nbsp;repository</code>”
51 option.
52
53 <li><p>Get some coffee. Depending on the size of your project, the
54 command above can run for several minutes.
 
55
56 <li><p>And you are done! Assuming everything worked, your project is now
57 mirrored on GitHub.
58
59 <li><p>Whenever you update your project, simply run this command to update
@@ -64,11 +65,18 @@
64 </blockquote>
65
66
67 <p> Unlike with the first time you ran that command, you don’t need
68 the remaining arguments, because Fossil remembers those things.
69 Subsequent mirror updates should happen in a second or less.
 
 
 
 
 
 
 
70 </ol>
71
72 ## Notes:
73
74 * The mirroring is one-way. If you check in changes on GitHub, those
@@ -87,10 +95,13 @@
87 subsequent invocations of "`fossil git export`" will know where you
88 left off the last time and what new content needs to be moved over into
89 Git. Be careful not to mess with the `.mirror_state` directory or
90 any of its contents. Do not put those files under Git management. Do
91 not edit or delete them.
 
 
 
92
93 * Only check-ins and simple tags are translated to Git. Git does not
94 support wiki or tickets or unversioned content or any of the other
95 features of Fossil that make it so convenient to use, so those other
96 elements cannot be mirrored in Git.
@@ -97,32 +108,41 @@
97
98 * In Git, all tags must be unique. If your Fossil repository has the
99 same tag on two or more check-ins, the tag will only be preserved on
100 the chronologically newest check-in.
101
 
 
 
 
 
 
 
102 ## Example GitHub Mirrors
103
104 As of this writing (2019-03-16) Fossil’s own repository is mirrored
105 on GitHub at:
106
107 >
108 <https://github.com/drhsqlite/fossil-mirror>
109
110 In addition, an experimental SQLite mirror is available:
111
112 >
113 <https://github.com/drhsqlite/sqlite-mirror>
114
115 The Fossil source repositories for both of these mirrors are at
116 <https://www2.fossil-scm.org/fossil> and <https://www2.sqlite.org/src>,
117 respectively. On that machine, there is a cron job that runs at
118 17 minutes after the hour, every hour that does:
 
 
119
120 >
121 /usr/bin/fossil sync -u -R /home/www/fossil/fossil.fossil
122 /usr/bin/fossil sync -R /home/www/fossil/sqlite.fossil
123 /usr/bin/fossil git export -R /home/www/fossil/fossil.fossil
124 /usr/bin/fossil git export -R /home/www/fossil/sqlite.fossil
125
126 The initial two "sync" commands pull in changes from the primary
127 Fossil repositores for Fossil and SQLite. The last two lines
128 export the changes to Git and push the results up to GitHub.
129
--- www/mirrortogithub.md
+++ www/mirrortogithub.md
@@ -49,11 +49,12 @@
49 <p> You can also run the command above outside of any open checkout of
50 your project by supplying the “<code>-R&nbsp;repository</code>”
51 option.
52
53 <li><p>Get some coffee. Depending on the size of your project, the
54 initial "<code>fossil git export</code>" command in the previous
55 step might run for several minutes.
56
57 <li><p>And you are done! Assuming everything worked, your project is now
58 mirrored on GitHub.
59
60 <li><p>Whenever you update your project, simply run this command to update
@@ -64,11 +65,18 @@
65 </blockquote>
66
67
68 <p> Unlike with the first time you ran that command, you don’t need
69 the remaining arguments, because Fossil remembers those things.
70 Subsequent mirror updates should usually happen in a fraction of
71 a second.
72
73 <li><p>To see the status of your mirror, run:
74
75 <blockquote>
76 <pre>$ fossil git status</pre>
77 </blockquote>
78 </ol>
79
80 ## Notes:
81
82 * The mirroring is one-way. If you check in changes on GitHub, those
@@ -87,10 +95,13 @@
95 subsequent invocations of "`fossil git export`" will know where you
96 left off the last time and what new content needs to be moved over into
97 Git. Be careful not to mess with the `.mirror_state` directory or
98 any of its contents. Do not put those files under Git management. Do
99 not edit or delete them.
100
101 * The name of the "trunk" branch is automatically translated into "master"
102 in the Git mirror.
103
104 * Only check-ins and simple tags are translated to Git. Git does not
105 support wiki or tickets or unversioned content or any of the other
106 features of Fossil that make it so convenient to use, so those other
107 elements cannot be mirrored in Git.
@@ -97,32 +108,41 @@
108
109 * In Git, all tags must be unique. If your Fossil repository has the
110 same tag on two or more check-ins, the tag will only be preserved on
111 the chronologically newest check-in.
112
113 * There is a
114 [long list of restrictions](https://git-scm.com/docs/git-check-ref-format)
115 on tag and branch names in Git. If any of your Fossil tag or branch names
116 violate these rules, then the names are translated prior to being exported
117 to Git. The translation usually involves converting the offending characters
118 into underscores.
119
120 ## Example GitHub Mirrors
121
122 As of this writing (2019-03-16) Fossil’s own repository is mirrored
123 on GitHub at:
124
125 >
126 <https://github.com/drhsqlite/fossil-mirror>
127
128 In addition, an official Git mirror of SQLite is available:
129
130 >
131 <https://github.com/sqlite/sqlite>
132
133 The Fossil source repositories for these mirrors are at
134 <https://www2.fossil-scm.org/fossil> and <https://www2.sqlite.org/src>,
135 respectively. Both repositories are hosted on the same VM at
136 [Linode](https://www.linode.com). On that machine, there is a
137 [cron job](https://linux.die.net/man/8/cron)
138 that runs at 17 minutes after the hour, every hour that does:
139
140 >
141 /usr/bin/fossil sync -u -R /home/www/fossil/fossil.fossil
142 /usr/bin/fossil sync -R /home/www/fossil/sqlite.fossil
143 /usr/bin/fossil git export -R /home/www/fossil/fossil.fossil
144 /usr/bin/fossil git export -R /home/www/fossil/sqlite.fossil
145
146 The initial two "sync" commands pull in changes from the primary
147 Fossil repositories for Fossil and SQLite. The last two lines
148 export the changes to Git and push the results up to GitHub.
149
--- www/selfhost.wiki
+++ www/selfhost.wiki
@@ -10,10 +10,12 @@
1010
1111
The canonical repository is (1). Repositories (2) and (3) automatically
1212
stay in synchronization with (1) via a
1313
<a href="http://en.wikipedia.org/wiki/Cron">cron job</a> that invokes
1414
"fossil sync" at regular intervals.
15
+Repository (2) also publishes a
16
+[./mirrortogithub.md|GitHub mirror of Fossil] as a demonstration.
1517
1618
Note that the two secondary repositories are more than just read-only mirrors.
1719
All three servers support full read/write capabilities.
1820
Changes (such as new tickets or wiki or check-ins) can be implemented
1921
on any of the three servers and those changes automatically propagate to the
@@ -67,6 +69,8 @@
6769
</pre></blockquote>
6870
6971
Server (2) is a
7072
<a href="http://www.linode.com/">Linode 4096</a> located in Newark, NJ
7173
and set up just like the canonical server (1) with the addition of a
72
-cron job for synchronization as in server (3).
74
+cron job for synchronization. The same cron job also runs the
75
+[/help?cmd=git|fossil git export] command after each sync in order to
76
+[./mirrortogithub.md|mirror all changes to GitHub].
7377
--- www/selfhost.wiki
+++ www/selfhost.wiki
@@ -10,10 +10,12 @@
10
11 The canonical repository is (1). Repositories (2) and (3) automatically
12 stay in synchronization with (1) via a
13 <a href="http://en.wikipedia.org/wiki/Cron">cron job</a> that invokes
14 "fossil sync" at regular intervals.
 
 
15
16 Note that the two secondary repositories are more than just read-only mirrors.
17 All three servers support full read/write capabilities.
18 Changes (such as new tickets or wiki or check-ins) can be implemented
19 on any of the three servers and those changes automatically propagate to the
@@ -67,6 +69,8 @@
67 </pre></blockquote>
68
69 Server (2) is a
70 <a href="http://www.linode.com/">Linode 4096</a> located in Newark, NJ
71 and set up just like the canonical server (1) with the addition of a
72 cron job for synchronization as in server (3).
 
 
73
--- www/selfhost.wiki
+++ www/selfhost.wiki
@@ -10,10 +10,12 @@
10
11 The canonical repository is (1). Repositories (2) and (3) automatically
12 stay in synchronization with (1) via a
13 <a href="http://en.wikipedia.org/wiki/Cron">cron job</a> that invokes
14 "fossil sync" at regular intervals.
15 Repository (2) also publishes a
16 [./mirrortogithub.md|GitHub mirror of Fossil] as a demonstration.
17
18 Note that the two secondary repositories are more than just read-only mirrors.
19 All three servers support full read/write capabilities.
20 Changes (such as new tickets or wiki or check-ins) can be implemented
21 on any of the three servers and those changes automatically propagate to the
@@ -67,6 +69,8 @@
69 </pre></blockquote>
70
71 Server (2) is a
72 <a href="http://www.linode.com/">Linode 4096</a> located in Newark, NJ
73 and set up just like the canonical server (1) with the addition of a
74 cron job for synchronization. The same cron job also runs the
75 [/help?cmd=git|fossil git export] command after each sync in order to
76 [./mirrortogithub.md|mirror all changes to GitHub].
77
--- www/webui.wiki
+++ www/webui.wiki
@@ -6,10 +6,11 @@
66
77
* [./bugtheory.wiki | Ticketing and bug tracking]
88
* [./wikitheory.wiki | Wiki]
99
* [./embeddeddoc.wiki | On-line documentation]
1010
* [./event.wiki | Technical notes]
11
+ * [./forum.wiki | Forum]
1112
* Timelines
1213
* Full text search over all of the above
1314
* Status information
1415
* Graphs of revision and branching history
1516
* File and version lists and differences
1617
--- www/webui.wiki
+++ www/webui.wiki
@@ -6,10 +6,11 @@
6
7 * [./bugtheory.wiki | Ticketing and bug tracking]
8 * [./wikitheory.wiki | Wiki]
9 * [./embeddeddoc.wiki | On-line documentation]
10 * [./event.wiki | Technical notes]
 
11 * Timelines
12 * Full text search over all of the above
13 * Status information
14 * Graphs of revision and branching history
15 * File and version lists and differences
16
--- www/webui.wiki
+++ www/webui.wiki
@@ -6,10 +6,11 @@
6
7 * [./bugtheory.wiki | Ticketing and bug tracking]
8 * [./wikitheory.wiki | Wiki]
9 * [./embeddeddoc.wiki | On-line documentation]
10 * [./event.wiki | Technical notes]
11 * [./forum.wiki | Forum]
12 * Timelines
13 * Full text search over all of the above
14 * Status information
15 * Graphs of revision and branching history
16 * File and version lists and differences
17
--- www/wikitheory.wiki
+++ www/wikitheory.wiki
@@ -8,10 +8,12 @@
88
* Description and comments in [./bugtheory.wiki | bug reports].
99
* Check-in comments.
1010
* [./embeddeddoc.wiki | Embedded documentation] files whose
1111
name ends in ".wiki" or ".md" or ".markdown".
1212
* [./event.wiki | Technical notes].
13
+ * [./forum.wiki | Forum messages].
14
+ * Auxiliary notes on check-ins and branches.
1315
1416
The [/wiki_rules | formatting rules for fossil wiki]
1517
are designed to be simple and intuitive. The idea is that wiki provides
1618
paragraph breaks, numbered and bulleted lists, and hyperlinking for
1719
simple documents together with a safe subset of HTML for more complex
@@ -56,11 +58,28 @@
5658
use the exact same markup. Some projects may choose to
5759
use both forms of documentation at the same time. Because the same
5860
format is used, it is trivial to move a file from wiki to embedded documentation
5961
or back again as the project evolves.
6062
61
-<h2>Bug-reports and check-in comments</h2>
63
+<h2>Bug-reports and check-in comments and Forum messages</h2>
6264
6365
The comments on check-ins and the text in the descriptions of bug reports
6466
both use wiki formatting. Exactly the same set of formatting rules apply.
6567
There is never a need to learn one formatting language for documentation
6668
and a different markup for bugs or for check-in comments.
69
+
70
+<h2>Auxiliary notes attached to check-ins or branches</h2>
71
+
72
+Stand-alone wiki pages with special names "branch/<i>BRANCHNAME</i>"
73
+or "checkin/<i>HASH</i>" are associated with the corresponding
74
+branch or check-in. The wiki text appears in an "About" section of
75
+timelines and info screens. Examples:
76
+
77
+ * [/timeline?r=graph-test-branch] shows the text of the
78
+ [/wiki?name=branch/graph-test-branch|branch/graph-test-branch]
79
+ wiki page at the top of the timeline
80
+ * [/info/19c60b7fc9e2] shows the text of the
81
+ [/wiki?name=checkin/19c60b7fc9e2400e56a6f938bbad0e34ca746ca2eabdecac10945539f1f5e8c6|checkin/19c60b7fc9e2...]
82
+ wiki page in the "About" section.
83
+
84
+This special wiki pages are very useful for recording historical
85
+notes.
6786
--- www/wikitheory.wiki
+++ www/wikitheory.wiki
@@ -8,10 +8,12 @@
8 * Description and comments in [./bugtheory.wiki | bug reports].
9 * Check-in comments.
10 * [./embeddeddoc.wiki | Embedded documentation] files whose
11 name ends in ".wiki" or ".md" or ".markdown".
12 * [./event.wiki | Technical notes].
 
 
13
14 The [/wiki_rules | formatting rules for fossil wiki]
15 are designed to be simple and intuitive. The idea is that wiki provides
16 paragraph breaks, numbered and bulleted lists, and hyperlinking for
17 simple documents together with a safe subset of HTML for more complex
@@ -56,11 +58,28 @@
56 use the exact same markup. Some projects may choose to
57 use both forms of documentation at the same time. Because the same
58 format is used, it is trivial to move a file from wiki to embedded documentation
59 or back again as the project evolves.
60
61 <h2>Bug-reports and check-in comments</h2>
62
63 The comments on check-ins and the text in the descriptions of bug reports
64 both use wiki formatting. Exactly the same set of formatting rules apply.
65 There is never a need to learn one formatting language for documentation
66 and a different markup for bugs or for check-in comments.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
--- www/wikitheory.wiki
+++ www/wikitheory.wiki
@@ -8,10 +8,12 @@
8 * Description and comments in [./bugtheory.wiki | bug reports].
9 * Check-in comments.
10 * [./embeddeddoc.wiki | Embedded documentation] files whose
11 name ends in ".wiki" or ".md" or ".markdown".
12 * [./event.wiki | Technical notes].
13 * [./forum.wiki | Forum messages].
14 * Auxiliary notes on check-ins and branches.
15
16 The [/wiki_rules | formatting rules for fossil wiki]
17 are designed to be simple and intuitive. The idea is that wiki provides
18 paragraph breaks, numbered and bulleted lists, and hyperlinking for
19 simple documents together with a safe subset of HTML for more complex
@@ -56,11 +58,28 @@
58 use the exact same markup. Some projects may choose to
59 use both forms of documentation at the same time. Because the same
60 format is used, it is trivial to move a file from wiki to embedded documentation
61 or back again as the project evolves.
62
63 <h2>Bug-reports and check-in comments and Forum messages</h2>
64
65 The comments on check-ins and the text in the descriptions of bug reports
66 both use wiki formatting. Exactly the same set of formatting rules apply.
67 There is never a need to learn one formatting language for documentation
68 and a different markup for bugs or for check-in comments.
69
70 <h2>Auxiliary notes attached to check-ins or branches</h2>
71
72 Stand-alone wiki pages with special names "branch/<i>BRANCHNAME</i>"
73 or "checkin/<i>HASH</i>" are associated with the corresponding
74 branch or check-in. The wiki text appears in an "About" section of
75 timelines and info screens. Examples:
76
77 * [/timeline?r=graph-test-branch] shows the text of the
78 [/wiki?name=branch/graph-test-branch|branch/graph-test-branch]
79 wiki page at the top of the timeline
80 * [/info/19c60b7fc9e2] shows the text of the
81 [/wiki?name=checkin/19c60b7fc9e2400e56a6f938bbad0e34ca746ca2eabdecac10945539f1f5e8c6|checkin/19c60b7fc9e2...]
82 wiki page in the "About" section.
83
84 This special wiki pages are very useful for recording historical
85 notes.
86

Keyboard Shortcuts

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