Fossil SCM

merged in trunk.

stephan 2020-05-26 06:47 style-css-revamp merge
Commit fe018289e3a76d312c4a0f0ee575bf3ed3e23f8859a1e7d8768382a9bf1ad4ad
+21
--- src/cgi.c
+++ src/cgi.c
@@ -433,10 +433,31 @@
433433
va_list ap;
434434
va_start(ap, zFormat);
435435
cgi_redirect(vmprintf(zFormat, ap));
436436
va_end(ap);
437437
}
438
+
439
+/*
440
+** Add a "Content-disposition: attachment; filename=%s" header to the reply.
441
+*/
442
+void cgi_content_disposition_filename(const char *zFilename){
443
+ char *z;
444
+ int i, n;
445
+
446
+ /* 0123456789 123456789 123456789 123456789 123456*/
447
+ z = mprintf("Content-Disposition: attachment; filename=\"%s\";\r\n",
448
+ file_tail(zFilename));
449
+ n = (int)strlen(z);
450
+ for(i=43; i<n-4; i++){
451
+ char c = z[i];
452
+ if( fossil_isalnum(c) ) continue;
453
+ if( c=='.' || c=='-' || c=='/' ) continue;
454
+ z[i] = '_';
455
+ }
456
+ cgi_append_header(z);
457
+ fossil_free(z);
458
+}
438459
439460
/*
440461
** Return the URL for the caller. This is obtained from either the
441462
** referer CGI parameter, if it exists, or the HTTP_REFERER HTTP parameter.
442463
** If neither exist, return zDefault.
443464
--- src/cgi.c
+++ src/cgi.c
@@ -433,10 +433,31 @@
433 va_list ap;
434 va_start(ap, zFormat);
435 cgi_redirect(vmprintf(zFormat, ap));
436 va_end(ap);
437 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
439 /*
440 ** Return the URL for the caller. This is obtained from either the
441 ** referer CGI parameter, if it exists, or the HTTP_REFERER HTTP parameter.
442 ** If neither exist, return zDefault.
443
--- src/cgi.c
+++ src/cgi.c
@@ -433,10 +433,31 @@
433 va_list ap;
434 va_start(ap, zFormat);
435 cgi_redirect(vmprintf(zFormat, ap));
436 va_end(ap);
437 }
438
439 /*
440 ** Add a "Content-disposition: attachment; filename=%s" header to the reply.
441 */
442 void cgi_content_disposition_filename(const char *zFilename){
443 char *z;
444 int i, n;
445
446 /* 0123456789 123456789 123456789 123456789 123456*/
447 z = mprintf("Content-Disposition: attachment; filename=\"%s\";\r\n",
448 file_tail(zFilename));
449 n = (int)strlen(z);
450 for(i=43; i<n-4; i++){
451 char c = z[i];
452 if( fossil_isalnum(c) ) continue;
453 if( c=='.' || c=='-' || c=='/' ) continue;
454 z[i] = '_';
455 }
456 cgi_append_header(z);
457 fossil_free(z);
458 }
459
460 /*
461 ** Return the URL for the caller. This is obtained from either the
462 ** referer CGI parameter, if it exists, or the HTTP_REFERER HTTP parameter.
463 ** If neither exist, return zDefault.
464
+13 -1
--- src/db.c
+++ src/db.c
@@ -2381,16 +2381,28 @@
23812381
char c = i==argc-1 ? '\n' : ' ';
23822382
fossil_print("%s%c", sqlite3_value_text(argv[i]), c);
23832383
}
23842384
}
23852385
}
2386
-LOCAL int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){
2386
+
2387
+/*
2388
+** Callback for sqlite3_trace_v2();
2389
+*/
2390
+int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){
23872391
sqlite3_stmt *pStmt = (sqlite3_stmt*)pP;
23882392
char *zSql;
23892393
int n;
23902394
const char *zArg = (const char*)pX;
23912395
char zEnd[40];
2396
+ if( m & SQLITE_TRACE_CLOSE ){
2397
+ /* If we are tracking closes, that means we want to clean up static
2398
+ ** prepared statements. */
2399
+ while( db.pAllStmt ){
2400
+ db_finalize(db.pAllStmt);
2401
+ }
2402
+ return 0;
2403
+ }
23922404
if( zArg[0]=='-' ) return 0;
23932405
if( m & SQLITE_TRACE_PROFILE ){
23942406
sqlite3_int64 nNano = *(sqlite3_int64*)pX;
23952407
double rMillisec = 0.000001 * nNano;
23962408
sqlite3_snprintf(sizeof(zEnd),zEnd," /* %.3fms */\n", rMillisec);
23972409
--- src/db.c
+++ src/db.c
@@ -2381,16 +2381,28 @@
2381 char c = i==argc-1 ? '\n' : ' ';
2382 fossil_print("%s%c", sqlite3_value_text(argv[i]), c);
2383 }
2384 }
2385 }
2386 LOCAL int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){
 
 
 
 
2387 sqlite3_stmt *pStmt = (sqlite3_stmt*)pP;
2388 char *zSql;
2389 int n;
2390 const char *zArg = (const char*)pX;
2391 char zEnd[40];
 
 
 
 
 
 
 
 
2392 if( zArg[0]=='-' ) return 0;
2393 if( m & SQLITE_TRACE_PROFILE ){
2394 sqlite3_int64 nNano = *(sqlite3_int64*)pX;
2395 double rMillisec = 0.000001 * nNano;
2396 sqlite3_snprintf(sizeof(zEnd),zEnd," /* %.3fms */\n", rMillisec);
2397
--- src/db.c
+++ src/db.c
@@ -2381,16 +2381,28 @@
2381 char c = i==argc-1 ? '\n' : ' ';
2382 fossil_print("%s%c", sqlite3_value_text(argv[i]), c);
2383 }
2384 }
2385 }
2386
2387 /*
2388 ** Callback for sqlite3_trace_v2();
2389 */
2390 int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){
2391 sqlite3_stmt *pStmt = (sqlite3_stmt*)pP;
2392 char *zSql;
2393 int n;
2394 const char *zArg = (const char*)pX;
2395 char zEnd[40];
2396 if( m & SQLITE_TRACE_CLOSE ){
2397 /* If we are tracking closes, that means we want to clean up static
2398 ** prepared statements. */
2399 while( db.pAllStmt ){
2400 db_finalize(db.pAllStmt);
2401 }
2402 return 0;
2403 }
2404 if( zArg[0]=='-' ) return 0;
2405 if( m & SQLITE_TRACE_PROFILE ){
2406 sqlite3_int64 nNano = *(sqlite3_int64*)pX;
2407 double rMillisec = 0.000001 * nNano;
2408 sqlite3_snprintf(sizeof(zEnd),zEnd," /* %.3fms */\n", rMillisec);
2409
--- src/default_css.txt
+++ src/default_css.txt
@@ -860,5 +860,11 @@
860860
// }
861861
// #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862862
// max-width: 30em;
863863
// overflow: auto;
864864
// }
865
+input {
866
+ max-width: 95%;
867
+}
868
+textarea {
869
+ max-width: 95%;
870
+}
865871
--- src/default_css.txt
+++ src/default_css.txt
@@ -860,5 +860,11 @@
860 // }
861 // #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862 // max-width: 30em;
863 // overflow: auto;
864 // }
 
 
 
 
 
 
865
--- src/default_css.txt
+++ src/default_css.txt
@@ -860,5 +860,11 @@
860 // }
861 // #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862 // max-width: 30em;
863 // overflow: auto;
864 // }
865 input {
866 max-width: 95%;
867 }
868 textarea {
869 max-width: 95%;
870 }
871
+18 -13
--- src/doc.c
+++ src/doc.c
@@ -824,11 +824,12 @@
824824
** regardless of what branch it occurs on.
825825
**
826826
** FILE is the name of a file to delivered up as a webpage. FILE is relative
827827
** to the root of the source tree of the repository. The FILE must
828828
** be a part of CHECKIN, except when CHECKIN=="ckout" when FILE is read
829
-** directly from disk and need not be a managed file.
829
+** directly from disk and need not be a managed file. For /uv, FILE
830
+** can also be the hash of the unversioned file.
830831
**
831832
** The "ckout" CHECKIN is intended for development - to provide a mechanism
832833
** for looking at what a file will look like using the /doc webpage after
833834
** it gets checked in.
834835
**
@@ -931,22 +932,26 @@
931932
goto doc_not_found;
932933
}
933934
}
934935
if( isUV ){
935936
if( db_table_exists("repository","unversioned") ){
936
- Stmt q;
937
- db_prepare(&q, "SELECT hash, mtime FROM unversioned"
938
- " WHERE name=%Q", zName);
939
- if( db_step(&q)==SQLITE_ROW ){
940
- etag_check(ETAG_HASH, db_column_text(&q,0));
941
- etag_last_modified(db_column_int64(&q,1));
942
- }
943
- db_finalize(&q);
944
- if( unversioned_content(zName, &filebody)==0 ){
945
- rid = 1;
946
- zDfltTitle = zName;
947
- }
937
+ rid = unversioned_content(zName, &filebody);
938
+ if( rid==1 ){
939
+ Stmt q;
940
+ db_prepare(&q, "SELECT hash, mtime FROM unversioned"
941
+ " WHERE name=%Q", zName);
942
+ if( db_step(&q)==SQLITE_ROW ){
943
+ etag_check(ETAG_HASH, db_column_text(&q,0));
944
+ etag_last_modified(db_column_int64(&q,1));
945
+ }
946
+ db_finalize(&q);
947
+ }else if( rid==2 ){
948
+ zName = db_text(zName,
949
+ "SELECT name FROM unversioned WHERE hash=%Q", zName);
950
+ g.isConst = 1;
951
+ }
952
+ zDfltTitle = zName;
948953
}
949954
}else if( fossil_strcmp(zCheckin,"ckout")==0 ){
950955
/* Read from the local checkout */
951956
char *zFullpath;
952957
db_must_be_within_tree();
953958
--- src/doc.c
+++ src/doc.c
@@ -824,11 +824,12 @@
824 ** regardless of what branch it occurs on.
825 **
826 ** FILE is the name of a file to delivered up as a webpage. FILE is relative
827 ** to the root of the source tree of the repository. The FILE must
828 ** be a part of CHECKIN, except when CHECKIN=="ckout" when FILE is read
829 ** directly from disk and need not be a managed file.
 
830 **
831 ** The "ckout" CHECKIN is intended for development - to provide a mechanism
832 ** for looking at what a file will look like using the /doc webpage after
833 ** it gets checked in.
834 **
@@ -931,22 +932,26 @@
931 goto doc_not_found;
932 }
933 }
934 if( isUV ){
935 if( db_table_exists("repository","unversioned") ){
936 Stmt q;
937 db_prepare(&q, "SELECT hash, mtime FROM unversioned"
938 " WHERE name=%Q", zName);
939 if( db_step(&q)==SQLITE_ROW ){
940 etag_check(ETAG_HASH, db_column_text(&q,0));
941 etag_last_modified(db_column_int64(&q,1));
942 }
943 db_finalize(&q);
944 if( unversioned_content(zName, &filebody)==0 ){
945 rid = 1;
946 zDfltTitle = zName;
947 }
 
 
 
 
948 }
949 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
950 /* Read from the local checkout */
951 char *zFullpath;
952 db_must_be_within_tree();
953
--- src/doc.c
+++ src/doc.c
@@ -824,11 +824,12 @@
824 ** regardless of what branch it occurs on.
825 **
826 ** FILE is the name of a file to delivered up as a webpage. FILE is relative
827 ** to the root of the source tree of the repository. The FILE must
828 ** be a part of CHECKIN, except when CHECKIN=="ckout" when FILE is read
829 ** directly from disk and need not be a managed file. For /uv, FILE
830 ** can also be the hash of the unversioned file.
831 **
832 ** The "ckout" CHECKIN is intended for development - to provide a mechanism
833 ** for looking at what a file will look like using the /doc webpage after
834 ** it gets checked in.
835 **
@@ -931,22 +932,26 @@
932 goto doc_not_found;
933 }
934 }
935 if( isUV ){
936 if( db_table_exists("repository","unversioned") ){
937 rid = unversioned_content(zName, &filebody);
938 if( rid==1 ){
939 Stmt q;
940 db_prepare(&q, "SELECT hash, mtime FROM unversioned"
941 " WHERE name=%Q", zName);
942 if( db_step(&q)==SQLITE_ROW ){
943 etag_check(ETAG_HASH, db_column_text(&q,0));
944 etag_last_modified(db_column_int64(&q,1));
945 }
946 db_finalize(&q);
947 }else if( rid==2 ){
948 zName = db_text(zName,
949 "SELECT name FROM unversioned WHERE hash=%Q", zName);
950 g.isConst = 1;
951 }
952 zDfltTitle = zName;
953 }
954 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
955 /* Read from the local checkout */
956 char *zFullpath;
957 db_must_be_within_tree();
958
+14 -6
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -24,19 +24,19 @@
2424
** SSL support is abstracted out into this module because Fossil can
2525
** be compiled without SSL support (which requires OpenSSL library)
2626
*/
2727
2828
#include "config.h"
29
+#include "http_ssl.h"
2930
3031
#ifdef FOSSIL_ENABLE_SSL
3132
3233
#include <openssl/bio.h>
3334
#include <openssl/ssl.h>
3435
#include <openssl/err.h>
3536
#include <openssl/x509.h>
3637
37
-#include "http_ssl.h"
3838
#include <assert.h>
3939
#include <sys/types.h>
4040
4141
/*
4242
** There can only be a single OpenSSL IO connection open at a time.
@@ -328,10 +328,11 @@
328328
ssl_close();
329329
return 1;
330330
}
331331
332332
if( !sslNoCertVerify && SSL_get_verify_result(ssl)!=X509_V_OK ){
333
+ int x;
333334
char *desc, *prompt;
334335
Blob ans;
335336
char cReply;
336337
BIO *mem;
337338
unsigned char md[32];
@@ -338,11 +339,17 @@
338339
char zHash[32*2+1];
339340
unsigned int mdLength = (int)sizeof(md);
340341
341342
memset(md, 0, sizeof(md));
342343
zHash[0] = 0;
343
- if( X509_digest(cert, EVP_sha256(), md, &mdLength) ){
344
+ /* MMNNFFPPS */
345
+#if OPENSSL_VERSION_NUMBER >= 0x010000000
346
+ x = X509_digest(cert, EVP_sha256(), md, &mdLength);
347
+#else
348
+ x = X509_digest(cert, EVP_sha1(), md, &mdLength);
349
+#endif
350
+ if( x ){
344351
int j;
345352
for(j=0; j<mdLength && j*2+1<sizeof(zHash); ++j){
346353
zHash[j*2] = "0123456789abcdef"[md[j]>>4];
347354
zHash[j*2+1] = "0123456789abcdef"[md[j]&0xf];
348355
}
@@ -518,25 +525,26 @@
518525
** for the domains listed. Or if
519526
** the --all option is specified,
520527
** remove all TLS cert exceptions.
521528
*/
522529
void test_tlsconfig_info(void){
523
- const char *zCmd;
524
- size_t nCmd;
525
- int nHit = 0;
526530
#if !defined(FOSSIL_ENABLE_SSL)
527531
fossil_print("TLS disabled in this build\n");
528532
#else
533
+ const char *zCmd;
534
+ size_t nCmd;
535
+ int nHit = 0;
529536
db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
530537
db_open_config(1,0);
531538
zCmd = g.argc>=3 ? g.argv[2] : "show";
532539
nCmd = strlen(zCmd);
533540
if( strncmp("show",zCmd,nCmd)==0 ){
534541
const char *zName, *zValue;
535542
size_t nName;
536543
Stmt q;
537
- fossil_print("OpenSSL-version: %s\n", SSLeay_version(SSLEAY_VERSION));
544
+ fossil_print("OpenSSL-version: %s (0x%09x)\n",
545
+ SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
538546
fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
539547
fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
540548
zName = X509_get_default_cert_file_env();
541549
zValue = fossil_getenv(zName);
542550
if( zValue==0 ) zValue = "";
543551
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -24,19 +24,19 @@
24 ** SSL support is abstracted out into this module because Fossil can
25 ** be compiled without SSL support (which requires OpenSSL library)
26 */
27
28 #include "config.h"
 
29
30 #ifdef FOSSIL_ENABLE_SSL
31
32 #include <openssl/bio.h>
33 #include <openssl/ssl.h>
34 #include <openssl/err.h>
35 #include <openssl/x509.h>
36
37 #include "http_ssl.h"
38 #include <assert.h>
39 #include <sys/types.h>
40
41 /*
42 ** There can only be a single OpenSSL IO connection open at a time.
@@ -328,10 +328,11 @@
328 ssl_close();
329 return 1;
330 }
331
332 if( !sslNoCertVerify && SSL_get_verify_result(ssl)!=X509_V_OK ){
 
333 char *desc, *prompt;
334 Blob ans;
335 char cReply;
336 BIO *mem;
337 unsigned char md[32];
@@ -338,11 +339,17 @@
338 char zHash[32*2+1];
339 unsigned int mdLength = (int)sizeof(md);
340
341 memset(md, 0, sizeof(md));
342 zHash[0] = 0;
343 if( X509_digest(cert, EVP_sha256(), md, &mdLength) ){
 
 
 
 
 
 
344 int j;
345 for(j=0; j<mdLength && j*2+1<sizeof(zHash); ++j){
346 zHash[j*2] = "0123456789abcdef"[md[j]>>4];
347 zHash[j*2+1] = "0123456789abcdef"[md[j]&0xf];
348 }
@@ -518,25 +525,26 @@
518 ** for the domains listed. Or if
519 ** the --all option is specified,
520 ** remove all TLS cert exceptions.
521 */
522 void test_tlsconfig_info(void){
523 const char *zCmd;
524 size_t nCmd;
525 int nHit = 0;
526 #if !defined(FOSSIL_ENABLE_SSL)
527 fossil_print("TLS disabled in this build\n");
528 #else
 
 
 
529 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
530 db_open_config(1,0);
531 zCmd = g.argc>=3 ? g.argv[2] : "show";
532 nCmd = strlen(zCmd);
533 if( strncmp("show",zCmd,nCmd)==0 ){
534 const char *zName, *zValue;
535 size_t nName;
536 Stmt q;
537 fossil_print("OpenSSL-version: %s\n", SSLeay_version(SSLEAY_VERSION));
 
538 fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
539 fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
540 zName = X509_get_default_cert_file_env();
541 zValue = fossil_getenv(zName);
542 if( zValue==0 ) zValue = "";
543
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -24,19 +24,19 @@
24 ** SSL support is abstracted out into this module because Fossil can
25 ** be compiled without SSL support (which requires OpenSSL library)
26 */
27
28 #include "config.h"
29 #include "http_ssl.h"
30
31 #ifdef FOSSIL_ENABLE_SSL
32
33 #include <openssl/bio.h>
34 #include <openssl/ssl.h>
35 #include <openssl/err.h>
36 #include <openssl/x509.h>
37
 
38 #include <assert.h>
39 #include <sys/types.h>
40
41 /*
42 ** There can only be a single OpenSSL IO connection open at a time.
@@ -328,10 +328,11 @@
328 ssl_close();
329 return 1;
330 }
331
332 if( !sslNoCertVerify && SSL_get_verify_result(ssl)!=X509_V_OK ){
333 int x;
334 char *desc, *prompt;
335 Blob ans;
336 char cReply;
337 BIO *mem;
338 unsigned char md[32];
@@ -338,11 +339,17 @@
339 char zHash[32*2+1];
340 unsigned int mdLength = (int)sizeof(md);
341
342 memset(md, 0, sizeof(md));
343 zHash[0] = 0;
344 /* MMNNFFPPS */
345 #if OPENSSL_VERSION_NUMBER >= 0x010000000
346 x = X509_digest(cert, EVP_sha256(), md, &mdLength);
347 #else
348 x = X509_digest(cert, EVP_sha1(), md, &mdLength);
349 #endif
350 if( x ){
351 int j;
352 for(j=0; j<mdLength && j*2+1<sizeof(zHash); ++j){
353 zHash[j*2] = "0123456789abcdef"[md[j]>>4];
354 zHash[j*2+1] = "0123456789abcdef"[md[j]&0xf];
355 }
@@ -518,25 +525,26 @@
525 ** for the domains listed. Or if
526 ** the --all option is specified,
527 ** remove all TLS cert exceptions.
528 */
529 void test_tlsconfig_info(void){
 
 
 
530 #if !defined(FOSSIL_ENABLE_SSL)
531 fossil_print("TLS disabled in this build\n");
532 #else
533 const char *zCmd;
534 size_t nCmd;
535 int nHit = 0;
536 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
537 db_open_config(1,0);
538 zCmd = g.argc>=3 ? g.argv[2] : "show";
539 nCmd = strlen(zCmd);
540 if( strncmp("show",zCmd,nCmd)==0 ){
541 const char *zName, *zValue;
542 size_t nName;
543 Stmt q;
544 fossil_print("OpenSSL-version: %s (0x%09x)\n",
545 SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_NUMBER);
546 fossil_print("OpenSSL-cert-file: %s\n", X509_get_default_cert_file());
547 fossil_print("OpenSSL-cert-dir: %s\n", X509_get_default_cert_dir());
548 zName = X509_get_default_cert_file_env();
549 zValue = fossil_getenv(zName);
550 if( zValue==0 ) zValue = "";
551
+33 -17
--- src/info.c
+++ src/info.c
@@ -1754,13 +1754,18 @@
17541754
style_footer();
17551755
}
17561756
17571757
/*
17581758
** WEBPAGE: raw
1759
-** URL: /raw?name=ARTIFACTID&m=TYPE
1759
+** URL: /raw/ARTIFACTID
17601760
** URL: /raw?ci=BRANCH&filename=NAME
17611761
**
1762
+** Additional query parameters:
1763
+**
1764
+** m=MIMETYPE The mimetype is MIMETYPE
1765
+** at=FILENAME Content-disposition; attachment; filename=FILENAME;
1766
+**
17621767
** Return the uninterpreted content of an artifact. Used primarily
17631768
** to view artifacts that are images.
17641769
*/
17651770
void rawartifact_page(void){
17661771
int rid = 0;
@@ -1816,26 +1821,37 @@
18161821
** NULL, guess at the MIME-type based on the filename
18171822
** associated with the artifact.
18181823
*/
18191824
void deliver_artifact(int rid, const char *zMime){
18201825
Blob content;
1826
+ const char *zAttachName = P("at");
18211827
if( zMime==0 ){
1822
- char *zFName = db_text(0, "SELECT filename.name FROM mlink, filename"
1823
- " WHERE mlink.fid=%d"
1824
- " AND filename.fnid=mlink.fnid", rid);
1825
- if( !zFName ){
1828
+ char *zFN = (char*)zAttachName;
1829
+ if( zFN==0 ){
1830
+ zFN = db_text(0, "SELECT filename.name FROM mlink, filename"
1831
+ " WHERE mlink.fid=%d"
1832
+ " AND filename.fnid=mlink.fnid", rid);
1833
+ }
1834
+ if( zFN==0 ){
18261835
/* Look also at the attachment table */
1827
- zFName = db_text(0, "SELECT attachment.filename FROM attachment, blob"
1828
- " WHERE blob.rid=%d"
1829
- " AND attachment.src=blob.uuid", rid);
1836
+ zFN = db_text(0, "SELECT attachment.filename FROM attachment, blob"
1837
+ " WHERE blob.rid=%d"
1838
+ " AND attachment.src=blob.uuid", rid);
1839
+ }
1840
+ if( zFN ){
1841
+ zMime = mimetype_from_name(zFN);
18301842
}
1831
- if( zFName ) zMime = mimetype_from_name(zFName);
1832
- if( zMime==0 ) zMime = "application/x-fossil-artifact";
1843
+ if( zMime==0 ){
1844
+ zMime = "application/x-fossil-artifact";
1845
+ }
18331846
}
18341847
content_get(rid, &content);
18351848
fossil_free(style_csp(1));
18361849
cgi_set_content_type(zMime);
1850
+ if( zAttachName ){
1851
+ cgi_content_disposition_filename(zAttachName);
1852
+ }
18371853
cgi_set_content(&content);
18381854
}
18391855
18401856
/*
18411857
** Render a hex dump of a file.
@@ -1929,12 +1945,12 @@
19291945
@ :</h2>
19301946
}
19311947
blob_zero(&downloadName);
19321948
if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
19331949
object_description(rid, objdescFlags, 0, &downloadName);
1934
- style_submenu_element("Download", "%s/raw/%T?name=%s",
1935
- g.zTop, blob_str(&downloadName), zUuid);
1950
+ style_submenu_element("Download", "%R/raw/%s?at=%T",
1951
+ zUuid, file_tail(blob_str(&downloadName)));
19361952
@ <hr />
19371953
content_get(rid, &content);
19381954
@ <blockquote><pre>
19391955
hexdump(&content);
19401956
@ </pre></blockquote>
@@ -2259,12 +2275,13 @@
22592275
if( asText ) objdescFlags &= ~OBJDESC_BASE;
22602276
objType = object_description(rid, objdescFlags,
22612277
(isFile?zName:0), &downloadName);
22622278
}
22632279
if( !descOnly && P("download")!=0 ){
2264
- cgi_redirectf("%R/raw/%T?name=%s", blob_str(&downloadName),
2265
- db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid));
2280
+ cgi_redirectf("%R/raw/%s?at=%T",
2281
+ db_text("x", "SELECT uuid FROM blob WHERE rid=%d", rid),
2282
+ file_tail(blob_str(&downloadName)));
22662283
/*NOTREACHED*/
22672284
}
22682285
if( g.perm.Admin ){
22692286
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
22702287
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
@@ -2305,12 +2322,11 @@
23052322
const char *zIp = db_column_text(&q,2);
23062323
@ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
23072324
}
23082325
db_finalize(&q);
23092326
}
2310
- style_submenu_element("Download", "%R/raw/%T?name=%s",
2311
- blob_str(&downloadName), zUuid);
2327
+ style_submenu_element("Download", "%R/raw/%s?at=%T", zUuid, file_tail(zName));
23122328
if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
23132329
style_submenu_element("Check-ins Using", "%R/timeline?n=200&uf=%s", zUuid);
23142330
}
23152331
zMime = mimetype_from_name(blob_str(&downloadName));
23162332
if( zMime ){
@@ -2340,11 +2356,11 @@
23402356
@ <hr />
23412357
content_get(rid, &content);
23422358
if( renderAsWiki ){
23432359
wiki_render_by_mimetype(&content, zMime);
23442360
}else if( renderAsHtml ){
2345
- @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
2361
+ @ <iframe src="%R/raw/%s(zUuid)"
23462362
@ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
23472363
@ sandbox="allow-same-origin" id="ifm1">
23482364
@ </iframe>
23492365
@ <script nonce="%h(style_nonce())">
23502366
@ document.getElementById("ifm1").addEventListener("load",
23512367
--- src/info.c
+++ src/info.c
@@ -1754,13 +1754,18 @@
1754 style_footer();
1755 }
1756
1757 /*
1758 ** WEBPAGE: raw
1759 ** URL: /raw?name=ARTIFACTID&m=TYPE
1760 ** URL: /raw?ci=BRANCH&filename=NAME
1761 **
 
 
 
 
 
1762 ** Return the uninterpreted content of an artifact. Used primarily
1763 ** to view artifacts that are images.
1764 */
1765 void rawartifact_page(void){
1766 int rid = 0;
@@ -1816,26 +1821,37 @@
1816 ** NULL, guess at the MIME-type based on the filename
1817 ** associated with the artifact.
1818 */
1819 void deliver_artifact(int rid, const char *zMime){
1820 Blob content;
 
1821 if( zMime==0 ){
1822 char *zFName = db_text(0, "SELECT filename.name FROM mlink, filename"
1823 " WHERE mlink.fid=%d"
1824 " AND filename.fnid=mlink.fnid", rid);
1825 if( !zFName ){
 
 
 
1826 /* Look also at the attachment table */
1827 zFName = db_text(0, "SELECT attachment.filename FROM attachment, blob"
1828 " WHERE blob.rid=%d"
1829 " AND attachment.src=blob.uuid", rid);
 
 
 
1830 }
1831 if( zFName ) zMime = mimetype_from_name(zFName);
1832 if( zMime==0 ) zMime = "application/x-fossil-artifact";
 
1833 }
1834 content_get(rid, &content);
1835 fossil_free(style_csp(1));
1836 cgi_set_content_type(zMime);
 
 
 
1837 cgi_set_content(&content);
1838 }
1839
1840 /*
1841 ** Render a hex dump of a file.
@@ -1929,12 +1945,12 @@
1929 @ :</h2>
1930 }
1931 blob_zero(&downloadName);
1932 if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1933 object_description(rid, objdescFlags, 0, &downloadName);
1934 style_submenu_element("Download", "%s/raw/%T?name=%s",
1935 g.zTop, blob_str(&downloadName), zUuid);
1936 @ <hr />
1937 content_get(rid, &content);
1938 @ <blockquote><pre>
1939 hexdump(&content);
1940 @ </pre></blockquote>
@@ -2259,12 +2275,13 @@
2259 if( asText ) objdescFlags &= ~OBJDESC_BASE;
2260 objType = object_description(rid, objdescFlags,
2261 (isFile?zName:0), &downloadName);
2262 }
2263 if( !descOnly && P("download")!=0 ){
2264 cgi_redirectf("%R/raw/%T?name=%s", blob_str(&downloadName),
2265 db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid));
 
2266 /*NOTREACHED*/
2267 }
2268 if( g.perm.Admin ){
2269 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2270 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
@@ -2305,12 +2322,11 @@
2305 const char *zIp = db_column_text(&q,2);
2306 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
2307 }
2308 db_finalize(&q);
2309 }
2310 style_submenu_element("Download", "%R/raw/%T?name=%s",
2311 blob_str(&downloadName), zUuid);
2312 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2313 style_submenu_element("Check-ins Using", "%R/timeline?n=200&uf=%s", zUuid);
2314 }
2315 zMime = mimetype_from_name(blob_str(&downloadName));
2316 if( zMime ){
@@ -2340,11 +2356,11 @@
2340 @ <hr />
2341 content_get(rid, &content);
2342 if( renderAsWiki ){
2343 wiki_render_by_mimetype(&content, zMime);
2344 }else if( renderAsHtml ){
2345 @ <iframe src="%R/raw/%T(blob_str(&downloadName))?name=%s(zUuid)"
2346 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2347 @ sandbox="allow-same-origin" id="ifm1">
2348 @ </iframe>
2349 @ <script nonce="%h(style_nonce())">
2350 @ document.getElementById("ifm1").addEventListener("load",
2351
--- src/info.c
+++ src/info.c
@@ -1754,13 +1754,18 @@
1754 style_footer();
1755 }
1756
1757 /*
1758 ** WEBPAGE: raw
1759 ** URL: /raw/ARTIFACTID
1760 ** URL: /raw?ci=BRANCH&filename=NAME
1761 **
1762 ** Additional query parameters:
1763 **
1764 ** m=MIMETYPE The mimetype is MIMETYPE
1765 ** at=FILENAME Content-disposition; attachment; filename=FILENAME;
1766 **
1767 ** Return the uninterpreted content of an artifact. Used primarily
1768 ** to view artifacts that are images.
1769 */
1770 void rawartifact_page(void){
1771 int rid = 0;
@@ -1816,26 +1821,37 @@
1821 ** NULL, guess at the MIME-type based on the filename
1822 ** associated with the artifact.
1823 */
1824 void deliver_artifact(int rid, const char *zMime){
1825 Blob content;
1826 const char *zAttachName = P("at");
1827 if( zMime==0 ){
1828 char *zFN = (char*)zAttachName;
1829 if( zFN==0 ){
1830 zFN = db_text(0, "SELECT filename.name FROM mlink, filename"
1831 " WHERE mlink.fid=%d"
1832 " AND filename.fnid=mlink.fnid", rid);
1833 }
1834 if( zFN==0 ){
1835 /* Look also at the attachment table */
1836 zFN = db_text(0, "SELECT attachment.filename FROM attachment, blob"
1837 " WHERE blob.rid=%d"
1838 " AND attachment.src=blob.uuid", rid);
1839 }
1840 if( zFN ){
1841 zMime = mimetype_from_name(zFN);
1842 }
1843 if( zMime==0 ){
1844 zMime = "application/x-fossil-artifact";
1845 }
1846 }
1847 content_get(rid, &content);
1848 fossil_free(style_csp(1));
1849 cgi_set_content_type(zMime);
1850 if( zAttachName ){
1851 cgi_content_disposition_filename(zAttachName);
1852 }
1853 cgi_set_content(&content);
1854 }
1855
1856 /*
1857 ** Render a hex dump of a file.
@@ -1929,12 +1945,12 @@
1945 @ :</h2>
1946 }
1947 blob_zero(&downloadName);
1948 if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
1949 object_description(rid, objdescFlags, 0, &downloadName);
1950 style_submenu_element("Download", "%R/raw/%s?at=%T",
1951 zUuid, file_tail(blob_str(&downloadName)));
1952 @ <hr />
1953 content_get(rid, &content);
1954 @ <blockquote><pre>
1955 hexdump(&content);
1956 @ </pre></blockquote>
@@ -2259,12 +2275,13 @@
2275 if( asText ) objdescFlags &= ~OBJDESC_BASE;
2276 objType = object_description(rid, objdescFlags,
2277 (isFile?zName:0), &downloadName);
2278 }
2279 if( !descOnly && P("download")!=0 ){
2280 cgi_redirectf("%R/raw/%s?at=%T",
2281 db_text("x", "SELECT uuid FROM blob WHERE rid=%d", rid),
2282 file_tail(blob_str(&downloadName)));
2283 /*NOTREACHED*/
2284 }
2285 if( g.perm.Admin ){
2286 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2287 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
@@ -2305,12 +2322,11 @@
2322 const char *zIp = db_column_text(&q,2);
2323 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
2324 }
2325 db_finalize(&q);
2326 }
2327 style_submenu_element("Download", "%R/raw/%s?at=%T", zUuid, file_tail(zName));
 
2328 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2329 style_submenu_element("Check-ins Using", "%R/timeline?n=200&uf=%s", zUuid);
2330 }
2331 zMime = mimetype_from_name(blob_str(&downloadName));
2332 if( zMime ){
@@ -2340,11 +2356,11 @@
2356 @ <hr />
2357 content_get(rid, &content);
2358 if( renderAsWiki ){
2359 wiki_render_by_mimetype(&content, zMime);
2360 }else if( renderAsHtml ){
2361 @ <iframe src="%R/raw/%s(zUuid)"
2362 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2363 @ sandbox="allow-same-origin" id="ifm1">
2364 @ </iframe>
2365 @ <script nonce="%h(style_nonce())">
2366 @ document.getElementById("ifm1").addEventListener("load",
2367
+5 -2
--- src/shell.c
+++ src/shell.c
@@ -6589,10 +6589,11 @@
65896589
** sqlar support.
65906590
*/
65916591
/* #include "sqlite3ext.h" */
65926592
SQLITE_EXTENSION_INIT1
65936593
#include <zlib.h>
6594
+#include <assert.h>
65946595
65956596
/*
65966597
** Implementation of the "sqlar_compress(X)" SQL function.
65976598
**
65986599
** If the type of X is SQLITE_BLOB, and compressing that blob using
@@ -8006,13 +8007,15 @@
80068007
if( !zDetail ) continue;
80078008
nDetail = STRLEN(zDetail);
80088009
80098010
for(i=0; i<nDetail; i++){
80108011
const char *zIdx = 0;
8011
- if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
8012
+ if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
80128013
zIdx = &zDetail[i+13];
8013
- }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
8014
+ }else if( i+22<nDetail
8015
+ && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0
8016
+ ){
80148017
zIdx = &zDetail[i+22];
80158018
}
80168019
if( zIdx ){
80178020
const char *zSql;
80188021
int nIdx = 0;
80198022
--- src/shell.c
+++ src/shell.c
@@ -6589,10 +6589,11 @@
6589 ** sqlar support.
6590 */
6591 /* #include "sqlite3ext.h" */
6592 SQLITE_EXTENSION_INIT1
6593 #include <zlib.h>
 
6594
6595 /*
6596 ** Implementation of the "sqlar_compress(X)" SQL function.
6597 **
6598 ** If the type of X is SQLITE_BLOB, and compressing that blob using
@@ -8006,13 +8007,15 @@
8006 if( !zDetail ) continue;
8007 nDetail = STRLEN(zDetail);
8008
8009 for(i=0; i<nDetail; i++){
8010 const char *zIdx = 0;
8011 if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
8012 zIdx = &zDetail[i+13];
8013 }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
 
 
8014 zIdx = &zDetail[i+22];
8015 }
8016 if( zIdx ){
8017 const char *zSql;
8018 int nIdx = 0;
8019
--- src/shell.c
+++ src/shell.c
@@ -6589,10 +6589,11 @@
6589 ** sqlar support.
6590 */
6591 /* #include "sqlite3ext.h" */
6592 SQLITE_EXTENSION_INIT1
6593 #include <zlib.h>
6594 #include <assert.h>
6595
6596 /*
6597 ** Implementation of the "sqlar_compress(X)" SQL function.
6598 **
6599 ** If the type of X is SQLITE_BLOB, and compressing that blob using
@@ -8006,13 +8007,15 @@
8007 if( !zDetail ) continue;
8008 nDetail = STRLEN(zDetail);
8009
8010 for(i=0; i<nDetail; i++){
8011 const char *zIdx = 0;
8012 if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
8013 zIdx = &zDetail[i+13];
8014 }else if( i+22<nDetail
8015 && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0
8016 ){
8017 zIdx = &zDetail[i+22];
8018 }
8019 if( zIdx ){
8020 const char *zSql;
8021 int nIdx = 0;
8022
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -164,10 +164,11 @@
164164
static int sqlcmd_autoinit(
165165
sqlite3 *db,
166166
const char **pzErrMsg,
167167
const void *notUsed
168168
){
169
+ int mTrace = SQLITE_TRACE_CLOSE;
169170
add_content_sql_commands(db);
170171
db_add_aux_functions(db);
171172
re_add_sql_func(db);
172173
search_sql_setup(db);
173174
foci_register(db);
@@ -186,10 +187,14 @@
186187
char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''",
187188
g.zConfigDbName);
188189
sqlite3_exec(db, zSql, 0, 0, 0);
189190
sqlite3_free(zSql);
190191
}
192
+ /* Arrange to trace close operations so that static prepared statements
193
+ ** will get cleaned up when the shell closes the database connection */
194
+ if( g.fSqlTrace ) mTrace |= SQLITE_TRACE_PROFILE;
195
+ sqlite3_trace_v2(db, mTrace, db_sql_trace, 0);
191196
return SQLITE_OK;
192197
}
193198
194199
/*
195200
** atexit() handler that cleans up global state modified by this module.
196201
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -164,10 +164,11 @@
164 static int sqlcmd_autoinit(
165 sqlite3 *db,
166 const char **pzErrMsg,
167 const void *notUsed
168 ){
 
169 add_content_sql_commands(db);
170 db_add_aux_functions(db);
171 re_add_sql_func(db);
172 search_sql_setup(db);
173 foci_register(db);
@@ -186,10 +187,14 @@
186 char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''",
187 g.zConfigDbName);
188 sqlite3_exec(db, zSql, 0, 0, 0);
189 sqlite3_free(zSql);
190 }
 
 
 
 
191 return SQLITE_OK;
192 }
193
194 /*
195 ** atexit() handler that cleans up global state modified by this module.
196
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -164,10 +164,11 @@
164 static int sqlcmd_autoinit(
165 sqlite3 *db,
166 const char **pzErrMsg,
167 const void *notUsed
168 ){
169 int mTrace = SQLITE_TRACE_CLOSE;
170 add_content_sql_commands(db);
171 db_add_aux_functions(db);
172 re_add_sql_func(db);
173 search_sql_setup(db);
174 foci_register(db);
@@ -186,10 +187,14 @@
187 char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''",
188 g.zConfigDbName);
189 sqlite3_exec(db, zSql, 0, 0, 0);
190 sqlite3_free(zSql);
191 }
192 /* Arrange to trace close operations so that static prepared statements
193 ** will get cleaned up when the shell closes the database connection */
194 if( g.fSqlTrace ) mTrace |= SQLITE_TRACE_PROFILE;
195 sqlite3_trace_v2(db, mTrace, db_sql_trace, 0);
196 return SQLITE_OK;
197 }
198
199 /*
200 ** atexit() handler that cleans up global state modified by this module.
201
+167 -85
--- 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.32.0. By combining all the individual C code files into this
3
+** version 3.32.1. 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.
@@ -1160,13 +1160,13 @@
11601160
**
11611161
** See also: [sqlite3_libversion()],
11621162
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
11631163
** [sqlite_version()] and [sqlite_source_id()].
11641164
*/
1165
-#define SQLITE_VERSION "3.32.0"
1166
-#define SQLITE_VERSION_NUMBER 3032000
1167
-#define SQLITE_SOURCE_ID "2020-05-17 13:47:28 69e149f76853d196c8855fedfc98848b60fb116ac36bc08824b1a122469f8ece"
1165
+#define SQLITE_VERSION "3.32.1"
1166
+#define SQLITE_VERSION_NUMBER 3032001
1167
+#define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350"
11681168
11691169
/*
11701170
** CAPI3REF: Run-Time Library Version Numbers
11711171
** KEYWORDS: sqlite3_version sqlite3_sourceid
11721172
**
@@ -17841,11 +17841,11 @@
1784117841
/*
1784217842
** An instance of this structure contains information needed to generate
1784317843
** code for a SELECT that contains aggregate functions.
1784417844
**
1784517845
** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
17846
-** pointer to this structure. The Expr.iColumn field is the index in
17846
+** pointer to this structure. The Expr.iAgg field is the index in
1784717847
** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
1784817848
** code for that node.
1784917849
**
1785017850
** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
1785117851
** original Select structure that describes the SELECT statement. These
@@ -19080,10 +19080,13 @@
1908019080
SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
1908119081
SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
1908219082
SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
1908319083
SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
1908419084
SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
19085
+SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*);
19086
+SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*);
19087
+
1908519088
#ifdef SQLITE_DEBUG
1908619089
SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
1908719090
#endif
1908819091
1908919092
/*
@@ -28274,10 +28277,17 @@
2827428277
#ifndef SQLITE_PRINT_BUF_SIZE
2827528278
# define SQLITE_PRINT_BUF_SIZE 70
2827628279
#endif
2827728280
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
2827828281
28282
+/*
28283
+** Hard limit on the precision of floating-point conversions.
28284
+*/
28285
+#ifndef SQLITE_PRINTF_PRECISION_LIMIT
28286
+# define SQLITE_FP_PRECISION_LIMIT 100000000
28287
+#endif
28288
+
2827928289
/*
2828028290
** Render a string given by "fmt" into the StrAccum object.
2828128291
*/
2828228292
SQLITE_API void sqlite3_str_vappendf(
2828328293
sqlite3_str *pAccum, /* Accumulate results here */
@@ -28474,10 +28484,12 @@
2847428484
** precision The specified precision. The default
2847528485
** is -1.
2847628486
** xtype The class of the conversion.
2847728487
** infop Pointer to the appropriate info struct.
2847828488
*/
28489
+ assert( width>=0 );
28490
+ assert( precision>=(-1) );
2847928491
switch( xtype ){
2848028492
case etPOINTER:
2848128493
flag_long = sizeof(char*)==sizeof(i64) ? 2 :
2848228494
sizeof(char*)==sizeof(long int) ? 1 : 0;
2848328495
/* Fall through into the next case */
@@ -28595,10 +28607,15 @@
2859528607
}
2859628608
#ifdef SQLITE_OMIT_FLOATING_POINT
2859728609
length = 0;
2859828610
#else
2859928611
if( precision<0 ) precision = 6; /* Set default precision */
28612
+#ifdef SQLITE_FP_PRECISION_LIMIT
28613
+ if( precision>SQLITE_FP_PRECISION_LIMIT ){
28614
+ precision = SQLITE_FP_PRECISION_LIMIT;
28615
+ }
28616
+#endif
2860028617
if( realvalue<0.0 ){
2860128618
realvalue = -realvalue;
2860228619
prefix = '-';
2860328620
}else{
2860428621
prefix = flag_prefix;
@@ -28877,11 +28894,11 @@
2887728894
}else{
2887828895
escarg = va_arg(ap,char*);
2887928896
}
2888028897
isnull = escarg==0;
2888128898
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
28882
- /* For %q, %Q, and %w, the precision is the number of byte (or
28899
+ /* For %q, %Q, and %w, the precision is the number of bytes (or
2888328900
** characters if the ! flags is present) to use from the input.
2888428901
** Because of the extra quoting characters inserted, the number
2888528902
** of output characters may be larger than the precision.
2888628903
*/
2888728904
k = precision;
@@ -29962,12 +29979,13 @@
2996229979
#else
2996329980
pWin = 0;
2996429981
#endif
2996529982
}
2996629983
if( pExpr->op==TK_AGG_FUNCTION ){
29967
- sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s",
29968
- pExpr->op2, pExpr->u.zToken, zFlgs);
29984
+ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s iAgg=%d agg=%p",
29985
+ pExpr->op2, pExpr->u.zToken, zFlgs,
29986
+ pExpr->iAgg, pExpr->pAggInfo);
2996929987
}else if( pExpr->op2!=0 ){
2997029988
const char *zOp2;
2997129989
char zBuf[8];
2997229990
sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2);
2997329991
zOp2 = zBuf;
@@ -30856,10 +30874,11 @@
3085630874
/* UTF-16 Little-endian -> UTF-8 */
3085730875
while( zIn<zTerm ){
3085830876
c = *(zIn++);
3085930877
c += (*(zIn++))<<8;
3086030878
if( c>=0xd800 && c<0xe000 ){
30879
+#ifdef SQLITE_REPLACE_INVALID_UTF
3086130880
if( c>=0xdc00 || zIn>=zTerm ){
3086230881
c = 0xfffd;
3086330882
}else{
3086430883
int c2 = *(zIn++);
3086530884
c2 += (*(zIn++))<<8;
@@ -30868,19 +30887,27 @@
3086830887
c = 0xfffd;
3086930888
}else{
3087030889
c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
3087130890
}
3087230891
}
30892
+#else
30893
+ if( zIn<zTerm ){
30894
+ int c2 = (*zIn++);
30895
+ c2 += ((*zIn++)<<8);
30896
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
30897
+ }
30898
+#endif
3087330899
}
3087430900
WRITE_UTF8(z, c);
3087530901
}
3087630902
}else{
3087730903
/* UTF-16 Big-endian -> UTF-8 */
3087830904
while( zIn<zTerm ){
3087930905
c = (*(zIn++))<<8;
3088030906
c += *(zIn++);
3088130907
if( c>=0xd800 && c<0xe000 ){
30908
+#ifdef SQLITE_REPLACE_INVALID_UTF
3088230909
if( c>=0xdc00 || zIn>=zTerm ){
3088330910
c = 0xfffd;
3088430911
}else{
3088530912
int c2 = (*(zIn++))<<8;
3088630913
c2 += *(zIn++);
@@ -30889,10 +30916,17 @@
3088930916
c = 0xfffd;
3089030917
}else{
3089130918
c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
3089230919
}
3089330920
}
30921
+#else
30922
+ if( zIn<zTerm ){
30923
+ int c2 = ((*zIn++)<<8);
30924
+ c2 += (*zIn++);
30925
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
30926
+ }
30927
+#endif
3089430928
}
3089530929
WRITE_UTF8(z, c);
3089630930
}
3089730931
}
3089830932
pMem->n = (int)(z - zOut);
@@ -46821,11 +46855,13 @@
4682146855
pFile->pVfs = pVfs;
4682246856
pFile->h = h;
4682346857
if( isReadonly ){
4682446858
pFile->ctrlFlags |= WINFILE_RDONLY;
4682546859
}
46826
- if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
46860
+ if( (flags & SQLITE_OPEN_MAIN_DB)
46861
+ && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE)
46862
+ ){
4682746863
pFile->ctrlFlags |= WINFILE_PSOW;
4682846864
}
4682946865
pFile->lastErrno = NO_ERROR;
4683046866
pFile->zPath = zName;
4683146867
#if SQLITE_MAX_MMAP_SIZE>0
@@ -48313,14 +48349,15 @@
4831348349
*/
4831448350
SQLITE_PRIVATE int sqlite3MemdbInit(void){
4831548351
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
4831648352
int sz = pLower->szOsFile;
4831748353
memdb_vfs.pAppData = pLower;
48318
- /* In all known configurations of SQLite, the size of a default
48319
- ** sqlite3_file is greater than the size of a memdb sqlite3_file.
48320
- ** Should that ever change, remove the following NEVER() */
48321
- if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
48354
+ /* The following conditional can only be true when compiled for
48355
+ ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
48356
+ ** it in, to be safe, but it is marked as NO_TEST since there
48357
+ ** is no way to reach it under most builds. */
48358
+ if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
4832248359
memdb_vfs.szOsFile = sz;
4832348360
return sqlite3_vfs_register(&memdb_vfs, 0);
4832448361
}
4832548362
#endif /* SQLITE_ENABLE_DESERIALIZE */
4832648363
@@ -59957,29 +59994,47 @@
5995759994
5995859995
aOut[0] = s1;
5995959996
aOut[1] = s2;
5996059997
}
5996159998
59999
+/*
60000
+** If there is the possibility of concurrent access to the SHM file
60001
+** from multiple threads and/or processes, then do a memory barrier.
60002
+*/
5996260003
static void walShmBarrier(Wal *pWal){
5996360004
if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
5996460005
sqlite3OsShmBarrier(pWal->pDbFd);
5996560006
}
5996660007
}
5996760008
60009
+/*
60010
+** Add the SQLITE_NO_TSAN as part of the return-type of a function
60011
+** definition as a hint that the function contains constructs that
60012
+** might give false-positive TSAN warnings.
60013
+**
60014
+** See tag-20200519-1.
60015
+*/
60016
+#if defined(__clang__) && !defined(SQLITE_NO_TSAN)
60017
+# define SQLITE_NO_TSAN __attribute__((no_sanitize_thread))
60018
+#else
60019
+# define SQLITE_NO_TSAN
60020
+#endif
60021
+
5996860022
/*
5996960023
** Write the header information in pWal->hdr into the wal-index.
5997060024
**
5997160025
** The checksum on pWal->hdr is updated before it is written.
5997260026
*/
59973
-static void walIndexWriteHdr(Wal *pWal){
60027
+static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){
5997460028
volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
5997560029
const int nCksum = offsetof(WalIndexHdr, aCksum);
5997660030
5997760031
assert( pWal->writeLock );
5997860032
pWal->hdr.isInit = 1;
5997960033
pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
5998060034
walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
60035
+ /* Possible TSAN false-positive. See tag-20200519-1 */
5998160036
memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
5998260037
walShmBarrier(pWal);
5998360038
memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
5998460039
}
5998560040
@@ -61165,36 +61220,17 @@
6116561220
** cannot be backfilled from the WAL.
6116661221
*/
6116761222
mxSafeFrame = pWal->hdr.mxFrame;
6116861223
mxPage = pWal->hdr.nPage;
6116961224
for(i=1; i<WAL_NREADER; i++){
61170
- /* Thread-sanitizer reports that the following is an unsafe read,
61171
- ** as some other thread may be in the process of updating the value
61172
- ** of the aReadMark[] slot. The assumption here is that if that is
61173
- ** happening, the other client may only be increasing the value,
61174
- ** not decreasing it. So assuming either that either the "old" or
61175
- ** "new" version of the value is read, and not some arbitrary value
61176
- ** that would never be written by a real client, things are still
61177
- ** safe.
61178
- **
61179
- ** Astute readers have pointed out that the assumption stated in the
61180
- ** last sentence of the previous paragraph is not guaranteed to be
61181
- ** true for all conforming systems. However, the assumption is true
61182
- ** for all compilers and architectures in common use today (circa
61183
- ** 2019-11-27) and the alternatives are both slow and complex, and
61184
- ** so we will continue to go with the current design for now. If this
61185
- ** bothers you, or if you really are running on a system where aligned
61186
- ** 32-bit reads and writes are not atomic, then you can simply avoid
61187
- ** the use of WAL mode, or only use WAL mode together with
61188
- ** PRAGMA locking_mode=EXCLUSIVE and all will be well.
61189
- */
61190
- u32 y = pInfo->aReadMark[i];
61225
+ u32 y = AtomicLoad(pInfo->aReadMark+i);
6119161226
if( mxSafeFrame>y ){
6119261227
assert( y<=pWal->hdr.mxFrame );
6119361228
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
6119461229
if( rc==SQLITE_OK ){
61195
- pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
61230
+ u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
61231
+ AtomicStore(pInfo->aReadMark+i, iMark);
6119661232
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
6119761233
}else if( rc==SQLITE_BUSY ){
6119861234
mxSafeFrame = y;
6119961235
xBusy = 0;
6120061236
}else{
@@ -61208,11 +61244,11 @@
6120861244
rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
6120961245
assert( rc==SQLITE_OK || pIter==0 );
6121061246
}
6121161247
6121261248
if( pIter
61213
- && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
61249
+ && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
6121461250
){
6121561251
u32 nBackfill = pInfo->nBackfill;
6121661252
6121761253
pInfo->nBackfillAttempted = mxSafeFrame;
6121861254
@@ -61423,11 +61459,11 @@
6142361459
** and *pChanged is set to 1.
6142461460
**
6142561461
** If the checksum cannot be verified return non-zero. If the header
6142661462
** is read successfully and the checksum verified, return zero.
6142761463
*/
61428
-static int walIndexTryHdr(Wal *pWal, int *pChanged){
61464
+static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){
6142961465
u32 aCksum[2]; /* Checksum on the header content */
6143061466
WalIndexHdr h1, h2; /* Two copies of the header content */
6143161467
WalIndexHdr volatile *aHdr; /* Header in shared memory */
6143261468
6143361469
/* The first page of the wal-index must be mapped at this point. */
@@ -61436,17 +61472,23 @@
6143661472
/* Read the header. This might happen concurrently with a write to the
6143761473
** same area of shared memory on a different CPU in a SMP,
6143861474
** meaning it is possible that an inconsistent snapshot is read
6143961475
** from the file. If this happens, return non-zero.
6144061476
**
61477
+ ** tag-20200519-1:
6144161478
** There are two copies of the header at the beginning of the wal-index.
6144261479
** When reading, read [0] first then [1]. Writes are in the reverse order.
6144361480
** Memory barriers are used to prevent the compiler or the hardware from
61444
- ** reordering the reads and writes.
61481
+ ** reordering the reads and writes. TSAN and similar tools can sometimes
61482
+ ** give false-positive warnings about these accesses because the tools do not
61483
+ ** account for the double-read and the memory barrier. The use of mutexes
61484
+ ** here would be problematic as the memory being accessed is potentially
61485
+ ** shared among multiple processes and not all mutex implementions work
61486
+ ** reliably in that environment.
6144561487
*/
6144661488
aHdr = walIndexHdr(pWal);
61447
- memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
61489
+ memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */
6144861490
walShmBarrier(pWal);
6144961491
memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
6145061492
6145161493
if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
6145261494
return 1; /* Dirty read */
@@ -62109,16 +62151,18 @@
6210962151
** needs to be flushed.
6211062152
*/
6211162153
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
6211262154
int rc; /* Return code */
6211362155
int cnt = 0; /* Number of TryBeginRead attempts */
62156
+#ifdef SQLITE_ENABLE_SNAPSHOT
62157
+ int bChanged = 0;
62158
+ WalIndexHdr *pSnapshot = pWal->pSnapshot;
62159
+#endif
6211462160
6211562161
assert( pWal->ckptLock==0 );
6211662162
6211762163
#ifdef SQLITE_ENABLE_SNAPSHOT
62118
- int bChanged = 0;
62119
- WalIndexHdr *pSnapshot = pWal->pSnapshot;
6212062164
if( pSnapshot ){
6212162165
if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
6212262166
bChanged = 1;
6212362167
}
6212462168
@@ -62283,26 +62327,28 @@
6228362327
for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
6228462328
WalHashLoc sLoc; /* Hash table location */
6228562329
int iKey; /* Hash slot index */
6228662330
int nCollide; /* Number of hash collisions remaining */
6228762331
int rc; /* Error code */
62332
+ u32 iH;
6228862333
6228962334
rc = walHashGet(pWal, iHash, &sLoc);
6229062335
if( rc!=SQLITE_OK ){
6229162336
return rc;
6229262337
}
6229362338
nCollide = HASHTABLE_NSLOT;
62294
- for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
62295
- u32 iH = sLoc.aHash[iKey];
62339
+ iKey = walHash(pgno);
62340
+ while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
6229662341
u32 iFrame = iH + sLoc.iZero;
6229762342
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
6229862343
assert( iFrame>iRead || CORRUPT_DB );
6229962344
iRead = iFrame;
6230062345
}
6230162346
if( (nCollide--)==0 ){
6230262347
return SQLITE_CORRUPT_BKPT;
6230362348
}
62349
+ iKey = walNextHash(iKey);
6230462350
}
6230562351
if( iRead ) break;
6230662352
}
6230762353
6230862354
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
@@ -97436,10 +97482,47 @@
9743697482
}
9743797483
p = p->pPrior;
9743897484
}while( p!=0 );
9743997485
return WRC_Continue;
9744097486
}
97487
+
97488
+/* Increase the walkerDepth when entering a subquery, and
97489
+** descrease when leaving the subquery.
97490
+*/
97491
+SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){
97492
+ UNUSED_PARAMETER(pSelect);
97493
+ pWalker->walkerDepth++;
97494
+ return WRC_Continue;
97495
+}
97496
+SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){
97497
+ UNUSED_PARAMETER(pSelect);
97498
+ pWalker->walkerDepth--;
97499
+}
97500
+
97501
+
97502
+/*
97503
+** No-op routine for the parse-tree walker.
97504
+**
97505
+** When this routine is the Walker.xExprCallback then expression trees
97506
+** are walked without any actions being taken at each node. Presumably,
97507
+** when this routine is used for Walker.xExprCallback then
97508
+** Walker.xSelectCallback is set to do something useful for every
97509
+** subquery in the parser tree.
97510
+*/
97511
+SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
97512
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
97513
+ return WRC_Continue;
97514
+}
97515
+
97516
+/*
97517
+** No-op routine for the parse-tree walker for SELECT statements.
97518
+** subquery in the parser tree.
97519
+*/
97520
+SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
97521
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
97522
+ return WRC_Continue;
97523
+}
9744197524
9744297525
/************** End of walker.c **********************************************/
9744397526
/************** Begin file resolve.c *****************************************/
9744497527
/*
9744597528
** 2008 August 18
@@ -97465,10 +97548,12 @@
9746597548
** This needs to occur when copying a TK_AGG_FUNCTION node from an
9746697549
** outer query into an inner subquery.
9746797550
**
9746897551
** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..)
9746997552
** is a helper function - a callback for the tree walker.
97553
+**
97554
+** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c
9747097555
*/
9747197556
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
9747297557
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
9747397558
return WRC_Continue;
9747497559
}
@@ -103206,11 +103291,14 @@
103206103291
op = pExpr->op;
103207103292
}
103208103293
switch( op ){
103209103294
case TK_AGG_COLUMN: {
103210103295
AggInfo *pAggInfo = pExpr->pAggInfo;
103211
- struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
103296
+ struct AggInfo_col *pCol;
103297
+ assert( pAggInfo!=0 );
103298
+ assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
103299
+ pCol = &pAggInfo->aCol[pExpr->iAgg];
103212103300
if( !pAggInfo->directMode ){
103213103301
assert( pCol->iMem>0 );
103214103302
return pCol->iMem;
103215103303
}else if( pAggInfo->useSortingIdx ){
103216103304
Table *pTab = pCol->pTab;
@@ -103506,11 +103594,14 @@
103506103594
sqlite3VdbeJumpHere(v, addr);
103507103595
break;
103508103596
}
103509103597
case TK_AGG_FUNCTION: {
103510103598
AggInfo *pInfo = pExpr->pAggInfo;
103511
- if( pInfo==0 ){
103599
+ if( pInfo==0
103600
+ || NEVER(pExpr->iAgg<0)
103601
+ || NEVER(pExpr->iAgg>=pInfo->nFunc)
103602
+ ){
103512103603
assert( !ExprHasProperty(pExpr, EP_IntValue) );
103513103604
sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
103514103605
}else{
103515103606
return pInfo->aFunc[pExpr->iAgg].iMem;
103516103607
}
@@ -105262,19 +105353,10 @@
105262105353
}
105263105354
}
105264105355
}
105265105356
return WRC_Continue;
105266105357
}
105267
-static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
105268
- UNUSED_PARAMETER(pSelect);
105269
- pWalker->walkerDepth++;
105270
- return WRC_Continue;
105271
-}
105272
-static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
105273
- UNUSED_PARAMETER(pSelect);
105274
- pWalker->walkerDepth--;
105275
-}
105276105358
105277105359
/*
105278105360
** Analyze the pExpr expression looking for aggregate functions and
105279105361
** for variables that need to be added to AggInfo object that pNC->pAggInfo
105280105362
** points to. Additional entries are made on the AggInfo object as
@@ -105284,12 +105366,12 @@
105284105366
** analyzed by sqlite3ResolveExprNames().
105285105367
*/
105286105368
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
105287105369
Walker w;
105288105370
w.xExprCallback = analyzeAggregate;
105289
- w.xSelectCallback = analyzeAggregatesInSelect;
105290
- w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
105371
+ w.xSelectCallback = sqlite3WalkerDepthIncrease;
105372
+ w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
105291105373
w.walkerDepth = 0;
105292105374
w.u.pNC = pNC;
105293105375
w.pParse = 0;
105294105376
assert( pNC->pSrcList!=0 );
105295105377
sqlite3WalkExpr(&w, pExpr);
@@ -122007,11 +122089,11 @@
122007122089
}
122008122090
if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
122009122091
sqlite3TableAffinity(v, pTab, regNewData+1);
122010122092
bAffinityDone = 1;
122011122093
}
122012
- VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
122094
+ VdbeNoopComment((v, "prep index %s", pIdx->zName));
122013122095
iThisCur = iIdxCur+ix;
122014122096
122015122097
122016122098
/* Skip partial indices for which the WHERE clause is not true */
122017122099
if( pIdx->pPartIdxWhere ){
@@ -133979,33 +134061,10 @@
133979134061
}
133980134062
}
133981134063
return WRC_Continue;
133982134064
}
133983134065
133984
-/*
133985
-** No-op routine for the parse-tree walker.
133986
-**
133987
-** When this routine is the Walker.xExprCallback then expression trees
133988
-** are walked without any actions being taken at each node. Presumably,
133989
-** when this routine is used for Walker.xExprCallback then
133990
-** Walker.xSelectCallback is set to do something useful for every
133991
-** subquery in the parser tree.
133992
-*/
133993
-SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
133994
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
133995
- return WRC_Continue;
133996
-}
133997
-
133998
-/*
133999
-** No-op routine for the parse-tree walker for SELECT statements.
134000
-** subquery in the parser tree.
134001
-*/
134002
-SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
134003
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
134004
- return WRC_Continue;
134005
-}
134006
-
134007134066
#if SQLITE_DEBUG
134008134067
/*
134009134068
** Always assert. This xSelectCallback2 implementation proves that the
134010134069
** xSelectCallback2 is never invoked.
134011134070
*/
@@ -135172,11 +135231,11 @@
135172135231
sAggInfo.mxReg = pParse->nMem;
135173135232
if( db->mallocFailed ) goto select_end;
135174135233
#if SELECTTRACE_ENABLED
135175135234
if( sqlite3SelectTrace & 0x400 ){
135176135235
int ii;
135177
- SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
135236
+ SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", &sAggInfo));
135178135237
sqlite3TreeViewSelect(0, p, 0);
135179135238
for(ii=0; ii<sAggInfo.nColumn; ii++){
135180135239
sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
135181135240
ii, sAggInfo.aCol[ii].iMem);
135182135241
sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
@@ -151215,10 +151274,27 @@
151215151274
if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
151216151275
}
151217151276
}
151218151277
return pList;
151219151278
}
151279
+
151280
+/*
151281
+** When rewriting a query, if the new subquery in the FROM clause
151282
+** contains TK_AGG_FUNCTION nodes that refer to an outer query,
151283
+** then we have to increase the Expr->op2 values of those nodes
151284
+** due to the extra subquery layer that was added.
151285
+**
151286
+** See also the incrAggDepth() routine in resolve.c
151287
+*/
151288
+static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
151289
+ if( pExpr->op==TK_AGG_FUNCTION
151290
+ && pExpr->op2>=pWalker->walkerDepth
151291
+ ){
151292
+ pExpr->op2++;
151293
+ }
151294
+ return WRC_Continue;
151295
+}
151220151296
151221151297
/*
151222151298
** If the SELECT statement passed as the second argument does not invoke
151223151299
** any SQL window functions, this function is a no-op. Otherwise, it
151224151300
** rewrites the SELECT statement so that window function xStep functions
@@ -151325,10 +151401,11 @@
151325151401
pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
151326151402
);
151327151403
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
151328151404
if( p->pSrc ){
151329151405
Table *pTab2;
151406
+ Walker w;
151330151407
p->pSrc->a[0].pSelect = pSub;
151331151408
sqlite3SrcListAssignCursors(pParse, p->pSrc);
151332151409
pSub->selFlags |= SF_Expanded;
151333151410
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
151334151411
pSub->selFlags |= (selFlags & SF_Aggregate);
@@ -151340,10 +151417,15 @@
151340151417
}else{
151341151418
memcpy(pTab, pTab2, sizeof(Table));
151342151419
pTab->tabFlags |= TF_Ephemeral;
151343151420
p->pSrc->a[0].pTab = pTab;
151344151421
pTab = pTab2;
151422
+ memset(&w, 0, sizeof(w));
151423
+ w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
151424
+ w.xSelectCallback = sqlite3WalkerDepthIncrease;
151425
+ w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
151426
+ sqlite3WalkSelect(&w, pSub);
151345151427
}
151346151428
}else{
151347151429
sqlite3SelectDelete(db, pSub);
151348151430
}
151349151431
if( db->mallocFailed ) rc = SQLITE_NOMEM;
@@ -224738,11 +224820,11 @@
224738224820
int nArg, /* Number of args */
224739224821
sqlite3_value **apUnused /* Function arguments */
224740224822
){
224741224823
assert( nArg==0 );
224742224824
UNUSED_PARAM2(nArg, apUnused);
224743
- sqlite3_result_text(pCtx, "fts5: 2020-05-17 00:26:44 1313557b512297e7b75ed748894379b2022aecf696d5a58318e46a668321c1ff", -1, SQLITE_TRANSIENT);
224825
+ sqlite3_result_text(pCtx, "fts5: 2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350", -1, SQLITE_TRANSIENT);
224744224826
}
224745224827
224746224828
/*
224747224829
** Return true if zName is the extension on one of the shadow tables used
224748224830
** by this module.
@@ -229521,12 +229603,12 @@
229521229603
}
229522229604
#endif /* SQLITE_CORE */
229523229605
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
229524229606
229525229607
/************** End of stmt.c ************************************************/
229526
-#if __LINE__!=229526
229608
+#if __LINE__!=229608
229527229609
#undef SQLITE_SOURCE_ID
229528
-#define SQLITE_SOURCE_ID "2020-05-17 13:47:28 69e149f76853d196c8855fedfc98848b60fb116ac36bc08824b1a122469falt2"
229610
+#define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba8alt2"
229529229611
#endif
229530229612
/* Return the source-id for this library */
229531229613
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
229532229614
/************************** End of sqlite3.c ******************************/
229533229615
--- 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.32.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.
@@ -1160,13 +1160,13 @@
1160 **
1161 ** See also: [sqlite3_libversion()],
1162 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1163 ** [sqlite_version()] and [sqlite_source_id()].
1164 */
1165 #define SQLITE_VERSION "3.32.0"
1166 #define SQLITE_VERSION_NUMBER 3032000
1167 #define SQLITE_SOURCE_ID "2020-05-17 13:47:28 69e149f76853d196c8855fedfc98848b60fb116ac36bc08824b1a122469f8ece"
1168
1169 /*
1170 ** CAPI3REF: Run-Time Library Version Numbers
1171 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1172 **
@@ -17841,11 +17841,11 @@
17841 /*
17842 ** An instance of this structure contains information needed to generate
17843 ** code for a SELECT that contains aggregate functions.
17844 **
17845 ** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
17846 ** pointer to this structure. The Expr.iColumn field is the index in
17847 ** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
17848 ** code for that node.
17849 **
17850 ** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
17851 ** original Select structure that describes the SELECT statement. These
@@ -19080,10 +19080,13 @@
19080 SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
19081 SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
19082 SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
19083 SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
19084 SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
 
 
 
19085 #ifdef SQLITE_DEBUG
19086 SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
19087 #endif
19088
19089 /*
@@ -28274,10 +28277,17 @@
28274 #ifndef SQLITE_PRINT_BUF_SIZE
28275 # define SQLITE_PRINT_BUF_SIZE 70
28276 #endif
28277 #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
28278
 
 
 
 
 
 
 
28279 /*
28280 ** Render a string given by "fmt" into the StrAccum object.
28281 */
28282 SQLITE_API void sqlite3_str_vappendf(
28283 sqlite3_str *pAccum, /* Accumulate results here */
@@ -28474,10 +28484,12 @@
28474 ** precision The specified precision. The default
28475 ** is -1.
28476 ** xtype The class of the conversion.
28477 ** infop Pointer to the appropriate info struct.
28478 */
 
 
28479 switch( xtype ){
28480 case etPOINTER:
28481 flag_long = sizeof(char*)==sizeof(i64) ? 2 :
28482 sizeof(char*)==sizeof(long int) ? 1 : 0;
28483 /* Fall through into the next case */
@@ -28595,10 +28607,15 @@
28595 }
28596 #ifdef SQLITE_OMIT_FLOATING_POINT
28597 length = 0;
28598 #else
28599 if( precision<0 ) precision = 6; /* Set default precision */
 
 
 
 
 
28600 if( realvalue<0.0 ){
28601 realvalue = -realvalue;
28602 prefix = '-';
28603 }else{
28604 prefix = flag_prefix;
@@ -28877,11 +28894,11 @@
28877 }else{
28878 escarg = va_arg(ap,char*);
28879 }
28880 isnull = escarg==0;
28881 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
28882 /* For %q, %Q, and %w, the precision is the number of byte (or
28883 ** characters if the ! flags is present) to use from the input.
28884 ** Because of the extra quoting characters inserted, the number
28885 ** of output characters may be larger than the precision.
28886 */
28887 k = precision;
@@ -29962,12 +29979,13 @@
29962 #else
29963 pWin = 0;
29964 #endif
29965 }
29966 if( pExpr->op==TK_AGG_FUNCTION ){
29967 sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s",
29968 pExpr->op2, pExpr->u.zToken, zFlgs);
 
29969 }else if( pExpr->op2!=0 ){
29970 const char *zOp2;
29971 char zBuf[8];
29972 sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2);
29973 zOp2 = zBuf;
@@ -30856,10 +30874,11 @@
30856 /* UTF-16 Little-endian -> UTF-8 */
30857 while( zIn<zTerm ){
30858 c = *(zIn++);
30859 c += (*(zIn++))<<8;
30860 if( c>=0xd800 && c<0xe000 ){
 
30861 if( c>=0xdc00 || zIn>=zTerm ){
30862 c = 0xfffd;
30863 }else{
30864 int c2 = *(zIn++);
30865 c2 += (*(zIn++))<<8;
@@ -30868,19 +30887,27 @@
30868 c = 0xfffd;
30869 }else{
30870 c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
30871 }
30872 }
 
 
 
 
 
 
 
30873 }
30874 WRITE_UTF8(z, c);
30875 }
30876 }else{
30877 /* UTF-16 Big-endian -> UTF-8 */
30878 while( zIn<zTerm ){
30879 c = (*(zIn++))<<8;
30880 c += *(zIn++);
30881 if( c>=0xd800 && c<0xe000 ){
 
30882 if( c>=0xdc00 || zIn>=zTerm ){
30883 c = 0xfffd;
30884 }else{
30885 int c2 = (*(zIn++))<<8;
30886 c2 += *(zIn++);
@@ -30889,10 +30916,17 @@
30889 c = 0xfffd;
30890 }else{
30891 c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
30892 }
30893 }
 
 
 
 
 
 
 
30894 }
30895 WRITE_UTF8(z, c);
30896 }
30897 }
30898 pMem->n = (int)(z - zOut);
@@ -46821,11 +46855,13 @@
46821 pFile->pVfs = pVfs;
46822 pFile->h = h;
46823 if( isReadonly ){
46824 pFile->ctrlFlags |= WINFILE_RDONLY;
46825 }
46826 if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
 
 
46827 pFile->ctrlFlags |= WINFILE_PSOW;
46828 }
46829 pFile->lastErrno = NO_ERROR;
46830 pFile->zPath = zName;
46831 #if SQLITE_MAX_MMAP_SIZE>0
@@ -48313,14 +48349,15 @@
48313 */
48314 SQLITE_PRIVATE int sqlite3MemdbInit(void){
48315 sqlite3_vfs *pLower = sqlite3_vfs_find(0);
48316 int sz = pLower->szOsFile;
48317 memdb_vfs.pAppData = pLower;
48318 /* In all known configurations of SQLite, the size of a default
48319 ** sqlite3_file is greater than the size of a memdb sqlite3_file.
48320 ** Should that ever change, remove the following NEVER() */
48321 if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
 
48322 memdb_vfs.szOsFile = sz;
48323 return sqlite3_vfs_register(&memdb_vfs, 0);
48324 }
48325 #endif /* SQLITE_ENABLE_DESERIALIZE */
48326
@@ -59957,29 +59994,47 @@
59957
59958 aOut[0] = s1;
59959 aOut[1] = s2;
59960 }
59961
 
 
 
 
59962 static void walShmBarrier(Wal *pWal){
59963 if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
59964 sqlite3OsShmBarrier(pWal->pDbFd);
59965 }
59966 }
59967
 
 
 
 
 
 
 
 
 
 
 
 
 
59968 /*
59969 ** Write the header information in pWal->hdr into the wal-index.
59970 **
59971 ** The checksum on pWal->hdr is updated before it is written.
59972 */
59973 static void walIndexWriteHdr(Wal *pWal){
59974 volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
59975 const int nCksum = offsetof(WalIndexHdr, aCksum);
59976
59977 assert( pWal->writeLock );
59978 pWal->hdr.isInit = 1;
59979 pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
59980 walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
 
59981 memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
59982 walShmBarrier(pWal);
59983 memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
59984 }
59985
@@ -61165,36 +61220,17 @@
61165 ** cannot be backfilled from the WAL.
61166 */
61167 mxSafeFrame = pWal->hdr.mxFrame;
61168 mxPage = pWal->hdr.nPage;
61169 for(i=1; i<WAL_NREADER; i++){
61170 /* Thread-sanitizer reports that the following is an unsafe read,
61171 ** as some other thread may be in the process of updating the value
61172 ** of the aReadMark[] slot. The assumption here is that if that is
61173 ** happening, the other client may only be increasing the value,
61174 ** not decreasing it. So assuming either that either the "old" or
61175 ** "new" version of the value is read, and not some arbitrary value
61176 ** that would never be written by a real client, things are still
61177 ** safe.
61178 **
61179 ** Astute readers have pointed out that the assumption stated in the
61180 ** last sentence of the previous paragraph is not guaranteed to be
61181 ** true for all conforming systems. However, the assumption is true
61182 ** for all compilers and architectures in common use today (circa
61183 ** 2019-11-27) and the alternatives are both slow and complex, and
61184 ** so we will continue to go with the current design for now. If this
61185 ** bothers you, or if you really are running on a system where aligned
61186 ** 32-bit reads and writes are not atomic, then you can simply avoid
61187 ** the use of WAL mode, or only use WAL mode together with
61188 ** PRAGMA locking_mode=EXCLUSIVE and all will be well.
61189 */
61190 u32 y = pInfo->aReadMark[i];
61191 if( mxSafeFrame>y ){
61192 assert( y<=pWal->hdr.mxFrame );
61193 rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
61194 if( rc==SQLITE_OK ){
61195 pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
 
61196 walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
61197 }else if( rc==SQLITE_BUSY ){
61198 mxSafeFrame = y;
61199 xBusy = 0;
61200 }else{
@@ -61208,11 +61244,11 @@
61208 rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
61209 assert( rc==SQLITE_OK || pIter==0 );
61210 }
61211
61212 if( pIter
61213 && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
61214 ){
61215 u32 nBackfill = pInfo->nBackfill;
61216
61217 pInfo->nBackfillAttempted = mxSafeFrame;
61218
@@ -61423,11 +61459,11 @@
61423 ** and *pChanged is set to 1.
61424 **
61425 ** If the checksum cannot be verified return non-zero. If the header
61426 ** is read successfully and the checksum verified, return zero.
61427 */
61428 static int walIndexTryHdr(Wal *pWal, int *pChanged){
61429 u32 aCksum[2]; /* Checksum on the header content */
61430 WalIndexHdr h1, h2; /* Two copies of the header content */
61431 WalIndexHdr volatile *aHdr; /* Header in shared memory */
61432
61433 /* The first page of the wal-index must be mapped at this point. */
@@ -61436,17 +61472,23 @@
61436 /* Read the header. This might happen concurrently with a write to the
61437 ** same area of shared memory on a different CPU in a SMP,
61438 ** meaning it is possible that an inconsistent snapshot is read
61439 ** from the file. If this happens, return non-zero.
61440 **
 
61441 ** There are two copies of the header at the beginning of the wal-index.
61442 ** When reading, read [0] first then [1]. Writes are in the reverse order.
61443 ** Memory barriers are used to prevent the compiler or the hardware from
61444 ** reordering the reads and writes.
 
 
 
 
 
61445 */
61446 aHdr = walIndexHdr(pWal);
61447 memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
61448 walShmBarrier(pWal);
61449 memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
61450
61451 if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
61452 return 1; /* Dirty read */
@@ -62109,16 +62151,18 @@
62109 ** needs to be flushed.
62110 */
62111 SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
62112 int rc; /* Return code */
62113 int cnt = 0; /* Number of TryBeginRead attempts */
 
 
 
 
62114
62115 assert( pWal->ckptLock==0 );
62116
62117 #ifdef SQLITE_ENABLE_SNAPSHOT
62118 int bChanged = 0;
62119 WalIndexHdr *pSnapshot = pWal->pSnapshot;
62120 if( pSnapshot ){
62121 if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
62122 bChanged = 1;
62123 }
62124
@@ -62283,26 +62327,28 @@
62283 for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
62284 WalHashLoc sLoc; /* Hash table location */
62285 int iKey; /* Hash slot index */
62286 int nCollide; /* Number of hash collisions remaining */
62287 int rc; /* Error code */
 
62288
62289 rc = walHashGet(pWal, iHash, &sLoc);
62290 if( rc!=SQLITE_OK ){
62291 return rc;
62292 }
62293 nCollide = HASHTABLE_NSLOT;
62294 for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
62295 u32 iH = sLoc.aHash[iKey];
62296 u32 iFrame = iH + sLoc.iZero;
62297 if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
62298 assert( iFrame>iRead || CORRUPT_DB );
62299 iRead = iFrame;
62300 }
62301 if( (nCollide--)==0 ){
62302 return SQLITE_CORRUPT_BKPT;
62303 }
 
62304 }
62305 if( iRead ) break;
62306 }
62307
62308 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
@@ -97436,10 +97482,47 @@
97436 }
97437 p = p->pPrior;
97438 }while( p!=0 );
97439 return WRC_Continue;
97440 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97441
97442 /************** End of walker.c **********************************************/
97443 /************** Begin file resolve.c *****************************************/
97444 /*
97445 ** 2008 August 18
@@ -97465,10 +97548,12 @@
97465 ** This needs to occur when copying a TK_AGG_FUNCTION node from an
97466 ** outer query into an inner subquery.
97467 **
97468 ** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..)
97469 ** is a helper function - a callback for the tree walker.
 
 
97470 */
97471 static int incrAggDepth(Walker *pWalker, Expr *pExpr){
97472 if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
97473 return WRC_Continue;
97474 }
@@ -103206,11 +103291,14 @@
103206 op = pExpr->op;
103207 }
103208 switch( op ){
103209 case TK_AGG_COLUMN: {
103210 AggInfo *pAggInfo = pExpr->pAggInfo;
103211 struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
 
 
 
103212 if( !pAggInfo->directMode ){
103213 assert( pCol->iMem>0 );
103214 return pCol->iMem;
103215 }else if( pAggInfo->useSortingIdx ){
103216 Table *pTab = pCol->pTab;
@@ -103506,11 +103594,14 @@
103506 sqlite3VdbeJumpHere(v, addr);
103507 break;
103508 }
103509 case TK_AGG_FUNCTION: {
103510 AggInfo *pInfo = pExpr->pAggInfo;
103511 if( pInfo==0 ){
 
 
 
103512 assert( !ExprHasProperty(pExpr, EP_IntValue) );
103513 sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
103514 }else{
103515 return pInfo->aFunc[pExpr->iAgg].iMem;
103516 }
@@ -105262,19 +105353,10 @@
105262 }
105263 }
105264 }
105265 return WRC_Continue;
105266 }
105267 static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
105268 UNUSED_PARAMETER(pSelect);
105269 pWalker->walkerDepth++;
105270 return WRC_Continue;
105271 }
105272 static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
105273 UNUSED_PARAMETER(pSelect);
105274 pWalker->walkerDepth--;
105275 }
105276
105277 /*
105278 ** Analyze the pExpr expression looking for aggregate functions and
105279 ** for variables that need to be added to AggInfo object that pNC->pAggInfo
105280 ** points to. Additional entries are made on the AggInfo object as
@@ -105284,12 +105366,12 @@
105284 ** analyzed by sqlite3ResolveExprNames().
105285 */
105286 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
105287 Walker w;
105288 w.xExprCallback = analyzeAggregate;
105289 w.xSelectCallback = analyzeAggregatesInSelect;
105290 w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
105291 w.walkerDepth = 0;
105292 w.u.pNC = pNC;
105293 w.pParse = 0;
105294 assert( pNC->pSrcList!=0 );
105295 sqlite3WalkExpr(&w, pExpr);
@@ -122007,11 +122089,11 @@
122007 }
122008 if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
122009 sqlite3TableAffinity(v, pTab, regNewData+1);
122010 bAffinityDone = 1;
122011 }
122012 VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
122013 iThisCur = iIdxCur+ix;
122014
122015
122016 /* Skip partial indices for which the WHERE clause is not true */
122017 if( pIdx->pPartIdxWhere ){
@@ -133979,33 +134061,10 @@
133979 }
133980 }
133981 return WRC_Continue;
133982 }
133983
133984 /*
133985 ** No-op routine for the parse-tree walker.
133986 **
133987 ** When this routine is the Walker.xExprCallback then expression trees
133988 ** are walked without any actions being taken at each node. Presumably,
133989 ** when this routine is used for Walker.xExprCallback then
133990 ** Walker.xSelectCallback is set to do something useful for every
133991 ** subquery in the parser tree.
133992 */
133993 SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
133994 UNUSED_PARAMETER2(NotUsed, NotUsed2);
133995 return WRC_Continue;
133996 }
133997
133998 /*
133999 ** No-op routine for the parse-tree walker for SELECT statements.
134000 ** subquery in the parser tree.
134001 */
134002 SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
134003 UNUSED_PARAMETER2(NotUsed, NotUsed2);
134004 return WRC_Continue;
134005 }
134006
134007 #if SQLITE_DEBUG
134008 /*
134009 ** Always assert. This xSelectCallback2 implementation proves that the
134010 ** xSelectCallback2 is never invoked.
134011 */
@@ -135172,11 +135231,11 @@
135172 sAggInfo.mxReg = pParse->nMem;
135173 if( db->mallocFailed ) goto select_end;
135174 #if SELECTTRACE_ENABLED
135175 if( sqlite3SelectTrace & 0x400 ){
135176 int ii;
135177 SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
135178 sqlite3TreeViewSelect(0, p, 0);
135179 for(ii=0; ii<sAggInfo.nColumn; ii++){
135180 sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
135181 ii, sAggInfo.aCol[ii].iMem);
135182 sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
@@ -151215,10 +151274,27 @@
151215 if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
151216 }
151217 }
151218 return pList;
151219 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151220
151221 /*
151222 ** If the SELECT statement passed as the second argument does not invoke
151223 ** any SQL window functions, this function is a no-op. Otherwise, it
151224 ** rewrites the SELECT statement so that window function xStep functions
@@ -151325,10 +151401,11 @@
151325 pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
151326 );
151327 p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
151328 if( p->pSrc ){
151329 Table *pTab2;
 
151330 p->pSrc->a[0].pSelect = pSub;
151331 sqlite3SrcListAssignCursors(pParse, p->pSrc);
151332 pSub->selFlags |= SF_Expanded;
151333 pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
151334 pSub->selFlags |= (selFlags & SF_Aggregate);
@@ -151340,10 +151417,15 @@
151340 }else{
151341 memcpy(pTab, pTab2, sizeof(Table));
151342 pTab->tabFlags |= TF_Ephemeral;
151343 p->pSrc->a[0].pTab = pTab;
151344 pTab = pTab2;
 
 
 
 
 
151345 }
151346 }else{
151347 sqlite3SelectDelete(db, pSub);
151348 }
151349 if( db->mallocFailed ) rc = SQLITE_NOMEM;
@@ -224738,11 +224820,11 @@
224738 int nArg, /* Number of args */
224739 sqlite3_value **apUnused /* Function arguments */
224740 ){
224741 assert( nArg==0 );
224742 UNUSED_PARAM2(nArg, apUnused);
224743 sqlite3_result_text(pCtx, "fts5: 2020-05-17 00:26:44 1313557b512297e7b75ed748894379b2022aecf696d5a58318e46a668321c1ff", -1, SQLITE_TRANSIENT);
224744 }
224745
224746 /*
224747 ** Return true if zName is the extension on one of the shadow tables used
224748 ** by this module.
@@ -229521,12 +229603,12 @@
229521 }
229522 #endif /* SQLITE_CORE */
229523 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
229524
229525 /************** End of stmt.c ************************************************/
229526 #if __LINE__!=229526
229527 #undef SQLITE_SOURCE_ID
229528 #define SQLITE_SOURCE_ID "2020-05-17 13:47:28 69e149f76853d196c8855fedfc98848b60fb116ac36bc08824b1a122469falt2"
229529 #endif
229530 /* Return the source-id for this library */
229531 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
229532 /************************** End of sqlite3.c ******************************/
229533
--- 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.32.1. 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.
@@ -1160,13 +1160,13 @@
1160 **
1161 ** See also: [sqlite3_libversion()],
1162 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
1163 ** [sqlite_version()] and [sqlite_source_id()].
1164 */
1165 #define SQLITE_VERSION "3.32.1"
1166 #define SQLITE_VERSION_NUMBER 3032001
1167 #define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350"
1168
1169 /*
1170 ** CAPI3REF: Run-Time Library Version Numbers
1171 ** KEYWORDS: sqlite3_version sqlite3_sourceid
1172 **
@@ -17841,11 +17841,11 @@
17841 /*
17842 ** An instance of this structure contains information needed to generate
17843 ** code for a SELECT that contains aggregate functions.
17844 **
17845 ** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
17846 ** pointer to this structure. The Expr.iAgg field is the index in
17847 ** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
17848 ** code for that node.
17849 **
17850 ** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
17851 ** original Select structure that describes the SELECT statement. These
@@ -19080,10 +19080,13 @@
19080 SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
19081 SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
19082 SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
19083 SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
19084 SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
19085 SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*);
19086 SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*);
19087
19088 #ifdef SQLITE_DEBUG
19089 SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
19090 #endif
19091
19092 /*
@@ -28274,10 +28277,17 @@
28277 #ifndef SQLITE_PRINT_BUF_SIZE
28278 # define SQLITE_PRINT_BUF_SIZE 70
28279 #endif
28280 #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
28281
28282 /*
28283 ** Hard limit on the precision of floating-point conversions.
28284 */
28285 #ifndef SQLITE_PRINTF_PRECISION_LIMIT
28286 # define SQLITE_FP_PRECISION_LIMIT 100000000
28287 #endif
28288
28289 /*
28290 ** Render a string given by "fmt" into the StrAccum object.
28291 */
28292 SQLITE_API void sqlite3_str_vappendf(
28293 sqlite3_str *pAccum, /* Accumulate results here */
@@ -28474,10 +28484,12 @@
28484 ** precision The specified precision. The default
28485 ** is -1.
28486 ** xtype The class of the conversion.
28487 ** infop Pointer to the appropriate info struct.
28488 */
28489 assert( width>=0 );
28490 assert( precision>=(-1) );
28491 switch( xtype ){
28492 case etPOINTER:
28493 flag_long = sizeof(char*)==sizeof(i64) ? 2 :
28494 sizeof(char*)==sizeof(long int) ? 1 : 0;
28495 /* Fall through into the next case */
@@ -28595,10 +28607,15 @@
28607 }
28608 #ifdef SQLITE_OMIT_FLOATING_POINT
28609 length = 0;
28610 #else
28611 if( precision<0 ) precision = 6; /* Set default precision */
28612 #ifdef SQLITE_FP_PRECISION_LIMIT
28613 if( precision>SQLITE_FP_PRECISION_LIMIT ){
28614 precision = SQLITE_FP_PRECISION_LIMIT;
28615 }
28616 #endif
28617 if( realvalue<0.0 ){
28618 realvalue = -realvalue;
28619 prefix = '-';
28620 }else{
28621 prefix = flag_prefix;
@@ -28877,11 +28894,11 @@
28894 }else{
28895 escarg = va_arg(ap,char*);
28896 }
28897 isnull = escarg==0;
28898 if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
28899 /* For %q, %Q, and %w, the precision is the number of bytes (or
28900 ** characters if the ! flags is present) to use from the input.
28901 ** Because of the extra quoting characters inserted, the number
28902 ** of output characters may be larger than the precision.
28903 */
28904 k = precision;
@@ -29962,12 +29979,13 @@
29979 #else
29980 pWin = 0;
29981 #endif
29982 }
29983 if( pExpr->op==TK_AGG_FUNCTION ){
29984 sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s iAgg=%d agg=%p",
29985 pExpr->op2, pExpr->u.zToken, zFlgs,
29986 pExpr->iAgg, pExpr->pAggInfo);
29987 }else if( pExpr->op2!=0 ){
29988 const char *zOp2;
29989 char zBuf[8];
29990 sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2);
29991 zOp2 = zBuf;
@@ -30856,10 +30874,11 @@
30874 /* UTF-16 Little-endian -> UTF-8 */
30875 while( zIn<zTerm ){
30876 c = *(zIn++);
30877 c += (*(zIn++))<<8;
30878 if( c>=0xd800 && c<0xe000 ){
30879 #ifdef SQLITE_REPLACE_INVALID_UTF
30880 if( c>=0xdc00 || zIn>=zTerm ){
30881 c = 0xfffd;
30882 }else{
30883 int c2 = *(zIn++);
30884 c2 += (*(zIn++))<<8;
@@ -30868,19 +30887,27 @@
30887 c = 0xfffd;
30888 }else{
30889 c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
30890 }
30891 }
30892 #else
30893 if( zIn<zTerm ){
30894 int c2 = (*zIn++);
30895 c2 += ((*zIn++)<<8);
30896 c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
30897 }
30898 #endif
30899 }
30900 WRITE_UTF8(z, c);
30901 }
30902 }else{
30903 /* UTF-16 Big-endian -> UTF-8 */
30904 while( zIn<zTerm ){
30905 c = (*(zIn++))<<8;
30906 c += *(zIn++);
30907 if( c>=0xd800 && c<0xe000 ){
30908 #ifdef SQLITE_REPLACE_INVALID_UTF
30909 if( c>=0xdc00 || zIn>=zTerm ){
30910 c = 0xfffd;
30911 }else{
30912 int c2 = (*(zIn++))<<8;
30913 c2 += *(zIn++);
@@ -30889,10 +30916,17 @@
30916 c = 0xfffd;
30917 }else{
30918 c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
30919 }
30920 }
30921 #else
30922 if( zIn<zTerm ){
30923 int c2 = ((*zIn++)<<8);
30924 c2 += (*zIn++);
30925 c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
30926 }
30927 #endif
30928 }
30929 WRITE_UTF8(z, c);
30930 }
30931 }
30932 pMem->n = (int)(z - zOut);
@@ -46821,11 +46855,13 @@
46855 pFile->pVfs = pVfs;
46856 pFile->h = h;
46857 if( isReadonly ){
46858 pFile->ctrlFlags |= WINFILE_RDONLY;
46859 }
46860 if( (flags & SQLITE_OPEN_MAIN_DB)
46861 && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE)
46862 ){
46863 pFile->ctrlFlags |= WINFILE_PSOW;
46864 }
46865 pFile->lastErrno = NO_ERROR;
46866 pFile->zPath = zName;
46867 #if SQLITE_MAX_MMAP_SIZE>0
@@ -48313,14 +48349,15 @@
48349 */
48350 SQLITE_PRIVATE int sqlite3MemdbInit(void){
48351 sqlite3_vfs *pLower = sqlite3_vfs_find(0);
48352 int sz = pLower->szOsFile;
48353 memdb_vfs.pAppData = pLower;
48354 /* The following conditional can only be true when compiled for
48355 ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
48356 ** it in, to be safe, but it is marked as NO_TEST since there
48357 ** is no way to reach it under most builds. */
48358 if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
48359 memdb_vfs.szOsFile = sz;
48360 return sqlite3_vfs_register(&memdb_vfs, 0);
48361 }
48362 #endif /* SQLITE_ENABLE_DESERIALIZE */
48363
@@ -59957,29 +59994,47 @@
59994
59995 aOut[0] = s1;
59996 aOut[1] = s2;
59997 }
59998
59999 /*
60000 ** If there is the possibility of concurrent access to the SHM file
60001 ** from multiple threads and/or processes, then do a memory barrier.
60002 */
60003 static void walShmBarrier(Wal *pWal){
60004 if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
60005 sqlite3OsShmBarrier(pWal->pDbFd);
60006 }
60007 }
60008
60009 /*
60010 ** Add the SQLITE_NO_TSAN as part of the return-type of a function
60011 ** definition as a hint that the function contains constructs that
60012 ** might give false-positive TSAN warnings.
60013 **
60014 ** See tag-20200519-1.
60015 */
60016 #if defined(__clang__) && !defined(SQLITE_NO_TSAN)
60017 # define SQLITE_NO_TSAN __attribute__((no_sanitize_thread))
60018 #else
60019 # define SQLITE_NO_TSAN
60020 #endif
60021
60022 /*
60023 ** Write the header information in pWal->hdr into the wal-index.
60024 **
60025 ** The checksum on pWal->hdr is updated before it is written.
60026 */
60027 static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){
60028 volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
60029 const int nCksum = offsetof(WalIndexHdr, aCksum);
60030
60031 assert( pWal->writeLock );
60032 pWal->hdr.isInit = 1;
60033 pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
60034 walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
60035 /* Possible TSAN false-positive. See tag-20200519-1 */
60036 memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
60037 walShmBarrier(pWal);
60038 memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
60039 }
60040
@@ -61165,36 +61220,17 @@
61220 ** cannot be backfilled from the WAL.
61221 */
61222 mxSafeFrame = pWal->hdr.mxFrame;
61223 mxPage = pWal->hdr.nPage;
61224 for(i=1; i<WAL_NREADER; i++){
61225 u32 y = AtomicLoad(pInfo->aReadMark+i);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61226 if( mxSafeFrame>y ){
61227 assert( y<=pWal->hdr.mxFrame );
61228 rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
61229 if( rc==SQLITE_OK ){
61230 u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
61231 AtomicStore(pInfo->aReadMark+i, iMark);
61232 walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
61233 }else if( rc==SQLITE_BUSY ){
61234 mxSafeFrame = y;
61235 xBusy = 0;
61236 }else{
@@ -61208,11 +61244,11 @@
61244 rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
61245 assert( rc==SQLITE_OK || pIter==0 );
61246 }
61247
61248 if( pIter
61249 && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
61250 ){
61251 u32 nBackfill = pInfo->nBackfill;
61252
61253 pInfo->nBackfillAttempted = mxSafeFrame;
61254
@@ -61423,11 +61459,11 @@
61459 ** and *pChanged is set to 1.
61460 **
61461 ** If the checksum cannot be verified return non-zero. If the header
61462 ** is read successfully and the checksum verified, return zero.
61463 */
61464 static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){
61465 u32 aCksum[2]; /* Checksum on the header content */
61466 WalIndexHdr h1, h2; /* Two copies of the header content */
61467 WalIndexHdr volatile *aHdr; /* Header in shared memory */
61468
61469 /* The first page of the wal-index must be mapped at this point. */
@@ -61436,17 +61472,23 @@
61472 /* Read the header. This might happen concurrently with a write to the
61473 ** same area of shared memory on a different CPU in a SMP,
61474 ** meaning it is possible that an inconsistent snapshot is read
61475 ** from the file. If this happens, return non-zero.
61476 **
61477 ** tag-20200519-1:
61478 ** There are two copies of the header at the beginning of the wal-index.
61479 ** When reading, read [0] first then [1]. Writes are in the reverse order.
61480 ** Memory barriers are used to prevent the compiler or the hardware from
61481 ** reordering the reads and writes. TSAN and similar tools can sometimes
61482 ** give false-positive warnings about these accesses because the tools do not
61483 ** account for the double-read and the memory barrier. The use of mutexes
61484 ** here would be problematic as the memory being accessed is potentially
61485 ** shared among multiple processes and not all mutex implementions work
61486 ** reliably in that environment.
61487 */
61488 aHdr = walIndexHdr(pWal);
61489 memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */
61490 walShmBarrier(pWal);
61491 memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
61492
61493 if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
61494 return 1; /* Dirty read */
@@ -62109,16 +62151,18 @@
62151 ** needs to be flushed.
62152 */
62153 SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
62154 int rc; /* Return code */
62155 int cnt = 0; /* Number of TryBeginRead attempts */
62156 #ifdef SQLITE_ENABLE_SNAPSHOT
62157 int bChanged = 0;
62158 WalIndexHdr *pSnapshot = pWal->pSnapshot;
62159 #endif
62160
62161 assert( pWal->ckptLock==0 );
62162
62163 #ifdef SQLITE_ENABLE_SNAPSHOT
 
 
62164 if( pSnapshot ){
62165 if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
62166 bChanged = 1;
62167 }
62168
@@ -62283,26 +62327,28 @@
62327 for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
62328 WalHashLoc sLoc; /* Hash table location */
62329 int iKey; /* Hash slot index */
62330 int nCollide; /* Number of hash collisions remaining */
62331 int rc; /* Error code */
62332 u32 iH;
62333
62334 rc = walHashGet(pWal, iHash, &sLoc);
62335 if( rc!=SQLITE_OK ){
62336 return rc;
62337 }
62338 nCollide = HASHTABLE_NSLOT;
62339 iKey = walHash(pgno);
62340 while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
62341 u32 iFrame = iH + sLoc.iZero;
62342 if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
62343 assert( iFrame>iRead || CORRUPT_DB );
62344 iRead = iFrame;
62345 }
62346 if( (nCollide--)==0 ){
62347 return SQLITE_CORRUPT_BKPT;
62348 }
62349 iKey = walNextHash(iKey);
62350 }
62351 if( iRead ) break;
62352 }
62353
62354 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
@@ -97436,10 +97482,47 @@
97482 }
97483 p = p->pPrior;
97484 }while( p!=0 );
97485 return WRC_Continue;
97486 }
97487
97488 /* Increase the walkerDepth when entering a subquery, and
97489 ** descrease when leaving the subquery.
97490 */
97491 SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){
97492 UNUSED_PARAMETER(pSelect);
97493 pWalker->walkerDepth++;
97494 return WRC_Continue;
97495 }
97496 SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){
97497 UNUSED_PARAMETER(pSelect);
97498 pWalker->walkerDepth--;
97499 }
97500
97501
97502 /*
97503 ** No-op routine for the parse-tree walker.
97504 **
97505 ** When this routine is the Walker.xExprCallback then expression trees
97506 ** are walked without any actions being taken at each node. Presumably,
97507 ** when this routine is used for Walker.xExprCallback then
97508 ** Walker.xSelectCallback is set to do something useful for every
97509 ** subquery in the parser tree.
97510 */
97511 SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
97512 UNUSED_PARAMETER2(NotUsed, NotUsed2);
97513 return WRC_Continue;
97514 }
97515
97516 /*
97517 ** No-op routine for the parse-tree walker for SELECT statements.
97518 ** subquery in the parser tree.
97519 */
97520 SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
97521 UNUSED_PARAMETER2(NotUsed, NotUsed2);
97522 return WRC_Continue;
97523 }
97524
97525 /************** End of walker.c **********************************************/
97526 /************** Begin file resolve.c *****************************************/
97527 /*
97528 ** 2008 August 18
@@ -97465,10 +97548,12 @@
97548 ** This needs to occur when copying a TK_AGG_FUNCTION node from an
97549 ** outer query into an inner subquery.
97550 **
97551 ** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..)
97552 ** is a helper function - a callback for the tree walker.
97553 **
97554 ** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c
97555 */
97556 static int incrAggDepth(Walker *pWalker, Expr *pExpr){
97557 if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
97558 return WRC_Continue;
97559 }
@@ -103206,11 +103291,14 @@
103291 op = pExpr->op;
103292 }
103293 switch( op ){
103294 case TK_AGG_COLUMN: {
103295 AggInfo *pAggInfo = pExpr->pAggInfo;
103296 struct AggInfo_col *pCol;
103297 assert( pAggInfo!=0 );
103298 assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
103299 pCol = &pAggInfo->aCol[pExpr->iAgg];
103300 if( !pAggInfo->directMode ){
103301 assert( pCol->iMem>0 );
103302 return pCol->iMem;
103303 }else if( pAggInfo->useSortingIdx ){
103304 Table *pTab = pCol->pTab;
@@ -103506,11 +103594,14 @@
103594 sqlite3VdbeJumpHere(v, addr);
103595 break;
103596 }
103597 case TK_AGG_FUNCTION: {
103598 AggInfo *pInfo = pExpr->pAggInfo;
103599 if( pInfo==0
103600 || NEVER(pExpr->iAgg<0)
103601 || NEVER(pExpr->iAgg>=pInfo->nFunc)
103602 ){
103603 assert( !ExprHasProperty(pExpr, EP_IntValue) );
103604 sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
103605 }else{
103606 return pInfo->aFunc[pExpr->iAgg].iMem;
103607 }
@@ -105262,19 +105353,10 @@
105353 }
105354 }
105355 }
105356 return WRC_Continue;
105357 }
 
 
 
 
 
 
 
 
 
105358
105359 /*
105360 ** Analyze the pExpr expression looking for aggregate functions and
105361 ** for variables that need to be added to AggInfo object that pNC->pAggInfo
105362 ** points to. Additional entries are made on the AggInfo object as
@@ -105284,12 +105366,12 @@
105366 ** analyzed by sqlite3ResolveExprNames().
105367 */
105368 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
105369 Walker w;
105370 w.xExprCallback = analyzeAggregate;
105371 w.xSelectCallback = sqlite3WalkerDepthIncrease;
105372 w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
105373 w.walkerDepth = 0;
105374 w.u.pNC = pNC;
105375 w.pParse = 0;
105376 assert( pNC->pSrcList!=0 );
105377 sqlite3WalkExpr(&w, pExpr);
@@ -122007,11 +122089,11 @@
122089 }
122090 if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
122091 sqlite3TableAffinity(v, pTab, regNewData+1);
122092 bAffinityDone = 1;
122093 }
122094 VdbeNoopComment((v, "prep index %s", pIdx->zName));
122095 iThisCur = iIdxCur+ix;
122096
122097
122098 /* Skip partial indices for which the WHERE clause is not true */
122099 if( pIdx->pPartIdxWhere ){
@@ -133979,33 +134061,10 @@
134061 }
134062 }
134063 return WRC_Continue;
134064 }
134065
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134066 #if SQLITE_DEBUG
134067 /*
134068 ** Always assert. This xSelectCallback2 implementation proves that the
134069 ** xSelectCallback2 is never invoked.
134070 */
@@ -135172,11 +135231,11 @@
135231 sAggInfo.mxReg = pParse->nMem;
135232 if( db->mallocFailed ) goto select_end;
135233 #if SELECTTRACE_ENABLED
135234 if( sqlite3SelectTrace & 0x400 ){
135235 int ii;
135236 SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", &sAggInfo));
135237 sqlite3TreeViewSelect(0, p, 0);
135238 for(ii=0; ii<sAggInfo.nColumn; ii++){
135239 sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
135240 ii, sAggInfo.aCol[ii].iMem);
135241 sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
@@ -151215,10 +151274,27 @@
151274 if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
151275 }
151276 }
151277 return pList;
151278 }
151279
151280 /*
151281 ** When rewriting a query, if the new subquery in the FROM clause
151282 ** contains TK_AGG_FUNCTION nodes that refer to an outer query,
151283 ** then we have to increase the Expr->op2 values of those nodes
151284 ** due to the extra subquery layer that was added.
151285 **
151286 ** See also the incrAggDepth() routine in resolve.c
151287 */
151288 static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
151289 if( pExpr->op==TK_AGG_FUNCTION
151290 && pExpr->op2>=pWalker->walkerDepth
151291 ){
151292 pExpr->op2++;
151293 }
151294 return WRC_Continue;
151295 }
151296
151297 /*
151298 ** If the SELECT statement passed as the second argument does not invoke
151299 ** any SQL window functions, this function is a no-op. Otherwise, it
151300 ** rewrites the SELECT statement so that window function xStep functions
@@ -151325,10 +151401,11 @@
151401 pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
151402 );
151403 p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
151404 if( p->pSrc ){
151405 Table *pTab2;
151406 Walker w;
151407 p->pSrc->a[0].pSelect = pSub;
151408 sqlite3SrcListAssignCursors(pParse, p->pSrc);
151409 pSub->selFlags |= SF_Expanded;
151410 pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
151411 pSub->selFlags |= (selFlags & SF_Aggregate);
@@ -151340,10 +151417,15 @@
151417 }else{
151418 memcpy(pTab, pTab2, sizeof(Table));
151419 pTab->tabFlags |= TF_Ephemeral;
151420 p->pSrc->a[0].pTab = pTab;
151421 pTab = pTab2;
151422 memset(&w, 0, sizeof(w));
151423 w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
151424 w.xSelectCallback = sqlite3WalkerDepthIncrease;
151425 w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
151426 sqlite3WalkSelect(&w, pSub);
151427 }
151428 }else{
151429 sqlite3SelectDelete(db, pSub);
151430 }
151431 if( db->mallocFailed ) rc = SQLITE_NOMEM;
@@ -224738,11 +224820,11 @@
224820 int nArg, /* Number of args */
224821 sqlite3_value **apUnused /* Function arguments */
224822 ){
224823 assert( nArg==0 );
224824 UNUSED_PARAM2(nArg, apUnused);
224825 sqlite3_result_text(pCtx, "fts5: 2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350", -1, SQLITE_TRANSIENT);
224826 }
224827
224828 /*
224829 ** Return true if zName is the extension on one of the shadow tables used
224830 ** by this module.
@@ -229521,12 +229603,12 @@
229603 }
229604 #endif /* SQLITE_CORE */
229605 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
229606
229607 /************** End of stmt.c ************************************************/
229608 #if __LINE__!=229608
229609 #undef SQLITE_SOURCE_ID
229610 #define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba8alt2"
229611 #endif
229612 /* Return the source-id for this library */
229613 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
229614 /************************** End of sqlite3.c ******************************/
229615
+3 -3
--- 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.32.0"
127
-#define SQLITE_VERSION_NUMBER 3032000
128
-#define SQLITE_SOURCE_ID "2020-05-17 13:47:28 69e149f76853d196c8855fedfc98848b60fb116ac36bc08824b1a122469f8ece"
126
+#define SQLITE_VERSION "3.32.1"
127
+#define SQLITE_VERSION_NUMBER 3032001
128
+#define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350"
129129
130130
/*
131131
** CAPI3REF: Run-Time Library Version Numbers
132132
** KEYWORDS: sqlite3_version sqlite3_sourceid
133133
**
134134
--- 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.32.0"
127 #define SQLITE_VERSION_NUMBER 3032000
128 #define SQLITE_SOURCE_ID "2020-05-17 13:47:28 69e149f76853d196c8855fedfc98848b60fb116ac36bc08824b1a122469f8ece"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
134
--- 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.32.1"
127 #define SQLITE_VERSION_NUMBER 3032001
128 #define SQLITE_SOURCE_ID "2020-05-25 16:19:56 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350"
129
130 /*
131 ** CAPI3REF: Run-Time Library Version Numbers
132 ** KEYWORDS: sqlite3_version sqlite3_sourceid
133 **
134
+1 -1
--- src/th_main.c
+++ src/th_main.c
@@ -1500,11 +1500,11 @@
15001500
if( argc!=3 ){
15011501
return Th_WrongNumArgs(interp, "unversioned content FILENAME");
15021502
}
15031503
if( Th_IsRepositoryOpen() ){
15041504
Blob content;
1505
- if( unversioned_content(argv[2], &content)==0 ){
1505
+ if( unversioned_content(argv[2], &content)!=0 ){
15061506
Th_SetResult(interp, blob_str(&content), blob_size(&content));
15071507
blob_reset(&content);
15081508
return TH_OK;
15091509
}else{
15101510
return TH_ERROR;
15111511
--- src/th_main.c
+++ src/th_main.c
@@ -1500,11 +1500,11 @@
1500 if( argc!=3 ){
1501 return Th_WrongNumArgs(interp, "unversioned content FILENAME");
1502 }
1503 if( Th_IsRepositoryOpen() ){
1504 Blob content;
1505 if( unversioned_content(argv[2], &content)==0 ){
1506 Th_SetResult(interp, blob_str(&content), blob_size(&content));
1507 blob_reset(&content);
1508 return TH_OK;
1509 }else{
1510 return TH_ERROR;
1511
--- src/th_main.c
+++ src/th_main.c
@@ -1500,11 +1500,11 @@
1500 if( argc!=3 ){
1501 return Th_WrongNumArgs(interp, "unversioned content FILENAME");
1502 }
1503 if( Th_IsRepositoryOpen() ){
1504 Blob content;
1505 if( unversioned_content(argv[2], &content)!=0 ){
1506 Th_SetResult(interp, blob_str(&content), blob_size(&content));
1507 blob_reset(&content);
1508 return TH_OK;
1509 }else{
1510 return TH_ERROR;
1511
--- src/unversioned.c
+++ src/unversioned.c
@@ -85,25 +85,40 @@
8585
}
8686
8787
/*
8888
** Initialize pContent to be the content of an unversioned file zName.
8989
**
90
-** Return 0 on success. Return 1 if zName is not found.
90
+** Return 0 on failures.
91
+** Return 1 if the file is found by name.
92
+** Return 2 if the file is found by hash.
9193
*/
9294
int unversioned_content(const char *zName, Blob *pContent){
9395
Stmt q;
94
- int rc = 1;
96
+ int rc = 0;
9597
blob_init(pContent, 0, 0);
96
- db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q", zName);
98
+ db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q",
99
+ zName);
97100
if( db_step(&q)==SQLITE_ROW ){
98101
db_column_blob(&q, 1, pContent);
99102
if( db_column_int(&q, 0)==1 ){
100103
blob_uncompress(pContent, pContent);
101104
}
102
- rc = 0;
105
+ rc = 1;
103106
}
104107
db_finalize(&q);
108
+ if( rc==0 && validate16(zName,-1) ){
109
+ db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE hash=%Q",
110
+ zName);
111
+ if( db_step(&q)==SQLITE_ROW ){
112
+ db_column_blob(&q, 1, pContent);
113
+ if( db_column_int(&q, 0)==1 ){
114
+ blob_uncompress(pContent, pContent);
115
+ }
116
+ rc = 2;
117
+ }
118
+ db_finalize(&q);
119
+ }
105120
return rc;
106121
}
107122
108123
/*
109124
** Write unversioned content into the database.
@@ -328,11 +343,11 @@
328343
int i;
329344
verify_all_options();
330345
db_begin_transaction();
331346
for(i=3; i<g.argc; i++){
332347
Blob content;
333
- if( unversioned_content(g.argv[i], &content)==0 ){
348
+ if( unversioned_content(g.argv[i], &content)!=0 ){
334349
blob_write_to_file(&content, "-");
335350
}
336351
blob_reset(&content);
337352
}
338353
db_end_transaction(0);
@@ -352,11 +367,11 @@
352367
}
353368
zTFile = fossil_temp_filename();
354369
if( zTFile==0 ) fossil_fatal("cannot find a temporary filename");
355370
db_begin_transaction();
356371
content_rcvid_init("#!fossil unversioned edit");
357
- if( unversioned_content(zUVFile, &content) ){
372
+ if( unversioned_content(zUVFile, &content)==0 ){
358373
fossil_fatal("no such uv-file: %Q", zUVFile);
359374
}
360375
if( looks_like_binary(&content) ){
361376
fossil_fatal("cannot edit binary content");
362377
}
@@ -381,11 +396,11 @@
381396
blob_reset(&content);
382397
}else if( memcmp(zCmd, "export", nCmd)==0 ){
383398
Blob content;
384399
verify_all_options();
385400
if( g.argc!=5 ) usage("export UVFILE OUTPUT");
386
- if( unversioned_content(g.argv[3], &content) ){
401
+ if( unversioned_content(g.argv[3], &content)==0 ){
387402
fossil_fatal("no such uv-file: %Q", g.argv[3]);
388403
}
389404
blob_write_to_file(&content, g.argv[4]);
390405
blob_reset(&content);
391406
}else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
392407
--- src/unversioned.c
+++ src/unversioned.c
@@ -85,25 +85,40 @@
85 }
86
87 /*
88 ** Initialize pContent to be the content of an unversioned file zName.
89 **
90 ** Return 0 on success. Return 1 if zName is not found.
 
 
91 */
92 int unversioned_content(const char *zName, Blob *pContent){
93 Stmt q;
94 int rc = 1;
95 blob_init(pContent, 0, 0);
96 db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q", zName);
 
97 if( db_step(&q)==SQLITE_ROW ){
98 db_column_blob(&q, 1, pContent);
99 if( db_column_int(&q, 0)==1 ){
100 blob_uncompress(pContent, pContent);
101 }
102 rc = 0;
103 }
104 db_finalize(&q);
 
 
 
 
 
 
 
 
 
 
 
 
105 return rc;
106 }
107
108 /*
109 ** Write unversioned content into the database.
@@ -328,11 +343,11 @@
328 int i;
329 verify_all_options();
330 db_begin_transaction();
331 for(i=3; i<g.argc; i++){
332 Blob content;
333 if( unversioned_content(g.argv[i], &content)==0 ){
334 blob_write_to_file(&content, "-");
335 }
336 blob_reset(&content);
337 }
338 db_end_transaction(0);
@@ -352,11 +367,11 @@
352 }
353 zTFile = fossil_temp_filename();
354 if( zTFile==0 ) fossil_fatal("cannot find a temporary filename");
355 db_begin_transaction();
356 content_rcvid_init("#!fossil unversioned edit");
357 if( unversioned_content(zUVFile, &content) ){
358 fossil_fatal("no such uv-file: %Q", zUVFile);
359 }
360 if( looks_like_binary(&content) ){
361 fossil_fatal("cannot edit binary content");
362 }
@@ -381,11 +396,11 @@
381 blob_reset(&content);
382 }else if( memcmp(zCmd, "export", nCmd)==0 ){
383 Blob content;
384 verify_all_options();
385 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
386 if( unversioned_content(g.argv[3], &content) ){
387 fossil_fatal("no such uv-file: %Q", g.argv[3]);
388 }
389 blob_write_to_file(&content, g.argv[4]);
390 blob_reset(&content);
391 }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
392
--- src/unversioned.c
+++ src/unversioned.c
@@ -85,25 +85,40 @@
85 }
86
87 /*
88 ** Initialize pContent to be the content of an unversioned file zName.
89 **
90 ** Return 0 on failures.
91 ** Return 1 if the file is found by name.
92 ** Return 2 if the file is found by hash.
93 */
94 int unversioned_content(const char *zName, Blob *pContent){
95 Stmt q;
96 int rc = 0;
97 blob_init(pContent, 0, 0);
98 db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q",
99 zName);
100 if( db_step(&q)==SQLITE_ROW ){
101 db_column_blob(&q, 1, pContent);
102 if( db_column_int(&q, 0)==1 ){
103 blob_uncompress(pContent, pContent);
104 }
105 rc = 1;
106 }
107 db_finalize(&q);
108 if( rc==0 && validate16(zName,-1) ){
109 db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE hash=%Q",
110 zName);
111 if( db_step(&q)==SQLITE_ROW ){
112 db_column_blob(&q, 1, pContent);
113 if( db_column_int(&q, 0)==1 ){
114 blob_uncompress(pContent, pContent);
115 }
116 rc = 2;
117 }
118 db_finalize(&q);
119 }
120 return rc;
121 }
122
123 /*
124 ** Write unversioned content into the database.
@@ -328,11 +343,11 @@
343 int i;
344 verify_all_options();
345 db_begin_transaction();
346 for(i=3; i<g.argc; i++){
347 Blob content;
348 if( unversioned_content(g.argv[i], &content)!=0 ){
349 blob_write_to_file(&content, "-");
350 }
351 blob_reset(&content);
352 }
353 db_end_transaction(0);
@@ -352,11 +367,11 @@
367 }
368 zTFile = fossil_temp_filename();
369 if( zTFile==0 ) fossil_fatal("cannot find a temporary filename");
370 db_begin_transaction();
371 content_rcvid_init("#!fossil unversioned edit");
372 if( unversioned_content(zUVFile, &content)==0 ){
373 fossil_fatal("no such uv-file: %Q", zUVFile);
374 }
375 if( looks_like_binary(&content) ){
376 fossil_fatal("cannot edit binary content");
377 }
@@ -381,11 +396,11 @@
396 blob_reset(&content);
397 }else if( memcmp(zCmd, "export", nCmd)==0 ){
398 Blob content;
399 verify_all_options();
400 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
401 if( unversioned_content(g.argv[3], &content)==0 ){
402 fossil_fatal("no such uv-file: %Q", g.argv[3]);
403 }
404 blob_write_to_file(&content, g.argv[4]);
405 blob_reset(&content);
406 }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
407
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,9 +1,14 @@
11
<title>Change Log</title>
22
3
+<a name='v2_12'></a>
4
+<h2>Changes for Version 2.12 (pending)</h2>
5
+
6
+ * <i>(no changes yet...)</i>
7
+
38
<a name='v2_11'></a>
4
-<h2>Changes for Version 2.11 (pending)</h2>
9
+<h2>Changes for Version 2.11 (2020-05-25)</h2>
510
611
* Support [/md_rules|Markdown] in the default ticket configuration.
712
* Timestamp strings in [./checkin_names.wiki|object names]
813
can now omit punctation. So, for example, "202004181942" and
914
"2020-04-18 19:42" mean the same thing.
1015
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,9 +1,14 @@
1 <title>Change Log</title>
2
 
 
 
 
 
3 <a name='v2_11'></a>
4 <h2>Changes for Version 2.11 (pending)</h2>
5
6 * Support [/md_rules|Markdown] in the default ticket configuration.
7 * Timestamp strings in [./checkin_names.wiki|object names]
8 can now omit punctation. So, for example, "202004181942" and
9 "2020-04-18 19:42" mean the same thing.
10
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,9 +1,14 @@
1 <title>Change Log</title>
2
3 <a name='v2_12'></a>
4 <h2>Changes for Version 2.12 (pending)</h2>
5
6 * <i>(no changes yet...)</i>
7
8 <a name='v2_11'></a>
9 <h2>Changes for Version 2.11 (2020-05-25)</h2>
10
11 * Support [/md_rules|Markdown] in the default ticket configuration.
12 * Timestamp strings in [./checkin_names.wiki|object names]
13 can now omit punctation. So, for example, "202004181942" and
14 "2020-04-18 19:42" mean the same thing.
15

Keyboard Shortcuts

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